如何计划和广播作业

本文介绍了如何创建后端应用代码来计划和广播作业。

使用 Azure IoT 中心来计划和跟踪作业,以更新数百万台设备来执行以下操作:

  • 调用直接方法
  • 更新的设备孪生

作业包装上述操作之一,并跟踪针对一组设备(由设备孪生查询定义)的执行情况。 例如,后端应用可以使用作业在 10,000 台设备上调用直接方法来重启设备。 使用设备孪生查询指定设备集,并将作业计划为在以后运行。 该任务在每个设备接收并执行重启直接方法时监控进度。

若要详细了解其中的每项功能,请参阅:

说明

本文所述的功能只能用于 IoT 中心的标准层。 有关 IoT 中心基本层和标准/免费层的详细信息,请参阅选择适用于解决方案的 IoT 中心层和大小

注意

本文旨在补充本文中引用的 Azure IoT SDK 示例。 可使用 SDK 工具生成设备和后端应用程序。

先决条件

  • 一个 IoT 中心

  • 已注册的设备

  • 如果应用程序使用 MQTT 协议,请确保端口 8883 在防火墙中打开。 MQTT 协议通过端口 8883 进行通信。 在某些公司和教育网络环境中,此端口可能被阻止。 有关解决此问题的更多信息和方法,请参阅连接到 IoT 中心(MQTT)

  • 需要 Visual Studio

概述

本文介绍了如何使用适用于 .NET 的 Azure IoT SDK 为计划作业创建后端服务应用程序代码,以调用直接方法或在一个或多个设备上执行设备孪生更新。

添加服务 NuGet 包

后端服务应用程序需要 NuGet 包“Microsoft.Azure.Devices”

Using 语句

添加以下 using 语句。

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;

using System.Threading;
using System.Threading.Tasks;

连接到 IoT 中心

可使用以下方法将后端服务连接到 IoT 中心:

  • 共享访问策略
  • Microsoft Entra

重要

本文介绍使用共享访问签名连接到服务的步骤。 虽然可使用此身份验证方法进行测试和评估,但使用 Microsoft Entra ID 或托管标识对设备进行身份验证是一种更安全的方法。 若要了解详细信息,请参阅 IoT 解决方案 > 云安全性的安全最佳做法

使用共享访问策略进行连接

使用 CreateFromConnectionString 将后端应用程序连接到设备。

本文介绍了可以计划作业以调用直接方法的后端代码、可以计划作业以更新设备孪生的后端代码,以及可以监视一个或多个设备的作业进度的后端代码。 若要执行这些操作,服务需要“注册表读取”和“注册表写入”权限。 默认情况下,每个 IoT 中心都使用名为 registryReadWrite的共享访问策略创建,该策略会授予这些权限。

有关共享访问策略的详细信息,请参阅使用共享访问签名控制对 IoT 中心的访问

static JobClient jobClient;
static string connectionString = "{Shared access policy connection string}";
jobClient = JobClient.CreateFromConnectionString(connString);

使用 Microsoft Entra 进行连接

使用 Microsoft Entra 的后端应用必须在连接到 IoT 中心之前成功完成身份验证并获取安全令牌凭据。 此令牌将传递给 IoT 中心连接方法。 有关为 IoT 中心设置和使用 Microsoft Entra 的一般信息,请参阅使用 Microsoft Entra ID 控制对 IoT 中心的访问

配置 Microsoft Entra 应用

必须设置一个针对首选身份验证凭据进行配置的 Microsoft Entra 应用。 该应用包含由后端应用程序用来进行身份验证的参数,例如客户端机密。 可用的应用身份验证配置如下:

  • 客户密钥
  • 证书
  • 联合身份凭据

根据正在执行的操作,Microsoft Entra 应用可能需要特定的角色权限。 例如,需要 IoT 中心孪生参与者角色才能启用对 IoT 中心设备和模块孪生的读写访问权限。 有关详细信息,请参阅使用 Azure RBAC 角色分配管理对 IoT 中心的访问

有关设置 Microsoft Entra 应用的详细信息,请参阅快速入门:将应用程序注册到 Microsoft 标识平台

使用 DefaultAzureCredential 进行身份验证

使用 Microsoft Entra 对后端应用程序进行身份验证的最简单方法是使用 DefaultAzureCredential,但建议在生产环境中使用其他方法,包括特定的 TokenCredential 或精简的 ChainedTokenCredential。 为简单起见,本部分介绍如何使用 DefaultAzureCredential 和客户端机密进行身份验证。 有关使用 DefaultAzureCredential 的利弊的详细信息,请参阅 DefaultAzureCredential 的使用指南

DefaultAzureCredential 支持不同的身份验证机制,并根据其执行环境确定相应的凭据类型。 它会尝试按顺序使用多种凭据类型,直到找到有效的凭据。

Microsoft Entra 需要这些 NuGet 包和相应的 using 语句:

  • Azure.Core
  • Azure.Identity
using Azure.Core;
using Azure.Identity;

在此示例中,Microsoft Entra 应用注册客户端机密、客户端 ID 和租户 ID 将添加到环境变量中。 DefaultAzureCredential 使用这些环境变量对应用程序进行身份验证。 成功 Microsoft Entra 身份验证的结果是传递给 IoT 中心连接方法的安全令牌凭据。

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

然后,可以将生成的 TokenCredential 传递给任何接受 Microsoft Entra 凭据的 SDK 客户端的连接到 IoT 中心方法:

在此示例中,TokenCredential 将传递给 ServiceClient.Create,以创建 ServiceClient 连接对象。

string hostname = "xxxxxxxxxx.azure-devices.net";
using var serviceClient = ServiceClient.Create(hostname, tokenCredential, TransportType.Amqp);

在此示例中,TokenCredential 将传递给 RegistryManager.Create,以创建 RegistryManager 对象。

string hostname = "xxxxxxxxxx.azure-devices.net";
registryManager = RegistryManager.Create(hostname, tokenCredential);
代码示例

有关 Microsoft Entra 服务身份验证的有效示例,请参阅基于角色的身份验证示例

计划直接方法作业

使用 ScheduleDeviceMethodAsync 来计划作业,以在一个或多个设备上运行直接方法。

使用 CloudToDeviceMethod 对象指定直接方法名称和设备连接超时值。

例如:

// The CloudToDeviceMethod record specifies the direct method name and device connection time-out
CloudToDeviceMethod directMethod = 
new CloudToDeviceMethod("LockDoor", TimeSpan.FromSeconds(5), 
TimeSpan.FromSeconds(5));

此示例在名为“Device-1”的设备上为名为“LockDoor”的直接方法计划作业。 计划的作业中包括的设备被包含为第二个参数,用作查询条件。 有关查询条件的详细信息,请参阅适用于设备和模块孪生、作业和消息路由的 IoT 中心查询语言

string methodJobId = Guid.NewGuid().ToString();  // a unique job ID
static string deviceId = "Device-1";             // In this example, there is only one device affected
JobResponse result = await jobClient.ScheduleDeviceMethodAsync(methodJobId,
   $"DeviceId IN ['{deviceId}']",
   directMethod,
   DateTime.UtcNow,
   (long)TimeSpan.FromMinutes(2).TotalSeconds);

计划设备孪生更新作业

使用 ScheduleTwinUpdateAsync 来调度一个新的设备孪生更新作业,以更新一个或多个设备上的期望属性和标签。

首先,创建并填充用于更新的设备孪生对象。 例如:

static string deviceId = "Device-1";

Twin twin = new Twin(deviceId);
twin.Tags = new TwinCollection();
twin.Tags["Building"] = "43";
twin.Tags["Floor"] = "3";
twin.ETag = "*";
twin.Properties.Desired["LocationUpdate"] = DateTime.UtcNow;

接下来,调用 ScheduleTwinUpdateAsync。 在第二个参数中将要更新的设备指定为查询。 有关查询条件的详细信息,请参阅适用于设备和模块孪生、作业和消息路由的 IoT 中心查询语言

string twinJobId = Guid.NewGuid().ToString();

JobResponse createJobResponse = jobClient.ScheduleTwinUpdateAsync(
   twinJobId,
   $"DeviceId IN ['{deviceId}']", 
   twin, 
   DateTime.UtcNow, 
   (long)TimeSpan.FromMinutes(2).TotalSeconds).Result;

监视作业

使用 GetJobAsync 监视特定作业 ID 的作业状态。

此示例定期检查作业 ID 的作业状态,直到作业状态为完成或失败。 例如:

JobResponse result;
do
{
   result = await jobClient.GetJobAsync(jobId);
   Console.WriteLine("Job Status : " + result.Status.ToString());
   Thread.Sleep(2000);
} while ((result.Status != JobStatus.Completed) && (result.Status != JobStatus.Failed));

SDK 计划作业示例

适用于 .NET 的 Azure IoT SDK 提供了用于处理作业计划任务的有效服务应用示例。 有关详细信息,请参阅:

概述

本文介绍了如何使用适用于 Java 的 Azure IoT SDK 为计划作业创建后端服务应用程序代码,以调用直接方法或在一个或多个设备上执行设备孪生更新。

服务导入语句

JobClient 类包含服务可用来计划作业的方法。

使用以下服务导入语句访问适用于 Java 的 Azure IoT SDK。

import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwinDevice;
import com.microsoft.azure.sdk.iot.service.devicetwin.Pair;
import com.microsoft.azure.sdk.iot.service.devicetwin.Query;
import com.microsoft.azure.sdk.iot.service.devicetwin.SqlQuery;
import com.microsoft.azure.sdk.iot.service.jobs.JobClient;
import com.microsoft.azure.sdk.iot.service.jobs.JobResult;
import com.microsoft.azure.sdk.iot.service.jobs.JobStatus;

import java.util.Date;
import java.time.Instant;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

连接到 IoT 中心

可使用以下方法将后端服务连接到 IoT 中心:

  • 共享访问策略
  • Microsoft Entra

重要

本文介绍使用共享访问签名连接到服务的步骤。 虽然可使用此身份验证方法进行测试和评估,但使用 Microsoft Entra ID 或托管标识对设备进行身份验证是一种更安全的方法。 若要了解详细信息,请参阅 IoT 解决方案 > 云安全性的安全最佳做法

使用共享访问策略进行连接

使用 JobClient 构造函数创建与 IoT 中心的连接。 JobClient 对象处理与 IoT 中心之间的通信。

本文介绍了可以计划作业以调用直接方法的后端代码、可以计划作业以更新设备孪生的后端代码,以及可以监视一个或多个设备的作业进度的后端代码。 若要执行这些操作,服务需要“注册表读取”和“注册表写入”权限。 默认情况下,每个 IoT 中心都使用名为 registryReadWrite的共享访问策略创建,该策略会授予这些权限。

有关共享访问策略的详细信息,请参阅使用共享访问签名控制对 IoT 中心的访问

例如:

public static final String iotHubConnectionString = "{Shared access policy connection string}";
JobClient jobClient = new JobClient(iotHubConnectionString);

使用 Microsoft Entra 进行连接

使用 Microsoft Entra 的后端应用必须在连接到 IoT 中心之前成功完成身份验证并获取安全令牌凭据。 此令牌将传递给 IoT 中心连接方法。 有关为 IoT 中心设置和使用 Microsoft Entra 的一般信息,请参阅使用 Microsoft Entra ID 控制对 IoT 中心的访问

有关 Java SDK 身份验证的概述,请参阅使用 Java 和 Azure 标识进行 Azure 身份验证

为简单起见,本部分重点介绍如何使用客户端机密进行身份验证。

配置 Microsoft Entra 应用

必须设置一个针对首选身份验证凭据进行配置的 Microsoft Entra 应用。 该应用包含由后端应用程序用来进行身份验证的参数,例如客户端机密。 可用的应用身份验证配置如下:

  • 客户端密码
  • 证书
  • 联邦身份凭证

根据正在执行的操作,Microsoft Entra 应用可能需要特定的角色权限。 例如,需要 IoT 中心孪生参与者角色才能启用对 IoT 中心设备和模块孪生的读写访问权限。 有关详细信息,请参阅使用 Azure RBAC 角色分配管理对 IoT 中心的访问

有关设置 Microsoft Entra 应用的详细信息,请参阅快速入门:将应用程序注册到 Microsoft 标识平台

使用 DefaultAzureCredential 进行身份验证

使用 Microsoft Entra 对后端应用程序进行身份验证的最简单方法是使用 DefaultAzureCredential,但建议在生产环境中使用其他方法,包括特定的 TokenCredential 或精简的 ChainedTokenCredential。 有关使用 DefaultAzureCredential 的利弊的详细信息,请参阅适用于 Java 的 Azure 标识客户端库中的凭据链

DefaultAzureCredential 支持不同的身份验证机制,并根据其执行环境确定相应的凭据类型。 它会尝试按顺序使用多种凭据类型,直到找到有效的凭据。

可以使用 DefaultAzureCredentialBuilder 来验证 Microsoft Entra 应用凭据。 客户端机密 tenantID、clientID 和客户端机密值等连接参数将保存为环境变量。 创建 TokenCredential 后,请将其作为“credential”参数传递给 ServiceClient 或其他生成器。

在此示例中,DefaultAzureCredentialBuilder 尝试根据 DefaultAzureCredential 中描述的列表对连接进行身份验证。 成功进行的 Microsoft Entra 身份验证的结果是一个安全令牌凭据,该凭据会被传递给 ServiceClient 等构造函数。

TokenCredential defaultAzureCredential = new DefaultAzureCredentialBuilder().build();
使用 ClientSecretCredentialBuilder 进行身份验证

可以使用 ClientSecretCredentialBuilder 来创建使用客户端机密信息的凭据。 如果成功,此方法将返回 TokenCredential,可将其作为“credential”参数传递给 ServiceClient 或其他生成器。

在此示例中,Microsoft Entra 应用注册客户端机密、客户端 ID 和租户 ID 值已添加到环境变量中。 ClientSecretCredentialBuilder 使用这些环境变量来生成凭据。

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();
其他身份验证类

Java SDK 还包括以下使用 Microsoft Entra 对后端应用程序进行身份验证的类:

代码示例

有关 Microsoft Entra 服务身份验证的有效示例,请参阅基于角色的身份验证示例

计划直接方法更新作业

使用 scheduleDeviceMethod 在一个或多个设备上运行直接方法。

此示例方法在名为“Device-1”的设备上为名为“lockDoor”的直接方法计划作业。

// Schedule a job now to call the lockDoor direct method
// against a single device. Response and connection
// timeouts are set to 5 seconds.
String deviceId = "Device-1";
String jobId = "DMCMD" + UUID.randomUUID();  //Job ID must be unique

// How long the job is permitted to run without
// completing its work on the set of devices
private static final long maxExecutionTimeInSeconds = 30;

System.out.println("Schedule job " + jobId + " for device " + deviceId);
try {
  JobResult jobResult = jobClient.scheduleDeviceMethod(jobId,
    "deviceId='" + deviceId + "'",
    "lockDoor",
    5L, 5L, null,
    new Date(),
    maxExecutionTimeInSeconds);
} catch (Exception e) {
  System.out.println("Exception scheduling direct method job: " + jobId);
  System.out.println(e.getMessage());
}

计划设备孪生更新作业

使用 scheduleUpdateTwin 来计划作业以在一个或多个设备上运行设备孪生更新。

首先,为设备孪生更新准备 DeviceTwinDevice 记录。 例如:

String deviceId = "Device-1";

//Create a device twin desired properties update object
DeviceTwinDevice twin = new DeviceTwinDevice(deviceId);
Set<Pair> desiredProperties = new HashSet<Pair>();
desiredProperties.add(new Pair("Building", 43));
desiredProperties.add(new Pair("Floor", 3));
twin.setDesiredProperties(desiredProperties);
// Optimistic concurrency control
twin.setETag("*");

然后调用 scheduleUpdateTwin 来计划更新作业。 例如:

String jobId = "DPCMD" + UUID.randomUUID();  //Unique job ID

// How long the job is permitted to run without
// completing its work on the set of devices
private static final long maxExecutionTimeInSeconds = 30;

// Schedule the update twin job to run now for a single device
System.out.println("Schedule job " + jobId + " for device " + deviceId);
try {
  JobResult jobResult = jobClient.scheduleUpdateTwin(jobId, 
    "deviceId='" + deviceId + "'",
    twin,
    new Date(),
    maxExecutionTimeInSeconds);
} catch (Exception e) {
  System.out.println("Exception scheduling desired properties job: " + jobId);
  System.out.println(e.getMessage());
}

监视作业

使用 getJob 根据特定作业 ID 提取作业信息。 getJob 返回一个 JobResult 对象,该对象包含你可用来检查作业信息(包括运行状态)的方法和属性。

例如:

try {
  JobResult jobResult = jobClient.getJob(jobId);
  if(jobResult == null)
  {
    System.out.println("No JobResult for: " + jobId);
    return;
  }
  // Check the job result until it's completed
  while(jobResult.getJobStatus() != JobStatus.completed)
  {
    Thread.sleep(100);
    jobResult = jobClient.getJob(jobId);
    System.out.println("Status " + jobResult.getJobStatus() + " for job " + jobId);
  }
  System.out.println("Final status " + jobResult.getJobStatus() + " for job " + jobId);
} catch (Exception e) {
  System.out.println("Exception monitoring job: " + jobId);
  System.out.println(e.getMessage());
  return;
}

查询作业状态

使用 queryDeviceJob 查询一个或多个作业的作业状态。

例如:

private static void queryDeviceJobs(JobClient jobClient, String start) throws Exception {
  System.out.println("\nQuery device jobs since " + start);

  // Create a jobs query using the time the jobs started
  Query deviceJobQuery = jobClient
      .queryDeviceJob(SqlQuery.createSqlQuery("*", SqlQuery.FromType.JOBS, "devices.jobs.startTimeUtc > '" + start + "'", null).getQuery());

  // Iterate over the list of jobs and print the details
  while (jobClient.hasNextJob(deviceJobQuery)) {
    System.out.println(jobClient.getNextJob(deviceJobQuery));
  }
}

SDK 计划作业示例

适用于 Java 的 Azure IoT SDK 提供了用于处理作业计划任务的有效服务应用示例。 有关详细信息,请参阅作业客户端示例

  • Python SDK - 建议使用 Python 3.7 或更高版本。 请确保根据安装程序的要求,使用 32 位或 64 位安装。 在安装过程中出现提示时,请确保将 Python 添加到特定于平台的环境变量中。

概述

本文介绍了如何使用适用于 Python 的 Azure IoT SDK 为计划作业创建后端服务应用程序代码,以调用直接方法或在一个或多个设备上执行设备孪生所需属性更新。

安装包

必须安装 azure-iot-hub 库才能创建后端服务应用程序

pip install azure-iot-hub

Import 语句

IoTHubJobManager 类公开了创建后端应用程序以通过该服务计划作业所需的所有方法。

添加以下 import 语句。

import os
import sys
import datetime
import time
import threading
import uuid
import msrest

from azure.iot.hub import IoTHubJobManager
from azure.iot.hub.models import JobProperties, JobRequest, Twin, TwinProperties, CloudToDeviceMethod

连接到 IoT 中心

可使用以下方法将后端服务连接到 IoT 中心:

  • 共享访问策略
  • Microsoft Entra

重要

本文介绍使用共享访问签名连接到服务的步骤。 虽然可使用此身份验证方法进行测试和评估,但使用 Microsoft Entra ID 或托管标识对设备进行身份验证是一种更安全的方法。 若要了解详细信息,请参阅 IoT 解决方案 > 云安全性的安全最佳做法

使用共享访问策略进行连接

使用 from_connection_string 连接到 IoT 中心。

本文介绍了可以计划作业以调用直接方法的后端代码、可以计划作业以更新设备孪生的后端代码,以及可以监视一个或多个设备的作业进度的后端代码。 若要执行这些操作,服务需要“注册表读取”和“注册表写入”权限。 默认情况下,每个 IoT 中心都使用名为 registryReadWrite的共享访问策略创建,该策略会授予这些权限。

有关共享访问策略的详细信息,请参阅使用共享访问签名控制对 IoT 中心的访问

例如:

IoTHubConnectionString = "{Shared access policy connection string}"
iothub_job_manager = IoTHubJobManager.from_connection_string(IoTHubConnectionString)

使用 Microsoft Entra 进行连接

使用 Microsoft Entra 的后端应用必须在连接到 IoT 中心之前成功完成身份验证并获取安全令牌凭据。 此令牌将传递给 IoT 中心连接方法。 有关为 IoT 中心设置和使用 Microsoft Entra 的一般信息,请参阅使用 Microsoft Entra ID 控制对 IoT 中心的访问

配置 Microsoft Entra 应用

必须设置一个针对首选身份验证凭据进行配置的 Microsoft Entra 应用。 该应用包含由后端应用程序用来进行身份验证的参数,例如客户端机密。 可用的应用身份验证配置如下:

  • 客户端密钥
  • 证书
  • 联邦身份凭据

根据正在执行的操作,Microsoft Entra 应用可能需要特定的角色权限。 例如,需要 IoT 中心孪生参与者角色才能启用对 IoT 中心设备和模块孪生的读写访问权限。 有关详细信息,请参阅使用 Azure RBAC 角色分配管理对 IoT 中心的访问

有关设置 Microsoft Entra 应用的详细信息,请参阅快速入门:将应用程序注册到 Microsoft 标识平台

使用 DefaultAzureCredential 进行身份验证

使用 Microsoft Entra 对后端应用程序进行身份验证的最简单方法是使用 DefaultAzureCredential,但建议在生产环境中使用其他方法,包括特定的 TokenCredential 或精简的 ChainedTokenCredential。 为简单起见,本部分介绍如何使用 DefaultAzureCredential 和客户端机密进行身份验证。 有关使用 DefaultAzureCredential 的利弊的详细信息,请参阅 DefaultAzureCredential 的使用指南

DefaultAzureCredential 支持不同的身份验证机制,并根据其执行环境确定相应的凭据类型。 它会尝试按顺序使用多种凭据类型,直到找到有效的凭据。

Microsoft Entra 需要这些 NuGet 包和相应的 using 语句:

  • Azure.Core
  • Azure.Identity
using Azure.Core;
using Azure.Identity;

在此示例中,Microsoft Entra 应用注册客户端机密、客户端 ID 和租户 ID 将添加到环境变量中。 DefaultAzureCredential 使用这些环境变量对应用程序进行身份验证。 成功 Microsoft Entra 身份验证的结果是传递给 IoT 中心连接方法的安全令牌凭据。

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

然后,可以将生成的 TokenCredential 传递给任何接受 Microsoft Entra 凭据的 SDK 客户端的连接到 IoT 中心方法:

在此示例中,TokenCredential 将传递给 ServiceClient.Create,以创建 ServiceClient 连接对象。

string hostname = "xxxxxxxxxx.azure-devices.net";
using var serviceClient = ServiceClient.Create(hostname, tokenCredential, TransportType.Amqp);

在此示例中,TokenCredential 将传递给 RegistryManager.Create,以创建 RegistryManager 对象。

string hostname = "xxxxxxxxxx.azure-devices.net";
registryManager = RegistryManager.Create(hostname, tokenCredential);
代码示例

有关 Microsoft Entra 服务身份验证的有效示例,请参阅基于角色的身份验证示例

计划直接方法作业

使用 create_scheduled_job 来计划新的直接方法,以在一个或多个设备上运行直接方法。

create_scheduled_job 参数说明:

  • job_id 必须唯一
  • type 设置为 scheduleDeviceMethod
  • 使用 cloud_to_device_method 设置直接方法名称和有效负载
  • 使用 max_execution_time_in_seconds 指定执行时间(以秒为单位)
  • 使用 query_condition 指定要包括在直接方法调用中的设备。 有关查询条件的详细信息,请参阅适用于设备和模块孪生、作业和消息路由的 IoT 中心查询语言

例如:

METHOD_NAME = "lockDoor"
METHOD_PAYLOAD = "{\"lockTime\":\"10m\"}"
job_id = uuid.uuid4()
DEVICE_ID = "Device-1"
TIMEOUT = 60

job_request = JobRequest()
job_request.job_id = job_id
job_request.type = "scheduleDeviceMethod"
job_request.start_time = datetime.datetime.utcnow().isoformat()
job_request.cloud_to_device_method = CloudToDeviceMethod(method_name=METHOD_NAME, payload=METHOD_PAYLOAD)
job_request.max_execution_time_in_seconds = TIMEOUT
job_request.query_condition = "DeviceId in ['{}']".format(device_id)

new_job_response = iothub_job_manager.create_scheduled_job(job_id, job_request)

计划设备孪生更新作业

使用 create_scheduled_job 来创建新作业,以在一个或多个设备上运行设备孪生所需属性更新。

create_scheduled_job 参数说明:

  • job_id 必须唯一
  • type 设置为 scheduleUpdateTwin
  • 使用 update_twin 设置直接方法名称和有效负载
  • 使用 max_execution_time_in_seconds 指定执行时间(以秒为单位)
  • 使用 query_condition 为具有直接方法调用的一个或多个设备指定条件。 有关查询条件的详细信息,请参阅适用于设备和模块孪生、作业和消息路由的 IoT 中心查询语言

例如:

UPDATE_PATCH = {"building":43,"floor":3}
job_id = uuid.uuid4()
TIMEOUT = 60

job_request = JobRequest()
job_request.job_id = job_id
job_request.type = "scheduleUpdateTwin"
job_request.start_time = datetime.datetime.utcnow().isoformat()
job_request.update_twin = Twin(etag="*", properties=TwinProperties(desired=UPDATE_PATCH))
job_request.max_execution_time_in_seconds = TIMEOUT
job_request.query_condition = "DeviceId in ['{}']".format(device_id)

new_job_response = iothub_job_manager.create_scheduled_job(job_id, job_request)

监视作业

使用 get_scheduled_job 检索 IoT 中心上特定作业的详细信息。

此示例每隔五秒检查一次特定作业 ID 的作业状态,直到作业完成。

while True:
    get_job_response = iothub_job_manager.get_scheduled_job(job_request.job_id)
    print_job_response("Get job response: ", get_job_response)
    if get_job_response.status == "completed":
      print ( "Job is completed." )
    time.sleep(5)

SDK 计划作业示例

适用于 Python 的 Azure IoT SDK 提供了用于处理作业计划任务的有效服务应用示例。 有关详细信息,请参阅:

  • 需要 Node.js 10.0.x 版或更高版本

概述

本文介绍了如何使用适用于 Node.js 的 Azure IoT SDK 为计划作业创建后端服务应用程序代码,以调用直接方法或在一个或多个设备上执行设备孪生更新。

安装服务 SDK 包

运行以下命令,在开发计算机上安装“azure-iothub”:

npm install azure-iothub --save

JobClient 类公开了从后端应用程序与作业计划操作进行交互所需的所有方法。

连接到 IoT 中心

可使用以下方法将后端服务连接到 IoT 中心:

  • 共享访问策略
  • Microsoft Entra

重要

本文介绍使用共享访问签名连接到服务的步骤。 虽然可使用此身份验证方法进行测试和评估,但使用 Microsoft Entra ID 或托管标识对设备进行身份验证是一种更安全的方法。 若要了解详细信息,请参阅 IoT 解决方案 > 云安全性的安全最佳做法

使用共享访问策略进行连接

使用 fromConnectionString 连接到 IoT 中心。

本文介绍了可以计划作业以调用直接方法的后端代码、可以计划作业以更新设备孪生的后端代码,以及可以监视一个或多个设备的作业进度的后端代码。 若要执行这些操作,服务需要“注册表读取”和“注册表写入”权限。 默认情况下,每个 IoT 中心都使用名为 registryReadWrite的共享访问策略创建,该策略会授予这些权限。

有关共享访问策略的详细信息,请参阅使用共享访问签名控制对 IoT 中心的访问

例如:

'use strict';
var JobClient = require('azure-iothub').JobClient;
var connectionString = '{Shared access policy connection string}';
var jobClient = JobClient.fromConnectionString(connectionString);

使用 Microsoft Entra 进行连接

使用 Microsoft Entra 的后端应用必须在连接到 IoT 中心之前成功完成身份验证并获取安全令牌凭据。 此令牌将传递给 IoT 中心连接方法。 有关为 IoT 中心设置和使用 Microsoft Entra 的一般信息,请参阅使用 Microsoft Entra ID 控制对 IoT 中心的访问

有关 Node.js SDK 身份验证的概述,请参阅:

配置 Microsoft Entra 应用

必须设置一个针对首选身份验证凭据进行配置的 Microsoft Entra 应用。 该应用包含由后端应用程序用来进行身份验证的参数,例如客户端机密。 可用的应用身份验证配置如下:

  • 客户端密钥
  • 证书
  • 联合身份凭据

根据正在执行的操作,Microsoft Entra 应用可能需要特定的角色权限。 例如,需要IoT 中心孪生体贡献者角色才能启用对 IoT 中心设备和模块孪生体的读写访问权限。 有关详细信息,请参阅使用 Azure RBAC 角色分配管理对 IoT 中心的访问

有关设置 Microsoft Entra 应用的详细信息,请参阅快速入门:将应用程序注册到 Microsoft 标识平台

使用 DefaultAzureCredential 进行身份验证

使用 Microsoft Entra 对后端应用程序进行身份验证的最简单方法是使用 DefaultAzureCredential,但建议在生产环境中使用其他方法,包括特定的 TokenCredential 或精简的 ChainedTokenCredential。 为简单起见,本部分介绍如何使用 DefaultAzureCredential 和客户端机密进行身份验证。 有关使用 DefaultAzureCredential 的利弊的详细信息,请参阅适用于 JavaScript 的 Azure 标识客户端库中的凭据链

DefaultAzureCredential 支持不同的身份验证机制,并根据其执行环境确定相应的凭据类型。 它会尝试按顺序使用多种凭据类型,直到找到有效的凭据。

Microsoft Entra 需要此包:

npm install --save @azure/identity

在此示例中,Microsoft Entra 应用注册客户端机密、客户端 ID 和租户 ID 已添加到环境变量中。 DefaultAzureCredential 使用这些环境变量对应用程序进行身份验证。 成功的 Microsoft Entra 身份验证的结果是将安全令牌凭据传递给 IoT 中心连接方法。

import { DefaultAzureCredential } from "@azure/identity";

// Azure SDK clients accept the credential as a parameter
const credential = new DefaultAzureCredential();

然后,可以将生成的凭据令牌传递给 fromTokenCredential,以连接到接受 Microsoft Entra 凭据的任何 SDK 客户端的 IoT 中心:

fromTokenCredential 需要两个参数:

  • Azure 服务 URL - Azure 服务 URL 应采用 {Your Entra ___domain URL}.azure-devices.net 格式(不包括 https:// 前缀)。 例如,MyAzureDomain.azure-devices.net
  • 微软 Azure 凭据令牌

在此示例中,使用 DefaultAzureCredential 获取 Azure 凭据。 然后将 Azure 域 URL 和凭据提供给 Registry.fromTokenCredential,以便与 IoT 中心创建连接。

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);
代码示例

有关 Microsoft Entra 服务身份验证的有效示例,请参阅 Azure 标识示例

创建直接方法作业

使用 scheduleDeviceMethod 来计划作业,以在一个或多个设备上运行直接方法。

首先,使用方法名称、有效负载和响应超时信息创建一个直接方法更新变量。 例如:

var methodParams = {
    methodName: 'lockDoor',
    payload: null,
    responseTimeoutInSeconds: 15 // Time-out after 15 seconds if device is unable to process method
};

然后调用 scheduleDeviceMethod 来计划该直接方法调用作业:

  • 每个作业必须具有唯一的作业 ID。 可以使用此作业 ID 来监视作业,如本文“监视作业”部分中所述。
  • 指定 queryCondition 参数以评估要在其上运行作业的设备。 有关查询条件的详细信息,请参阅适用于设备和模块孪生、作业和消息路由的 IoT 中心查询语言
  • 检查 jobResult 回调来了解作业计划结果。 如果作业已成功计划,则你可以监视作业状态,如本文“监视作业”部分中所示。

例如:

var methodJobId = uuid.v4();
var queryCondition = "deviceId IN ['myDeviceId']";
var startTime = new Date();
var maxExecutionTimeInSeconds =  300;

jobClient.scheduleDeviceMethod(methodJobId,
                            queryCondition,
                            methodParams,
                            startTime,
                            maxExecutionTimeInSeconds,
                            function(err) {
    if (err) {
        console.error('Could not schedule direct method job: ' + err.message);
    } else {
        monitorJob(methodJobId, function(err, result) {
            if (err) {
                console.error('Could not monitor direct method job: ' + err.message);
            } else {
                console.log(JSON.stringify(result, null, 2));
            }
        });
    }
});

计划设备孪生更新作业

使用 scheduleTwinUpdate 来创建新作业以在一个或多个设备上运行设备孪生更新。

首先,创建一个设备孪生所需属性更新变量。

var twinPatch = {
   etag: '*',
   properties: {
       desired: {
           building: '43',
           floor: 3
       }
   }
};

然后调用 scheduleTwinUpdate 来计划设备孪生所需属性更新作业:

  • 每个作业必须具有唯一的作业 ID。 可以使用此作业 ID 来监视作业,如本文“监视作业”部分中所述。
  • 指定 queryCondition 参数以评估要在其上运行作业的设备。 有关查询条件的详细信息,请参阅适用于设备和模块孪生、作业和消息路由的 IoT 中心查询语言
  • 检查 jobResult 回调来了解作业计划结果。 如果作业已成功计划,则你可以监视作业状态,如本文“监视作业”部分中所示。

例如:

var twinJobId = uuid.v4();
var queryCondition = "deviceId IN ['myDeviceId']";
var startTime = new Date();
var maxExecutionTimeInSeconds =  300;

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));
            }
        });
    }
});

监视作业

使用 getJob 监视特定作业 ID 的作业状态。

此示例函数定期检查特定作业 ID 的作业状态,直到作业完成或失败。

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);
}

SDK 计划作业示例

适用于 Node.js 的 Azure IoT SDK 提供了用于处理作业计划任务的有效服务应用示例。 有关详细信息,请参阅作业客户端 E2E 测试