Get started with device management (Node.js)

Back-end apps can use Azure IoT Hub primitives, such as device twin and direct methods, to remotely start and monitor device management actions on devices. This tutorial shows you how a back-end app and a device app can work together to initiate and monitor a remote device reboot using IoT Hub.

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 IoT Hub tiers, see Choose the right IoT Hub tier.

Use a direct method to initiate device management actions (such as reboot, factory reset, and firmware update) from a back-end app in the cloud. The device is responsible for:

  • Handling the method request sent from IoT Hub.

  • Initiating the corresponding device-specific action on the device.

  • Providing status updates through reported properties to IoT Hub.

You can use a back-end app in the cloud to run device twin queries to report on the progress of your device management actions.

This tutorial shows you how to:

  • Use the Azure portal to create an IoT Hub and create a device identity in your IoT hub.

  • Create a simulated device app that contains a direct method that reboots that device. Direct methods are invoked from the cloud.

  • Create a Node.js console app that calls the reboot direct method in the simulated device app through your IoT hub.

At the end of this tutorial, you have two Node.js console apps:

  • dmpatterns_getstarted_device.js, which connects to your IoT hub with the device identity created earlier, receives a reboot direct method, simulates a physical reboot, and reports the time for the last reboot.

  • dmpatterns_getstarted_service.js, which calls a direct method in the simulated device app, displays the response, and displays the updated reported properties.

Prerequisites

  • Node.js version 10.0.x or later. Prepare your development environment describes how to install Node.js for this tutorial on either Windows or Linux.

  • An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

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.

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.

  1. Open Azure Cloud Shell.

  2. In Azure Cloud Shell, run the following command to install the Microsoft Azure IoT Extension for Azure CLI:

    az extension add --name azure-cli-iot-ext
    
  3. 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}
    az iot hub device-identity show-connection-string --device-id myDeviceId --hub-name {Your IoT Hub name} -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 simulated device app

In this section, you:

  • Create a Node.js console app that responds to a direct method called by the cloud

  • Trigger a simulated device reboot

  • Use the reported properties to enable device twin queries to identify devices and when they last rebooted

  1. Create an empty folder called manageddevice. In the manageddevice folder, create a package.json file using the following command at your command prompt. Accept all the defaults:

    npm init
    
  2. At your command prompt in the manageddevice folder, run the following command to install the azure-iot-device Device SDK package and azure-iot-device-mqtt package:

    npm install azure-iot-device azure-iot-device-mqtt --save
    
  3. Using a text editor, create a dmpatterns_getstarted_device.js file in the manageddevice folder.

  4. Add the following 'require' statements at the start of the dmpatterns_getstarted_device.js file:

    'use strict';
    
    var Client = require('azure-iot-device').Client;
    var Protocol = require('azure-iot-device-mqtt').Mqtt;
    
  5. Add a connectionString variable and use it to create a Client instance. Replace the {yourdeviceconnectionstring} placeholder value with the device connection string you copied previously in Register a new device in the IoT hub.

    var connectionString = '{yourdeviceconnectionstring}';
    var client = Client.fromConnectionString(connectionString, Protocol);
    
  6. Add the following function to implement the direct method on the device

    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.');
            }
        });
    
        // Report the reboot before the physical restart
        var date = new Date();
        var patch = {
            iothubDM : {
                reboot : {
                    lastReboot : date.toISOString(),
                }
            }
        };
    
        // Get device Twin
        client.getTwin(function(err, twin) {
            if (err) {
                console.error('could not get twin');
            } else {
                console.log('twin acquired');
                twin.properties.reported.update(patch, function(err) {
                    if (err) throw err;
                    console.log('Device reboot twin state reported')
                });  
            }
        });
    
        // Add your device's reboot API for physical restart.
        console.log('Rebooting!');
    };
    
  7. Open the connection to your IoT hub and start the direct method listener:

    client.open(function(err) {
        if (err) {
            console.error('Could not open IotHub client');
        }  else {
            console.log('Client opened.  Waiting for reboot method.');
            client.onDeviceMethod('reboot', onReboot);
        }
    });
    
  8. Save and close the dmpatterns_getstarted_device.js file.

Note

To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry policies (such as an exponential backoff), 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:

  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 IoT hub, select Shared access policies.

  3. From the list of policies, select the service 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.

Trigger a remote reboot on the device using a direct method

In this section, you create a Node.js 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.

  1. Create an empty folder called triggerrebootondevice. In the triggerrebootondevice folder, create a package.json file using the following command at your command prompt. Accept all the defaults:

    npm init
    
  2. At your command prompt in the triggerrebootondevice folder, run the following command to install the azure-iothub Device SDK package and azure-iot-device-mqtt package:

    npm install azure-iothub --save
    
  3. Using a text editor, create a dmpatterns_getstarted_service.js file in the triggerrebootondevice folder.

  4. Add the following 'require' statements at the start of the dmpatterns_getstarted_service.js file:

    'use strict';
    
    var Registry = require('azure-iothub').Registry;
    var Client = require('azure-iothub').Client;
    
  5. Add the following variable declarations and replace the {iothubconnectionstring} placeholder value with the IoT hub connection string you copied previously in Get the IoT hub connection string:

    var connectionString = '{iothubconnectionstring}';
    var registry = Registry.fromConnectionString(connectionString);
    var client = Client.fromConnectionString(connectionString);
    var deviceToReboot = 'myDeviceId';
    
  6. Add the following function to invoke the device method to reboot the target device:

    var startRebootDevice = function(twin) {
    
        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.");  
            }
        });
    };
    
  7. Add the following function to query for the device and get the last reboot time:

    var queryTwinLastReboot = function() {
    
        registry.getTwin(deviceToReboot, function(err, twin){
    
            if (twin.properties.reported.iothubDM != null)
            {
                if (err) {
                    console.error('Could not query twins: ' + err.constructor.name + ': ' + err.message);
                } else {
                    var lastRebootTime = twin.properties.reported.iothubDM.reboot.lastReboot;
                    console.log('Last reboot time: ' + JSON.stringify(lastRebootTime, null, 2));
                }
            } else 
                console.log('Waiting for device to report last reboot time.');
        });
    };
    
  8. Add the following code to call the functions that trigger the reboot direct method and query for the last reboot time:

    startRebootDevice();
    setInterval(queryTwinLastReboot, 2000);
    
  9. Save and close the dmpatterns_getstarted_service.js file.

Run the apps

You're now ready to run the apps.

  1. At the command prompt in the manageddevice folder, run the following command to begin listening for the reboot direct method.

    node dmpatterns_getstarted_device.js
    
  2. At the command prompt in the triggerrebootondevice folder, run the following command to trigger the remote reboot and query for the device twin to find the last reboot time.

    node dmpatterns_getstarted_service.js
    
  3. You see the device response to the reboot direct method and the reboot status in the console.

    The following shows the device response to the reboot direct method sent by the service:

    manageddevice app output

    The following shows the service triggering the reboot and polling the device twin for the last reboot time:

    triggerrebootondevice app output

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 tutorial, 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.