Schedule and broadcast jobs (Node)

Azure IoT Hub is a fully managed service that enables a back-end app to create and track jobs that schedule and update millions of devices. Jobs can be used for the following actions:

  • Update desired properties
  • Update tags
  • Invoke direct methods

Conceptually, a job wraps one of these actions and tracks the progress of execution against a set of devices, which is defined by a device twin query. For example, a back-end app can use a job to invoke a reboot method on 10,000 devices, specified by a device twin query and scheduled at a future time. That application can then track progress as each of those devices receive and execute the reboot method.

Learn more about each of these capabilities in these articles:

Note

The features described in this article are only available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:

  • Create a Node.js simulated device app that has a direct method, which enables lockDoor, which can be called by the solution back end.
  • Create a Node.js console app that calls the lockDoor direct method in the simulated device app using a job and updates the desired properties using a device job.

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

simDevice.js, which connects to your IoT hub with the device identity and receives a lockDoor direct method.

scheduleJobService.js, which calls a direct method in the simulated device app and updates the device twin's desired properties using a job.

To complete this tutorial, you need the following:

  • Node.js version 4.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

Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this task by using the Azure portal.

  1. Sign in to the Azure portal.

  2. Select Create a resource > Internet of Things > IoT Hub.

    Azure portal Jumpbar

  3. In the IoT hub pane, enter the following information for your IoT hub:

    • Subscription: Choose the subscription that you want to use to create this IoT hub.

    • Resource group: Create a resource group to host the IoT hub or use an existing one. For more information, see Use resource groups to manage your Azure resources.

    • Region: Select the closest location to you.

    • Name: Create a name for your IoT hub. If the name you enter is available, a green check mark appears.

    Important

    The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while naming it.

    IoT Hub basics window

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

  5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your subscription. For more information, see the Pricing and scale tier.

    IoT Hub size and scale window

  6. Select Review + create.

  7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You can monitor the progress in the Notifications pane.

  8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that you have created an IoT hub, locate the important information that you use to connect devices and applications to your IoT hub. Click Shared access policies.

  9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

    Shared access policies

Create a device identity

In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device IDs are case sensitive.

  1. Run the following in your command-line environment:

    npm install -g iothub-explorer@latest

  2. Then, run the following command to sign in to your hub. Substitute {iot hub connection string} with the IoT Hub connection string you previously copied:

    iothub-explorer login "{iot hub connection string}"

  3. Finally, create a new device identity called myDeviceId with the command:

    iothub-explorer create myDeviceId --connection-string

    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.

Refer to Getting started with IoT Hub to programmatically create device identities.

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, which triggers a simulated lockDoor method.

  1. Create a new empty folder called simDevice. In the simDevice 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 simDevice 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 new simDevice.js file in the simDevice folder.
  4. Add the following 'require' statements at the start of the simDevice.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.

    var connectionString = 'HostName={youriothostname};DeviceId={yourdeviceid};SharedAccessKey={yourdevicekey}';
    var client = Client.fromConnectionString(connectionString, Protocol);
    
  6. Add the following function to handle the lockDoor method.

    var onLockDoor = function(request, response) {
    
        // Respond the cloud app for the direct method
        response.send(200, function(err) {
            if (!err) {
                console.error('An error occured when sending a method response:\n' + err.toString());
            } else {
                console.log('Response to method \'' + request.methodName + '\' sent successfully.');
            }
        });
    
        console.log('Locking Door!');
    };
    
  7. Add the following code to register the handler for the lockDoor method.

    client.open(function(err) {
        if (err) {
            console.error('Could not connect to IotHub client.');
        }  else {
            console.log('Client connected to IoT Hub. Register handler for lockDoor direct method.');
            client.onDeviceMethod('lockDoor', onLockDoor);
        }
    });
    
  8. Save and close the simDevice.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 MSDN article Transient Fault Handling.

Schedule jobs for calling a direct method and updating a device twin's properties

In this section, you create a Node.js console app that initiates a remote lockDoor on a device using a direct method and update the device twin's properties.

  1. Create a new empty folder called scheduleJobService. In the scheduleJobService 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 scheduleJobService folder, run the following command to install the azure-iothub Device SDK package and azure-iot-device-mqtt package:

    npm install azure-iothub uuid --save
    
  3. Using a text editor, create a new scheduleJobService.js file in the scheduleJobService folder.
  4. Add the following 'require' statements at the start of the dmpatterns_gscheduleJobServiceetstarted_service.js file:

    'use strict';
    
    var uuid = require('uuid');
    var JobClient = require('azure-iothub').JobClient;
    
  5. Add the following variable declarations and replace the placeholder values:

    var connectionString = '{iothubconnectionstring}';
    var queryCondition = "deviceId IN ['myDeviceId']";
    var startTime = new Date();
    var maxExecutionTimeInSeconds =  300;
    var jobClient = JobClient.fromConnectionString(connectionString);
    
  6. Add the following function that is used to monitor the execution of the job:

    function monitorJob (jobId, callback) {
        var jobMonitorInterval = setInterval(function() {
            jobClient.getJob(jobId, function(err, result) {
            if (err) {
                console.error('Could not get job status: ' + err.message);
            } else {
                console.log('Job: ' + jobId + ' - status: ' + result.status);
                if (result.status === 'completed' || result.status === 'failed' || result.status === 'cancelled') {
                clearInterval(jobMonitorInterval);
                callback(null, result);
                }
            }
            });
        }, 5000);
    }
    
  7. Add the following code to schedule the job that calls the device method:

    var methodParams = {
        methodName: 'lockDoor',
        payload: null,
        responseTimeoutInSeconds: 15 // Timeout after 15 seconds if device is unable to process method
    };
    
    var methodJobId = uuid.v4();
    console.log('scheduling Device Method job with id: ' + methodJobId);
    jobClient.scheduleDeviceMethod(methodJobId,
                                queryCondition,
                                methodParams,
                                startTime,
                                maxExecutionTimeInSeconds,
                                function(err) {
        if (err) {
            console.error('Could not schedule device method job: ' + err.message);
        } else {
            monitorJob(methodJobId, function(err, result) {
                if (err) {
                    console.error('Could not monitor device method job: ' + err.message);
                } else {
                    console.log(JSON.stringify(result, null, 2));
                }
            });
        }
    });
    
  8. Add the following code to schedule the job to update the device twin:

    var twinPatch = {
       etag: '*', 
       properties: {
           desired: {
               building: '43', 
               floor: 3
           }
       }
    };
    
    var twinJobId = uuid.v4();
    
    console.log('scheduling Twin Update job with id: ' + twinJobId);
    jobClient.scheduleTwinUpdate(twinJobId,
                                queryCondition,
                                twinPatch,
                                startTime,
                                maxExecutionTimeInSeconds,
                                function(err) {
        if (err) {
            console.error('Could not schedule twin update job: ' + err.message);
        } else {
            monitorJob(twinJobId, function(err, result) {
                if (err) {
                    console.error('Could not monitor twin update job: ' + err.message);
                } else {
                    console.log(JSON.stringify(result, null, 2));
                }
            });
        }
    });
    
  9. Save and close the scheduleJobService.js file.

Run the applications

You are now ready to run the applications.

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

    node simDevice.js
    
  2. At the command prompt in the scheduleJobService folder, run the following command to trigger the jobs to lock the door and update the twin

    node scheduleJobService.js
    
  3. You see the device response to the direct method in the console.

Next steps

In this tutorial, you used a job to schedule a direct method to a device and the update of the device twin's properties.

To continue getting started with IoT Hub and device management patterns such as remote over the air firmware update, see:

Tutorial: How to do a firmware update

To continue getting started with IoT Hub, see Getting started with Azure IoT Edge.