Get started with device management
Back-end apps can use Azure IoT Hub primitives, such as device twins and direct methods, to remotely start and monitor device management actions on devices.
Use a direct method from a back-end application to initiate device management actions, such as reboot, factory reset, and firmware update.
The device is responsible for:
- Handling the direct method request sent from IoT Hub
- Initiating the corresponding device-specific action on the device
- Providing status updates through reported properties to IoT Hub
This article shows you how a back-end app and a device app can work together to initiate and monitor a remote device action using a direct method.
- A service app calls a direct method to reboot in a device app through an IoT hub.
- A device app handles a direct method to reboot a device.
Note
The features described in this article are available only in the standard tier of IoT Hub. For more information about the basic and standard/free IoT Hub tiers, see Choose the right IoT Hub tier for your solution.
Note
This article is meant to complement Azure IoT SDKs samples that are referenced from within this article. You can use SDK tools to build both device and back-end applications.
Prerequisites
An IoT hub
A registered device
If your application uses the MQTT protocol, make sure that port 8883 is open in your firewall. The MQTT protocol 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).
- Requires Visual Studio
Overview
This article describes how to use the Azure IoT SDK for .NET to create device and backend service application code for device direct messages.
Create a device application
This section describes how to use device application code to create a direct method callback listener.
Important
This article includes steps to connect a device using a shared access signature, also called symmetric key authentication. This authentication method is convenient for testing and evaluation, but authenticating a device using X.509 certificates is a more secure approach. To learn more, see Security best practices > Connection security.
Required device NuGet package
Device client applications written in C# require the Microsoft.Azure.Devices.Client NuGet package.
Add these using
statements to use the device library.
using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;
Connect to a device
The DeviceClient class exposes all the methods required to interact with device messages from the device.
Connect to the device using the CreateFromConnectionString method along with device connection string and the connection transport protocol.
The CreateFromConnectionString
TransportType transport protocol parameter supports the following transport protocols:
Mqtt
Mqtt_WebSocket_Only
Mqtt_Tcp_Only
Amqp
Amqp_WebSocket_Only
Amqp_Tcp_Only
Http1
This example connects to a device using the Mqtt
transport protocol.
static string DeviceConnectionString = "{IoT hub device connection string}";
static deviceClient = null;
deviceClient = DeviceClient.CreateFromConnectionString(DeviceConnectionString,
TransportType.Mqtt);
Create a direct method callback listener
Use SetMethodHandlerAsync to initialize a direct method callback listener. The listener is associated with a method name keyword, such as "reboot". The method name can be used in an IoT Hub or backend application to trigger the callback method on the device.
This example sets up a callback listener named onReboot
that will trigger when the "reboot" direct method name is called.
try
{
// setup callback for "reboot" method
deviceClient.SetMethodHandlerAsync("reboot", onReboot, null).Wait();
Console.WriteLine("Waiting for reboot method\n Press enter to exit.");
Console.ReadLine();
Console.WriteLine("Exiting...");
// as a good practice, remove the "reboot" handler
deviceClient.SetMethodHandlerAsync("reboot", null, null).Wait();
deviceClient.CloseAsync().Wait();
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}
Continuing the example, the onReboot
callback method implements the direct method on the device.
The handler function calls MethodResponse to send a response acknowledgment to the calling application.
static Task<MethodResponse> onReboot(MethodRequest methodRequest, object userContext)
{
// In a production device, you would trigger a reboot
// scheduled to start after this method returns.
// For this sample, we simulate the reboot by writing to the console
// and updating the reported properties.
try
{
Console.WriteLine("Rebooting!");
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}
string result = @"{""result"":""Reboot started.""}";
return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200));
}
Note
To keep things simple, this article does not implement any retry policy. In production code, you should implement retry policies (such as an exponential backoff), as suggested in Transient fault handling.
SDK device samples
The Azure IoT SDK for .NET provides working samples of device apps that handle direct method tasks. For more information, see:
Create a backend application
This section describes how to trigger a direct method on a device.
The ServiceClient class exposes all methods required to create a backend application to send direct method calls to devices.
Required service NuGet package
Backend service applications require the Microsoft.Azure.Devices NuGet package.
Add these using
statements to use the service library.
using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;
Connect to IoT hub
You can connect a backend service to IoT Hub using the following methods:
- Shared access policy
- Microsoft Entra
Important
This article includes steps to connect to a service using a shared access signature. This authentication method is convenient for testing and evaluation, but authenticating to a service with Microsoft Entra ID or managed identities is a more secure approach. To learn more, see Security best practices > Cloud security.
Connect using a shared access policy
Connect a backend application using CreateFromConnectionString.
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.
As a parameter to CreateFromConnectionString
, supply the service shared access policy. For more information about shared access policies, see Control access to IoT Hub with shared access signatures.
ServiceClient serviceClient;
string connectionString = "{IoT hub service shared access policy connection string}";
serviceClient = ServiceClient.CreateFromConnectionString(connectionString);
Connect using Microsoft Entra
A backend app that uses Microsoft Entra must successfully authenticate and obtain a security token credential before connecting to IoT Hub. This token is passed to a IoT Hub connection method. For general information about setting up and using Microsoft Entra for IoT Hub, see Control access to IoT Hub by using Microsoft Entra ID.
Configure Microsoft Entra app
You must set up a Microsoft Entra app that is configured for your preferred authentication credential. The app contains parameters such as client secret that are used by the backend application to authenticate. The available app authentication configurations are:
- Client secret
- Certificate
- Federated identity credential
Microsoft Entra apps may require specific role permissions depending on operations being performed. For example, IoT Hub Twin Contributor is required to enable read and write access to a IoT Hub device and module twins. For more information, see Manage access to IoT Hub by using Azure RBAC role assignment.
For more information about setting up a Microsoft Entra app, see Quickstart: Register an application with the Microsoft identity platform.
Authenticate using DefaultAzureCredential
The easiest way to use Microsoft Entra to authenticate a backend application is to use DefaultAzureCredential, but it's recommended to use a different method in a production environment including a specific TokenCredential
or pared-down ChainedTokenCredential
. For simplicity, this section describes authentication using DefaultAzureCredential
and Client secret. For more information about the pros and cons of using DefaultAzureCredential
, see Usage guidance for DefaultAzureCredential.
DefaultAzureCredential
supports different authentication mechanisms and determines the appropriate credential type based on the environment it's executing in. It attempts to use multiple credential types in an order until it finds a working credential.
Microsoft Entra requires these NuGet packages and corresponding using
statements:
- Azure.Core
- Azure.Identity
using Azure.Core;
using Azure.Identity;
In this example, Microsoft Entra app registration client secret, client ID, and tenant ID are added to environment variables. These environment variables are used by DefaultAzureCredential
to authenticate the application. The result of a successful Microsoft Entra authentication is a security token credential that is passed to an IoT Hub connection method.
string clientSecretValue = "xxxxxxxxxxxxxxx";
string clientID = "xxxxxxxxxxxxxx";
string tenantID = "xxxxxxxxxxxxx";
Environment.SetEnvironmentVariable("AZURE_CLIENT_SECRET", clientSecretValue);
Environment.SetEnvironmentVariable("AZURE_CLIENT_ID", clientID);
Environment.SetEnvironmentVariable("AZURE_TENANT_ID", tenantID);
TokenCredential tokenCredential = new DefaultAzureCredential();
The resulting TokenCredential can then be passed to a connect to IoT Hub method for any SDK client that accepts Microsoft Entra credentials:
In this example, the TokenCredential
is passed to ServiceClient.Create
to create a ServiceClient connection object.
string hostname = "xxxxxxxxxx.azure-devices.net";
using var serviceClient = ServiceClient.Create(hostname, tokenCredential, TransportType.Amqp);
In this example, the TokenCredential
is passed to RegistryManager.Create
to create a RegistryManager object.
string hostname = "xxxxxxxxxx.azure-devices.net";
registryManager = RegistryManager.Create(hostname, tokenCredential);
Code sample
For a working sample of Microsoft Entra service authentication, see Role based authentication sample.
Invoke a method on a device
To invoke a method on a device:
- Create a CloudToDeviceMethod object. Pass the device direct method name as a parameter.
- Call InvokeDeviceMethodAsync to invoke the method on the device.
This example calls the "reboot" method to initiate a reboot on the device. The "reboot" method is mapped to a listener on the device as described in the Create a direct method callback listener section of this article.
string targetDevice = "myDeviceId";
CloudToDeviceMethod method = new CloudToDeviceMethod("reboot");
method.ResponseTimeout = TimeSpan.FromSeconds(30);
CloudToDeviceMethodResult response = await serviceClient.InvokeDeviceMethodAsync(targetDevice, method);
Console.WriteLine("Invoked firmware update on device.");
SDK service samples
The Azure IoT SDK for .NET provides working samples of service apps that handle message tasks. For more information, see:
- Requires Java SE Development Kit 8. Make sure you select Java 8 under Long-term support to navigate to downloads for JDK 8.
Overview
This article describes how to use the Azure IoT SDK for Java to create device and backend service application code for device direct methods.
Create a device application
This section describes how to use device application code to create a direct method callback listener.
Important
This article includes steps to connect a device using a shared access signature, also called symmetric key authentication. This authentication method is convenient for testing and evaluation, but authenticating a device using X.509 certificates is a more secure approach. To learn more, see Security best practices > Connection security.
Device import statement
Use the following device import statements to access the Azure IoT SDK for Java.
import com.microsoft.azure.sdk.iot.device.*;
import com.microsoft.azure.sdk.iot.device.exceptions.IotHubClientException;
import com.microsoft.azure.sdk.iot.device.twin.DirectMethodPayload;
import com.microsoft.azure.sdk.iot.device.twin.DirectMethodResponse;
import com.microsoft.azure.sdk.iot.device.twin.MethodCallback;
import com.microsoft.azure.sdk.iot.device.transport.IotHubConnectionStatus;
import com.microsoft.azure.sdk.iot.device.twin.SubscriptionAcknowledgedCallback;
Connect to a device
The DeviceClient class exposes all the methods you require to interact with direct methods on the device.
To connect to a device:
Use IotHubClientProtocol to choose a transport protocol. For example:
IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
Use the
DeviceClient
constructor to add the device primary connection string and protocol.String connString = "{IoT hub device connection string}"; DeviceClient client = new DeviceClient(connString, protocol);
Use open to connect the device to IoT hub. If the client is already open, the method does nothing.
client.open(true);
Create a direct method callback listener
Use subscribeToMethods to initialize a direct method callback listener. subscribeToMethods
listens for incoming direct methods until the connection is terminated. The method name and payload is received for each direct method call.
The listener should call DirectMethodResponse to send a method response acknowledgment to the calling application.
For example:
client.subscribeToMethods(
(methodName, methodData, context) ->
{
System.out.println("Received a direct method invocation with name " + methodName + " and payload " + methodData.getPayloadAsJsonString());
return new DirectMethodResponse(200, methodData);
},
null);
System.out.println("Successfully subscribed to direct methods");
Note
To keep things simple, this article does not implement any retry policy. In production code, you should implement retry policies (such as an exponential backoff), as suggested in Transient fault handling.
SDK device samples
The Azure IoT SDK for Java includes a working sample to test the device app concepts described in this article. For more information, see Direct Method Sample.
Create a backend application
This section describes how to initiate a remote reboot on a device using a direct method.
The ServiceClient
DeviceMethod class contains methods that services can use to access device twins.
Service import statements
Use the following service import statements to access the Azure IoT SDK for Java.
import com.microsoft.azure.sdk.iot.service.methods.DirectMethodRequestOptions;
import com.microsoft.azure.sdk.iot.service.methods.DirectMethodsClient;
import com.microsoft.azure.sdk.iot.service.methods.DirectMethodResponse;
Connect to IoT hub
You can connect a backend service to IoT Hub using the following methods:
- Shared access policy
- Microsoft Entra
Important
This article includes steps to connect to a service using a shared access signature. This authentication method is convenient for testing and evaluation, but authenticating to a service with Microsoft Entra ID or managed identities is a more secure approach. To learn more, see Security best practices > Cloud security.
Connect using a shared access policy
Use the DeviceMethod constructor to add the service primary connection string and connect to IoT Hub.
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.
As a parameter to the DeviceMethod
constructor, supply the service shared access policy. For more information about shared access policies, see Control access to IoT Hub with shared access signatures.
For example:
String iotHubConnectionString = "HostName=xxxxx.azure-devices.net;SharedAccessKeyName=service;SharedAccessKey=xxxxxxxxxxxxxxxxxxxxxxxx";
DeviceMethod methodClient = new DeviceMethod(iotHubConnectionString);
Connect using Microsoft Entra
A backend app that uses Microsoft Entra must successfully authenticate and obtain a security token credential before connecting to IoT Hub. This token is passed to a IoT Hub connection method. For general information about setting up and using Microsoft Entra for IoT Hub, see Control access to IoT Hub by using Microsoft Entra ID.
For an overview of Java SDK authentication, see Azure authentication with Java and Azure Identity.
For simplicity, this section focuses on describing authentication using client secret.
Configure Microsoft Entra app
You must set up a Microsoft Entra app that is configured for your preferred authentication credential. The app contains parameters such as client secret that are used by the backend application to authenticate. The available app authentication configurations are:
- Client secret
- Certificate
- Federated identity credential
Microsoft Entra apps may require specific role permissions depending on operations being performed. For example, IoT Hub Twin Contributor is required to enable read and write access to a IoT Hub device and module twins. For more information, see Manage access to IoT Hub by using Azure RBAC role assignment.
For more information about setting up a Microsoft Entra app, see Quickstart: Register an application with the Microsoft identity platform.
Authenticate using DefaultAzureCredential
The easiest way to use Microsoft Entra to authenticate a backend application is to use DefaultAzureCredential, but it's recommended to use a different method in a production environment including a specific TokenCredential
or pared-down ChainedTokenCredential
.
For more information about the pros and cons of using DefaultAzureCredential
, see
Credential chains in the Azure Identity client library for Java.
DefaultAzureCredential supports different authentication mechanisms and determines the appropriate credential type based on the environment it's executing in. It attempts to use multiple credential types in an order until it finds a working credential.
You can authenticate Microsoft Entra app credentials using DefaultAzureCredentialBuilder. Save connection parameters such as client secret tenantID, clientID, and client secret values as environmental variables. Once the TokenCredential
is created, pass it to ServiceClient or other builder as the 'credential' parameter.
In this example, DefaultAzureCredentialBuilder
attempts to authenticate a connection from the list described in DefaultAzureCredential. The result of a successful Microsoft Entra authentication is a security token credential that is passed to a constructor such as ServiceClient.
TokenCredential defaultAzureCredential = new DefaultAzureCredentialBuilder().build();
Authenticate using ClientSecretCredentialBuilder
You can use ClientSecretCredentialBuilder to create a credential using client secret information. If successful, this method returns a TokenCredential that can be passed to ServiceClient or other builder as the 'credential' parameter.
In this example, Microsoft Entra app registration client secret, client ID, and tenant ID values have been added to environment variables. These environment variables are used by ClientSecretCredentialBuilder
to build the credential.
string clientSecretValue = System.getenv("AZURE_CLIENT_SECRET");
string clientID = System.getenv("AZURE_CLIENT_ID");
string tenantID = System.getenv("AZURE_TENANT_ID");
TokenCredential credential =
new ClientSecretCredentialBuilder()
.tenantId(tenantID)
.clientId(clientID)
.clientSecret(clientSecretValue)
.build();
Other authentication classes
The Java SDK also includes these classes that authenticate a backend app with Microsoft Entra:
- AuthorizationCodeCredential
- AzureCliCredential
- AzureDeveloperCliCredential
- AzurePipelinesCredential
- ChainedTokenCredential
- ClientAssertionCredential
- ClientCertificateCredential
- DeviceCodeCredential
- EnvironmentCredential
- InteractiveBrowserCredential
- ManagedIdentityCredential
- OnBehalfOfCredential
Code samples
For working samples of Microsoft Entra service authentication, see Role based authentication sample.
Invoke a method on a device
Call DeviceMethod.invoke to invoke a method on a device and return the result status.
The invoke
payload parameter is optional. Use null
if there is no payload supplied. The payload parameter can take different data forms including string, byte array, and HashMap. For examples, see Direct Method Tests.
This example calls the "reboot" method to initiate a reboot on the device. The "reboot" method is mapped to a listener on the device as described in the Create a direct method callback listener section of this article.
For example:
String deviceId = "myFirstDevice";
String methodName = "reboot";
String payload = "Test payload";
Long responseTimeout = TimeUnit.SECONDS.toSeconds(30);
Long connectTimeout = TimeUnit.SECONDS.toSeconds(5);
MethodResult result = methodClient.invoke(deviceId, methodName, responseTimeout, connectTimeout, payload);
if (result == null)
{
throw new IOException("Method invoke returns null");
}
System.out.println("Status=" + result.getStatus());
SDK service samples
The Azure IoT SDK for Java provides a working sample of service apps that handle direct method tasks. For more information, see:
- Python SDK - 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.
Overview
This article describes how to use the Azure IoT SDK for Python to create device and backend service application code for device direct methods.
Install packages
The azure-iot-device library must be installed to create device applications.
pip install azure-iot-device
The azure-iot-hub library must be installed to create backend service applications.
pip install azure-iot-hub
Create a device application
This section describes how to use device application code to create a direct method callback listener.
Important
This article includes steps to connect a device using a shared access signature, also called symmetric key authentication. This authentication method is convenient for testing and evaluation, but authenticating a device using X.509 certificates is a more secure approach. To learn more, see Security best practices > Connection security.
Device import statements
Add this import statement to access IoTHubDeviceClient
and MethodResponse
.
# import the device client library
from azure.iot.device import IoTHubDeviceClient, MethodResponse
Connect to a device
The IoTHubDeviceClient class contains methods that can be used to work with direct methods.
Use create_from_connection_string to connect an application to a device using a device connection string.
# substitute the device connection string in conn_str
# and add it to the IoTHubDeviceClient object
conn_str = "{IoT hub device connection string}"
device_client = IoTHubDeviceClient.create_from_connection_string(conn_str)
Create a direct method callback
Use on_method_request_received to create a handler function or coroutine that is called when a direct method is received. The listener is associated with a method name keyword, such as "reboot". The method name can be used in an IoT Hub or backend application to trigger the callback method on the device.
The handler function should create a MethodResponse and pass it to send_method_response to send a direct method response acknowledgment to the calling application.
This example sets up a direct method handler named method_request_handler
.
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()
In this example, the method_request_handler
callback method implements the direct method on the device. The code is executed when the "rebootDevice" direct method is called from a service application. The method calls send_method_response
to send a direct method response acknowledgment to the calling application.
# 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")
# 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)
SDK device samples
The Azure IoT SDK for Python provides a working sample of a device app that handles direct method tasks. For more information, see Receive direct method.
Create a backend application
This section describes how to use a backend service application to call a direct method on a device.
The IoTHubRegistryManager class exposes all methods required to create a backend application to send messages to a device.
Service import statements
Add these import statements to connect to Iot Hub, send cloud-to-device direct methods, and receive device direct method responses.
from azure.iot.hub import IoTHubRegistryManager
from azure.iot.hub.models import CloudToDeviceMethod, CloudToDeviceMethodResult
Connect to IoT hub
You can connect a backend service to IoT Hub using the following methods:
- Shared access policy
- Microsoft Entra
Important
This article includes steps to connect to a service using a shared access signature. This authentication method is convenient for testing and evaluation, but authenticating to a service with Microsoft Entra ID or managed identities is a more secure approach. To learn more, see Security best practices > Cloud security.
Connect using a shared access policy
Connect to IoT hub using from_connection_string.
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.
As a parameter to from_connection_string
, supply the service shared access policy. For more information about shared access policies, see Control access to IoT Hub with shared access signatures.
For example:
# Connect to IoT hub
IOTHUB_CONNECTION_STRING = "{IoT hub service connection string}"
iothub_registry_manager = IoTHubRegistryManager.from_connection_string(IOTHUB_CONNECTION_STRING)
Connect using Microsoft Entra
A backend app that uses Microsoft Entra must successfully authenticate and obtain a security token credential before connecting to IoT Hub. This token is passed to a IoT Hub connection method. For general information about setting up and using Microsoft Entra for IoT Hub, see Control access to IoT Hub by using Microsoft Entra ID.
For an overview of Python SDK authentication, see Authenticate Python apps to Azure services by using the Azure SDK for Python
Configure Microsoft Entra app
You must set up a Microsoft Entra app that is configured for your preferred authentication credential. The app contains parameters such as client secret that are used by the backend application to authenticate. The available app authentication configurations are:
- Client secret
- Certificate
- Federated identity credential
Microsoft Entra apps may require specific role permissions depending on operations being performed. For example, IoT Hub Twin Contributor is required to enable read and write access to a IoT Hub device and module twins. For more information, see Manage access to IoT Hub by using Azure RBAC role assignment.
For more information about setting up a Microsoft Entra app, see Quickstart: Register an application with the Microsoft identity platform.
Authenticate using DefaultAzureCredential
The easiest way to use Microsoft Entra to authenticate a backend application is to use DefaultAzureCredential, but it's recommended to use a different method in a production environment including a specific TokenCredential
or pared-down ChainedTokenCredential
. For simplicity, this section describes authentication using DefaultAzureCredential
and Client secret. For more information about the pros and cons of using DefaultAzureCredential
, see Credential chains in the Azure Identity client library for Python.
DefaultAzureCredential supports different authentication mechanisms and determines the appropriate credential type based on the environment it's executing in. It attempts to use multiple credential types in an order until it finds a working credential.
Microsoft Entra requires this import package and corresponding import
statement:
pip install azure-identity
from azure.identity import DefaultAzureCredential
In this example, Microsoft Entra app registration client secret, client ID, and tenant ID have been added to environment variables. These environment variables are used by DefaultAzureCredential
to authenticate the application. The result of a successful Microsoft Entra authentication is a security token credential that is passed to an IoT Hub connection method.
from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()
The resulting AccessToken can then be passed to from_token_credential
to connect to IoT Hub for any SDK client that accepts Microsoft Entra credentials:
- IoTHubRegistryManager to create a service connection to IoT Hub using an Entra token credential.
- IoTHubJobManager
- DigitalTwinClient
- IoTHubHttpRuntimeManager
- IoTHubConfigurationManager
from_token_credential
requires two parameters:
- The Azure service URL - The Azure service URL should be in the format
{Your Entra domain URL}.azure-devices.net
without ahttps://
prefix. For example,MyAzureDomain.azure-devices.net
. - The Azure credential token
In this example, the Azure credential is obtained using DefaultAzureCredential
. The Azure service URL and credential are then supplied to IoTHubRegistryManager.from_token_credential
to create the connection to IoT Hub.
import sys
import os
from azure.identity import DefaultAzureCredential
from azure.iot.hub import IoTHubRegistryManager
# Define the client secret values
clientSecretValue = 'xxxxxxxxxxxxxxx'
clientID = 'xxxxxxxxxxxxxx'
tenantID = 'xxxxxxxxxxxxx'
# Set environment variables
os.environ['AZURE_CLIENT_SECRET'] = clientSecretValue
os.environ['AZURE_CLIENT_ID'] = clientID
os.environ['AZURE_TENANT_ID'] = tenantID
# Acquire a credential object
credential = DefaultAzureCredential()
# Use Entra to authorize IoT Hub service
print("Connecting to IoTHubRegistryManager...")
iothub_registry_manager = IoTHubRegistryManager.from_token_credential(
url="MyAzureDomain.azure-devices.net",
token_credential=credential)
Code samples
For working samples of Microsoft Entra service authentication, see Microsoft Authentication Library (MSAL) for Python.
Invoke a method on a device
You can invoke a direct method by name on a device. The method name identifies the method. In the following and previous device example shown in Create a direct method callback, the direct method name is "rebootDevice".
To invoke a direct method on a device:
- Create a CloudToDeviceMethod object. Supply the method name and payload as parameters.
- Call invoke_device_method to invoke a direct method on a device. Supply the device ID and
CloudToDeviceMethod
payload object as parameters.
This example calls CloudToDeviceMethod
to invoke a direct method named "rebootDevice" on a device. After the direct method has been successfully invoked, the direct method response payload is displayed.
CONNECTION_STRING = "{IoTHubConnectionString}"
DEVICE_ID = "{deviceId}"
METHOD_NAME = "rebootDevice"
METHOD_PAYLOAD = "{\"method_number\":\"42\"}"
TIMEOUT = 60
WAIT_COUNT = 10
try:
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 ( "Successfully invoked the device to reboot." )
print ( "The device has returned this payload:" )
print ( response.payload )
except Exception as ex:
print ( "" )
print ( "Unexpected error {0}".format(ex) )
return
SDK service samples
The Azure IoT SDK for Python provides working samples of service apps that handle direct method tasks. For more information, see:
- Requires Node.js version 10.0.x or later
Overview
This article describes how to use the Azure IoT SDK for Node.js to create device and backend service application code for device direct methods.
Create a device application
This section describes how to use device application code to create a direct method callback.
Install SDK packages
The azure-iot-device package contains objects that interface with IoT devices. Run this command to install the azure-iot-device device SDK on your development machine:
npm install azure-iot-device --save
Choose a transport protocol
The Client
object supports these protocols:
Amqp
Http
- When usingHttp
, theClient
instance checks for messages from IoT Hub infrequently (a minimum of every 25 minutes).Mqtt
MqttWs
AmqpWs
Install needed transport protocols on your development machine.
For example, this command installs the Amqp
protocol:
npm install azure-iot-device-amqp --save
For more information about the differences between MQTT, AMQP, and HTTPS support, see Cloud-to-device communications guidance and Choose a communication protocol.
Create a client object
Create a Client
object using the installed package.
For example:
const Client = require('azure-iot-device').Client;
Create a protocol object
Create a Protocol
object using an installed transport package.
This example assigns the AMQP protocol:
const Protocol = require('azure-iot-device-amqp').Amqp;
Add the device connection string and transport protocol
Call fromConnectionString to supply device connection parameters:
- connStr - The device connection string.
- transportCtor - The transport protocol.
This example uses the Amqp
transport protocol:
const deviceConnectionString = "{IoT hub device connection string}"
const Protocol = require('azure-iot-device-mqtt').Amqp;
let client = Client.fromConnectionString(deviceConnectionString, Protocol);
Open the connection to IoT Hub
Use the open method to open connection between an IoT device and IoT Hub.
For example:
client.open(function(err) {
if (err) {
console.error('error connecting to hub: ' + err);
process.exit(1);
}
})
Create a direct method callback
Call onDeviceMethod to create a callback handler function or coroutine that is called when a direct method is received. The listener is associated with a method name keyword, such as "reboot". The method name can be used in an IoT Hub or backend application to trigger the callback method on the device.
The callback handler function should call response.send
to send a response acknowledgment message to the calling application.
This example sets up a direct method handler named onReboot
that is called when the "reboot" direct method name is used.
client.onDeviceMethod('reboot', onReboot);
In this example, the onReboot
callback method implements the direct method on the device. The code is executed when the "reboot" direct method is called from a service application. The function calls response.send
to send a response acknowledgment message to the calling application.
var onReboot = function(request, response) {
// Respond the cloud app for the direct method
response.send(200, 'Reboot started', function(err) {
if (err) {
console.error('An error occurred when sending a method response:\n' + err.toString());
} else {
console.log('Response to method \'' + request.methodName + '\' sent successfully.');
}
});
// Add your device's reboot API for physical restart.
console.log('Rebooting!');
};
SDK device samples
The Azure IoT SDK for Node.js provides working samples of device apps that handle device management tasks. For more information, see:
Create a backend application
This section describes how to invoke a direct method on a device.
Install service SDK package
Run this command to install azure-iothub on your development machine:
npm install azure-iothub --save
Connect to IoT hub
You can connect a backend service to IoT Hub using the following methods:
- Shared access policy
- Microsoft Entra
Important
This article includes steps to connect to a service using a shared access signature. This authentication method is convenient for testing and evaluation, but authenticating to a service with Microsoft Entra ID or managed identities is a more secure approach. To learn more, see Security best practices > Cloud security.
Connect using a shared access policy
Use fromConnectionString to connect to IoT hub.
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.
As a parameter to CreateFromConnectionString
, supply the service shared access policy connection string. For more information about shared access policies, see Control access to IoT Hub with shared access signatures.
var Client = require('azure-iothub').Client;
var connectionString = '{IoT hub shared access policy connection string}';
var client = Client.fromConnectionString(connectionString);
Connect using Microsoft Entra
A backend app that uses Microsoft Entra must successfully authenticate and obtain a security token credential before connecting to IoT Hub. This token is passed to a IoT Hub connection method. For general information about setting up and using Microsoft Entra for IoT Hub, see Control access to IoT Hub by using Microsoft Entra ID.
For an overview of Node.js SDK authentication, see:
Configure Microsoft Entra app
You must set up a Microsoft Entra app that is configured for your preferred authentication credential. The app contains parameters such as client secret that are used by the backend application to authenticate. The available app authentication configurations are:
- Client secret
- Certificate
- Federated identity credential
Microsoft Entra apps may require specific role permissions depending on operations being performed. For example, IoT Hub Twin Contributor is required to enable read and write access to a IoT Hub device and module twins. For more information, see Manage access to IoT Hub by using Azure RBAC role assignment.
For more information about setting up a Microsoft Entra app, see Quickstart: Register an application with the Microsoft identity platform.
Authenticate using DefaultAzureCredential
The easiest way to use Microsoft Entra to authenticate a backend application is to use DefaultAzureCredential, but it's recommended to use a different method in a production environment including a specific TokenCredential
or pared-down ChainedTokenCredential
. For simplicity, this section describes authentication using DefaultAzureCredential
and Client secret.
For more information about the pros and cons of using DefaultAzureCredential
, see
Credential chains in the Azure Identity client library for JavaScript
DefaultAzureCredential supports different authentication mechanisms and determines the appropriate credential type based on the environment it's executing in. It attempts to use multiple credential types in an order until it finds a working credential.
Microsoft Entra requires this package:
npm install --save @azure/identity
In this example, Microsoft Entra app registration client secret, client ID, and tenant ID have been added to environment variables. These environment variables are used by DefaultAzureCredential
to authenticate the application. The result of a successful Microsoft Entra authentication is a security token credential that is passed to an IoT Hub connection method.
import { DefaultAzureCredential } from "@azure/identity";
// Azure SDK clients accept the credential as a parameter
const credential = new DefaultAzureCredential();
The resulting credential token can then be passed to fromTokenCredential to connect to IoT Hub for any SDK client that accepts Microsoft Entra credentials:
fromTokenCredential
requires two parameters:
- The Azure service URL - The Azure service URL should be in the format
{Your Entra domain URL}.azure-devices.net
without ahttps://
prefix. For example,MyAzureDomain.azure-devices.net
. - The Azure credential token
In this example, the Azure credential is obtained using DefaultAzureCredential
. The Azure domain URL and credential are then supplied to Registry.fromTokenCredential
to create the connection to IoT Hub.
const { DefaultAzureCredential } = require("@azure/identity");
let Registry = require('azure-iothub').Registry;
// Define the client secret values
clientSecretValue = 'xxxxxxxxxxxxxxx'
clientID = 'xxxxxxxxxxxxxx'
tenantID = 'xxxxxxxxxxxxx'
// Set environment variables
process.env['AZURE_CLIENT_SECRET'] = clientSecretValue;
process.env['AZURE_CLIENT_ID'] = clientID;
process.env['AZURE_TENANT_ID'] = tenantID;
// Acquire a credential object
const credential = new DefaultAzureCredential()
// Create an instance of the IoTHub registry
hostName = 'MyAzureDomain.azure-devices.net';
let registry = Registry.fromTokenCredential(hostName,credential);
Code samples
For working samples of Microsoft Entra service authentication, see Azure identity examples.
Invoke a method on a device
Use invokeDeviceMethod to invoke a direct method by name on a device. The method name parameter identifies the direct method.
This example calls the "reboot" method to initiate a reboot on the device. The "reboot" method is mapped to a callback handler function on the device as described in the Create a direct method callback section of this article.
var startRebootDevice = function(deviceToReboot) {
var methodName = "reboot";
var methodParams = {
methodName: methodName,
payload: null,
timeoutInSeconds: 30
};
client.invokeDeviceMethod(deviceToReboot, methodParams, function(err, result) {
if (err) {
console.error("Direct method error: "+err.message);
} else {
console.log("Successfully invoked the device to reboot.");
}
});
};
SDK service samples
The Azure IoT SDK for Node.js provides working samples of service apps that handle device management tasks. For more information, see: