模块标识和模块标识孪生类似于 Azure IoT 中心设备标识和设备孪生,但提供更精细的粒度。 Azure IoT 中心设备标识和设备孪生允许后端应用程序配置设备并提供设备条件的可见性,而模块标识和模块标识孪生为设备的各个组件提供这些功能。 在支持多个组件的设备上(例如操作系统设备或固件设备),模块标识和模块标识孪生允许每个部件拥有独立的配置和条件。 有关详细信息,请参阅了解 Azure IoT 中心模块孪生。
备注
本文所述的功能只能用于 IoT 中心的标准层。 有关 IoT 中心基本层和标准/免费层的详细信息,请参阅选择适合你的解决方案的 IoT 中心层。
本文介绍如何开发两种类型的应用程序:
- 设备应用,用于查看和更新模块标识孪生报告属性并处理更新所需属性的请求。
- 服务应用,可读取和设置模块标识所需属性。
备注
本文旨在补充本文中引用的 Azure IoT SDK 示例。 可使用 SDK 工具生成设备和后端应用程序。
一个 IoT 中心
IoT 中心设备
IoT 中心设备模块标识
如果应用程序使用 MQTT 协议,请确保端口 8883 在防火墙中打开。 MQTT 协议通过端口 8883 进行通信。 在某些公司和教育网络环境中,此端口可能被阻止。
- 需要 Visual Studio
本文介绍如何使用适用于 .NET 的 Azure IoT SDK 为设备标识孪生创建设备和后端服务应用程序代码。
本部分介绍如何使用设备应用程序代码进行以下操作:
- 检索模块标识孪生并检查报告属性
- 更新报告模块标识孪生属性
- 创建模块所需属性更新回调处理程序
重要
本文包括使用共享访问签名(也称为对称密钥身份验证)连接设备的步骤。 此身份验证方法便于测试和评估,但使用 X.509 证书对设备进行身份验证是一种更安全的方法。
使用 C# 编写的设备客户端应用程序需要 NuGet 包“Microsoft.Azure.Devices.Client”。
添加这些 using
语句以使用设备库。
using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;
ModuleClient 类公开从设备与模块标识孪生进行交互所需的所有方法。
使用 CreateFromConnectionString 方法和模块标识连接字符串连接到设备。
未指定传输参数时进行 CreateFromConnectionString
调用,将使用默认的 AMQP 传输进行连接。
此示例使用默认 AMQP 传输连接到设备。
static string ModuleConnectionString = "{Device module identity connection string}";
private static ModuleClient _moduleClient = null;
_moduleClient = ModuleClient.CreateFromConnectionString(ModuleConnectionString, null);
调用 GetTwinAsync,将当前模块标识孪生属性检索到 Twin 对象中。
此示例检索并显示 JSON 格式的模块标识孪生属性。
Console.WriteLine("Retrieving twin...");
Twin twin = await _moduleClient.GetTwinAsync();
Console.WriteLine("\tModule identity twin value received:");
Console.WriteLine(JsonConvert.SerializeObject(twin.Properties));
更新孪生报告属性:
- 为报告属性更新创建 TwinCollection 对象
- 更新
TwinCollection
对象中的一个或多个报告属性 - 使用 UpdateReportedPropertiesAsync 将报告属性更改推送到 IoT 中心服务
例如:
try
{
Console.WriteLine("Sending sample start time as reported property");
TwinCollection reportedProperties = new TwinCollection();
reportedProperties["DateTimeLastAppLaunch"] = DateTime.UtcNow;
await _moduleClient.UpdateReportedPropertiesAsync(reportedProperties);
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}
通过将回调处理程序方法名称传递到 SetDesiredPropertyUpdateCallbackAsync,创建在设备标识孪生中更改所需属性时执行的所需属性更新回调处理程序。
例如,此调用设置系统,以在更改所需模块属性时通知名为 OnDesiredPropertyChangedAsync
的方法。
await _moduleClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChangedAsync, null);
模块标识孪生属性以 TwinCollection 形式传递到回调方法,并且可作为 KeyValuePair
结构进行检查。
此示例以 TwinCollection
的形式接收所需属性更新,然后循环访问并输出 KeyValuePair
集合更新。 循环访问 KeyValuePair
集合后,代码调用 UpdateReportedPropertiesAsync
以更新 DateTimeLastDesiredPropertyChangeReceived
报告属性,使上次更新时间保持最新状态。
private async Task OnDesiredPropertyChangedAsync(TwinCollection desiredProperties, object userContext)
{
var reportedProperties = new TwinCollection();
Console.WriteLine("\tDesired properties requested:");
Console.WriteLine($"\t{desiredProperties.ToJson()}");
// For the purpose of this sample, we'll blindly accept all twin property write requests.
foreach (KeyValuePair<string, object> desiredProperty in desiredProperties)
{
Console.WriteLine($"Setting {desiredProperty.Key} to {desiredProperty.Value}.");
reportedProperties[desiredProperty.Key] = desiredProperty.Value;
}
Console.WriteLine("\tAlso setting current time as reported property");
reportedProperties["DateTimeLastDesiredPropertyChangeReceived"] = DateTime.UtcNow;
await _moduleClient.UpdateReportedPropertiesAsync(reportedProperties);
}
适用于 .NET 的 Azure IoT SDK 提供了处理模块标识孪生任务的设备应用中的有效示例。 有关详细信息,请参阅:
本部分介绍如何读取和更新模块标识字段。
RegistryManager 类公开创建后端应用程序以从服务与模块标识孪生进行交互所需的所有方法。
后端服务应用程序需要 NuGet 包“Microsoft.Azure.Devices”。
添加这些 using
语句以使用服务库。
using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;
可使用以下方法将后端服务连接到 IoT 中心:
- 共享访问策略
- Microsoft Entra
重要
本文介绍使用共享访问签名连接到服务的步骤。 虽然可使用此身份验证方法进行测试和评估,但使用 Microsoft Entra ID 或托管标识对设备进行身份验证是一种更安全的方法。
使用 CreateFromConnectionString 将后端应用程序连接到 IoT 中心。
本节中使用的 UpdateModuleAsync
方法需要“服务连接”共享访问策略权限才能将所需属性添加到模块。 作为 CreateFromConnectionString
的参数,提供包含“服务连接”权限的共享访问策略连接字符串。 有关共享访问策略的详细信息,请参阅使用共享访问签名控制对 IoT 中心的访问。
例如:
static RegistryManager registryManager;
static string connectionString = "{IoT hub shared access policy connection string}";
registryManager = RegistryManager.CreateFromConnectionString(connectionString);
使用 Microsoft Entra 的后端应用必须在连接到 IoT 中心之前成功完成身份验证并获取安全令牌凭据。 此令牌将传递给 IoT 中心连接方法。 有关为 IoT 中心设置和使用 Microsoft Entra 的一般信息,请参阅使用 Microsoft Entra ID 控制对 IoT 中心的访问。
必须设置一个针对首选身份验证凭据进行配置的 Microsoft Entra 应用。 该应用包含由后端应用程序用来进行身份验证的参数,例如客户端机密。 可用的应用身份验证配置如下:
- 客户端机密
- 证书
- 联合标识凭据
根据正在执行的操作,Microsoft Entra 应用可能需要特定的角色权限。 例如,需要 IoT 中心孪生参与者角色才能启用对 IoT 中心设备和模块孪生的读写访问权限。 有关详细信息,请参阅使用 Azure RBAC 角色分配管理对 IoT 中心的访问。
有关设置 Microsoft Entra 应用的详细信息,请参阅快速入门:将应用程序注册到 Microsoft 标识平台。
使用 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 服务身份验证的有效示例,请参阅基于角色的身份验证示例。
调用 GetModuleAsync,将当前模块标识孪生字段检索到 Module 对象中。
Module
类包括与模块标识孪生部分对应的 properties
。 使用 Module 类属性查看和更新模块标识孪生字段。 在使用 UpdateModuleAsync
将更新写入设备之前,可使用 Module
对象属性更新多个字段。
进行模块标识孪生字段更新后,调用 UpdateModuleAsync 将 Module
对象字段更新写回设备。 将 try
和 catch
逻辑与错误处理程序结合使用,从 UpdateModuleAsync
捕获格式不正确的修补程序错误。
此示例将模块检索到 Module
对象中,更新 module
LastActivityTime
属性,然后使用 UpdateModuleAsync
更新 IoT 中心中的模块。
// Retrieve the module
var module = await registryManager.GetModuleAsync("myDeviceId","myModuleId");
// Update the module object
module.LastActivityTime = DateTime.Now;
// Apply the patch to update the device twin tags section
try
{
await registryManager.UpdateModuleAsync(module);
}
catch (Exception e)
{
console.WriteLine("Module update failed.", e.Message);
}
- GetModulesOnDeviceAsync - 检索设备上的模块标识
- RemoveModuleAsync - 从设备中删除以前注册的模块
适用于 .NET 的 Azure IoT SDK 提供了处理模块标识孪生任务的服务应用的有效示例。 有关详细信息,请参阅注册表管理器 E2E 测试。
- 建议使用 Python 版本 3.7 或更高版本。 请确保根据安装程序的要求,使用 32 位或 64 位安装。 在安装过程中出现提示时,请确保将 Python 添加到特定于平台的环境变量中。
本文介绍如何使用适用于 Python 的 Azure IoT SDK 为设备标识孪生创建设备和后端服务应用程序代码。
必须安装 azure-iot-device 库才能创建设备应用程序。
pip install azure-iot-device
必须安装 azure-iot-hub 库才能创建后端服务应用程序。
pip install azure-iot-hub
msrest 库用于捕获 HTTPOperationError 异常。
pip install msrest
本部分介绍如何使用设备应用程序代码进行以下操作:
- 检索模块标识孪生并检查报告属性
- 更新模块标识孪生报告属性
- 创建模块标识孪生所需属性更新回调处理程序
重要
本文包括使用共享访问签名(也称为对称密钥身份验证)连接设备的步骤。 此身份验证方法便于测试和评估,但使用 X.509 证书对设备进行身份验证是一种更安全的方法。
添加此 import
语句以使用设备库。
# import the device client library
import asyncio
from azure.iot.device.aio import IoTHubDeviceClient
IoTHubModuleClient 类包含可用于处理模块标识孪生的方法。
将应用程序连接到设备:
- 调用 create_from_connection_string,以添加模块标识连接字符串
- 调用 connect,将设备客户端连接到 Azure IoT 中心
# import the device client library
import asyncio
from azure.iot.device.aio import IoTHubDeviceClient
# substitute the device connection string in conn_str
# and add it to the IoTHubDeviceClient object
conn_str = "{Device module identity connection string}"
device_client = IoTHubDeviceClient.create_from_connection_string(conn_str)
# connect the application to the device
await device_client.connect()
调用 get_twin,从 Azure IoT 中心服务检索模块标识孪生。 孪生信息放置在可检查的变量中。
此示例检索设备孪生,并使用 print
命令以 JSON 格式查看设备孪生。
# get the twin
twin = await device_client.get_twin()
print("Twin document:")
print("{}".format(twin))
可应用修补程序来更新 JSON 格式的模块标识孪生报告属性。
应用修补程序以更新报告属性:
- 将报告属性 JSON 修补程序分配给变量。
- 调用 patch_twin_reported_properties,将 JSON 修补程序应用于报告属性。
例如:
# create the reported properties patch
reported_properties = {"temperature": random.randint(320, 800) / 10}
print("Setting reported temperature to {}".format(reported_properties["temperature"]))
# update the reported properties and wait for the result
await device_client.patch_twin_reported_properties(reported_properties)
调用 on_twin_desired_properties_patch_received 以创建在接收模块标识孪生所需属性修补程序时调用的处理程序函数或协同例程。 处理程序采用一个参数,即 JSON 字典对象形式的孪生修补程序。
此示例设置名为 twin_patch_handler
的所需属性修补程序处理程序。
例如:
try:
# Set handlers on the client
device_client.on_twin_desired_properties_patch_received = twin_patch_handler
except:
# Clean up in the event of failure
client.shutdown()
twin_patch_handler
接收并输出 JSON 所需属性更新。
# Define behavior for receiving twin desired property patches
def twin_patch_handler(twin_patch):
print("Twin patch received:")
print(twin_patch)
适用于 Python 的 Azure IoT SDK 提供了处理模块标识孪生任务的设备应用中的有效示例:
- get_twin - 连接到设备并检索孪生信息。
- update_twin_reported_properties - 更新孪生报告属性。
- receive_twin_desired_properties - 接收和更新所需属性。
本部分介绍如何创建后端应用程序来检索和更新模块标识孪生所需属性。
IoTHubRegistryManager 类公开创建后端应用程序以从服务与模块标识孪生进行交互所需的所有方法。
添加此 import
语句以使用服务库。
import sys
from azure.iot.hub import IoTHubRegistryManager
from azure.iot.hub.models import Twin, TwinProperties, QuerySpecification, QueryResult
可使用以下方法将后端服务连接到 IoT 中心:
- 共享访问策略
- Microsoft Entra
重要
本文介绍使用共享访问签名连接到服务的步骤。 虽然可使用此身份验证方法进行测试和评估,但使用 Microsoft Entra ID 或托管标识对设备进行身份验证是一种更安全的方法。
使用 from_connection_string 连接到 IoT 中心。
本节中使用的 update_module_twin
方法需要“服务连接”共享访问策略权限才能将所需属性添加到模块。 作为 from_connection_string
的参数,提供包含“服务连接”权限的共享访问策略连接字符串。 有关共享访问策略的详细信息,请参阅使用共享访问签名控制对 IoT 中心的访问。
例如:
# Connect to IoT hub
IOTHUB_CONNECTION_STRING = "{IoT hub shared access policy connection string}"
iothub_registry_manager = IoTHubRegistryManager.from_connection_string(IOTHUB_CONNECTION_STRING)
使用 Microsoft Entra 的后端应用必须在连接到 IoT 中心之前成功完成身份验证并获取安全令牌凭据。 此令牌将传递给 IoT 中心连接方法。 有关为 IoT 中心设置和使用 Microsoft Entra 的一般信息,请参阅使用 Microsoft Entra ID 控制对 IoT 中心的访问。
有关 Python SDK 身份验证的概述,请参阅使用 Azure SDK for Python 向 Azure 服务进行 Python 应用身份验证
必须设置一个针对首选身份验证凭据进行配置的 Microsoft Entra 应用。 该应用包含由后端应用程序用来进行身份验证的参数,例如客户端机密。 可用的应用身份验证配置如下:
- 客户端机密
- 证书
- 联合标识凭据
根据正在执行的操作,Microsoft Entra 应用可能需要特定的角色权限。 例如,需要 IoT 中心孪生参与者角色才能启用对 IoT 中心设备和模块孪生的读写访问权限。 有关详细信息,请参阅使用 Azure RBAC 角色分配管理对 IoT 中心的访问。
有关设置 Microsoft Entra 应用的详细信息,请参阅快速入门:将应用程序注册到 Microsoft 标识平台。
使用 Microsoft Entra 对后端应用程序进行身份验证的最简单方法是使用 DefaultAzureCredential,但建议在生产环境中使用其他方法,包括特定的 TokenCredential
或精简的 ChainedTokenCredential
。 为简单起见,本部分介绍如何使用 DefaultAzureCredential
和客户端机密进行身份验证。 有关使用 DefaultAzureCredential
的利弊的详细信息,请参阅适用于 Python 的 Azure 标识客户端库中的凭据链。
DefaultAzureCredential 支持不同的身份验证机制,并根据其执行环境确定相应的凭据类型。 它会尝试按顺序使用多种凭据类型,直到找到有效的凭据。
Microsoft Entra 需要此导入包和相应的 import
语句:
pip install azure-identity
from azure.identity import DefaultAzureCredential
在此示例中,Microsoft Entra 应用注册客户端机密、客户端 ID 和租户 ID 已添加到环境变量中。 DefaultAzureCredential
使用这些环境变量对应用程序进行身份验证。 成功 Microsoft Entra 身份验证的结果是传递给 IoT 中心连接方法的安全令牌凭据。
from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()
然后可以将生成的 AccessToken 传递给 from_token_credential
,以连接到任何接受 Microsoft Entra 凭据的 SDK 客户端的 IoT 中心:
- IoTHubRegistryManager,使用 Entra 令牌凭据创建与 IoT 中心的服务连接。
- IoTHubJobManager
- DigitalTwinClient
- IoTHubHttpRuntimeManager
- IoTHubConfigurationManager
from_token_credential
需要两个参数:
- Azure 服务 URL - Azure 服务 URL 应采用
{Your Entra domain URL}.azure-devices.net
格式(不包括https://
前缀)。 例如,MyAzureDomain.azure-devices.net
。 - Azure 凭据令牌
在此示例中,使用 DefaultAzureCredential
获取 Azure 凭据。 然后将 Azure 服务 URL 和凭据提供给 IoTHubRegistryManager.from_token_credential
,以便与 IoT 中心创建连接。
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)
有关 Microsoft Entra 服务身份验证的工作示例,请参阅适用于 Python 的 Microsoft 身份验证库 (MSAL)。
可使用 update_module_twin 从后端应用程序更新所需属性。
检索和更新模块标识孪生所需属性:
- 调用 get_module_twin 以获取模块标识孪生的当前版本。
- 使用 Twin 类,添加 JSON 格式的所需属性。
- 调用
update_module_twin
,将修补程序应用于设备孪生。 还可使用 replace_module_twin 替换模块标识孪生的所需属性和标记。
此示例将 telemetryInterval
所需属性更新为 122
。
try:
module_twin = iothub_registry_manager.get_module_twin(DEVICE_ID, MODULE_ID)
print ( "" )
print ( "Module identity twin properties before update:" )
print ( "{0}".format(module_twin.properties) )
# Update twin
twin_patch = Twin()
twin_patch.properties = TwinProperties(desired={"telemetryInterval": 122})
updated_module_twin = iothub_registry_manager.update_module_twin(
DEVICE_ID, MODULE_ID, twin_patch, module_twin.etag
)
print ( "" )
print ( "Module identity twin properties after update :" )
print ( "{0}".format(updated_module_twin.properties) )
except Exception as ex:
print ( "Unexpected error {0}".format(ex) )
except KeyboardInterrupt:
print ( "IoTHubRegistryManager sample stopped" )
适用于 Python 的 Azure IoT SDK 提供了处理设备设备标识模块孪生任务的服务应用的有效示例。 有关详细信息,请参阅测试 IoT 中心注册表管理器。
- 需要 Node.js 10.0.x 版或更高版本
本文介绍如何使用适用于 Node.js 的 Azure IoT SDK 为设备标识孪生创建设备和后端服务应用程序代码。
本部分介绍如何使用适用于 Node.js 的 Azure IoT SDK 中的 azure-iot-device 包来创建一个设备应用程序,以进行以下操作:
- 检索模块标识孪生并检查报告属性
- 更新模块标识报告孪生属性
- 接收模块标识孪生所需属性更改的通知
重要
本文包括使用共享访问签名(也称为对称密钥身份验证)连接设备的步骤。 此身份验证方法便于测试和评估,但使用 X.509 证书对设备进行身份验证是一种更安全的方法。
运行以下命令,在开发计算机上安装“azure-iot-device”设备 SDK:
npm install azure-iot-device --save
azure-iot-device 包包含与 IoT 设备交互的对象。 Twin 类包括特定于孪生的对象。 本部分介绍用于读写设备模块标识孪生数据的 Client
类代码。
Client
对象支持以下属性:
Amqp
Http
- 使用Http
时,Client
实例不会频繁地检查来自 IoT 中心的消息(至少每 25 分钟一次)。Mqtt
MqttWs
AmqpWs
在开发计算机上安装所需的传输协议。
例如,以下命令安装 Amqp
协议:
npm install azure-iot-device-amqp --save
有关 MQTT、AMQP 和 HTTPS 支持之间的差异的详细信息,请参阅云到设备通信指南和选择设备通信协议。
使用已安装的包创建 Client
对象。
例如:
const Client = require('azure-iot-device').Client;
使用已安装的传输包创建 Protocol
对象。
此示例分配 AMQP 协议:
const Protocol = require('azure-iot-device-amqp').Amqp;
调用 fromConnectionString 以提供设备连接参数:
- connStr - IoT 中心标识模块连接字符串。
- transportCtor - 传输协议。
此示例使用 Amqp
传输协议:
const deviceConnectionString = "{IoT hub identity module connection string}"
const Protocol = require('azure-iot-device-mqtt').Amqp;
let client = Client.fromConnectionString(deviceConnectionString, Protocol);
使用 open 方法打开 IoT 设备和 IoT 中心之间的连接。
例如:
client.open(function(err) {
if (err) {
console.error('error connecting to hub: ' + err);
process.exit(1);
}
})
调用 getTwin,将当前模块标识孪生信息检索到 Twin 对象中。
然后,设备代码可以访问模块标识孪生属性。
例如:
// Retrieve the current module identity twin
client.getTwin(function(err, twin))
if (err)
console.error('could not get twin');
// Display the current properties
console.log('twin contents:');
console.log(twin.properties);
使用 update 以更新设备报告属性。 纳入 JSON 格式的修补程序作为该方法的第一个参数,以及函数执行状态回调方法作为该方法的第二个参数。
在此示例中,JSON 格式的模块标识孪生修补程序存储在 patch
变量中。 该修补程序包含一个 cellular
的模块标识孪生 connectivity
更新值。 该修补程序和错误处理程序被传递到 update
方法。 如果出现错误,随即会显示控制台错误消息。
// Create a patch to send to IoT Hub
var patch = {
updateTime: new Date().toString(),
firmwareVersion:'1.2.1',
weather:{
temperature: 72,
humidity: 17
}
};
// Apply the patch
twin.properties.reported.update(patch, function(err)
{
if (err)
{
console.error('could not update twin');
}
else
{
console.log('twin state reported');
process.exit();
}
});
通过将回调处理程序方法名称传递到 twin.on,创建更改所需属性时执行的模块标识孪生所需属性更新事件侦听器。
所需属性事件侦听器可采用以下形式:
- 使用单个事件处理程序接收所有修补程序
- 在属性分组下的任何内容发生更改的情况下接收事件
- 接收单个属性更改的事件
可创建侦听器来接收任何所需属性更改。
此示例代码输出从服务接收的任何属性。
twin.on('properties.desired', function (delta) {
console.log('new desired properties received:');
console.log(JSON.stringify(delta));
});
如果属性分组下的任何内容发生更改,可创建一个侦听器来接收事件。
例如:
minTemperature
和maxTemperature
属性位于名为properties.desired.climate changes
的属性分组下。后端服务应用程序应用此修补程序以更新
minTemperature
和maxTemperature
所需属性:const twinPatch1 = { properties: { desired: { climate: { minTemperature: 68, maxTemperature: 76, }, }, }, };
此代码设置一个所需属性更改事件侦听器,该侦听器会触发
properties.desired.climate
属性分组中的任何更改。 如果此组中存在一个所需属性更改,则向控制台显示最小和最大温度更改消息:twin.on('properties.desired.climate', function (delta) { if (delta.minTemperature || delta.maxTemperature) { console.log('updating desired temp:'); console.log('min temp = ' + twin.properties.desired.climate.minTemperature); console.log('max temp = ' + twin.properties.desired.climate.maxTemperature); } });
可为单个属性更改设置侦听器。 在此示例中,仅当 fanOn
布尔值是修补程序的一部分时,才会执行此事件的代码。 每当服务更新所需 fanOn
状态时,该代码都会输出新的相应状态。
后端应用程序应用此所需属性修补程序:
const twinPatch2 = { properties: { desired: { climate: { hvac: { systemControl: { fanOn: true, }, }, }, }, }, };
仅当
fanOn
属性发生更改时,侦听器才会触发:twin.on('properties.desired.climate.hvac.systemControl', function (fanOn) { console.log('setting fan state to ' + fanOn); });
此示例封装本部分的原则,包括多级回调函数嵌套。
var Client = require('azure-iot-device').Client;
var Protocol = require('azure-iot-device-amqp').Amqp;
// Copy/paste your module connection string here.
var connectionString = 'HostName=xxx.azure-devices.net;DeviceId=myFirstDevice2;ModuleId=myFirstModule2;SharedAccessKey=xxxxxxxxxxxxxxxxxx';
// Create a client using the Amqp protocol.
var client = Client.fromConnectionString(connectionString, Protocol);
client.on('error', function (err) {
console.error(err.message);
});
// connect to the hub
client.open(function(err) {
if (err) {
console.error('error connecting to hub: ' + err);
process.exit(1);
}
console.log('client opened');
// Create device Twin
client.getTwin(function(err, twin) {
if (err) {
console.error('error getting twin: ' + err);
process.exit(1);
}
// Output the current properties
console.log('twin contents:');
console.log(twin.properties);
// Add a handler for desired property changes
twin.on('properties.desired', function(delta) {
console.log('new desired properties received:');
console.log(JSON.stringify(delta));
});
// create a patch to send to the hub
var patch = {
updateTime: new Date().toString(),
firmwareVersion:'1.2.1',
weather:{
temperature: 75,
humidity: 20
}
};
// send the patch
twin.properties.reported.update(patch, function(err) {
if (err) throw err;
console.log('twin state reported');
});
});
});
适用于 Node.js 的 Azure IoT SDK 提供了处理模块标识孪生任务的设备应用中的有效示例。 有关详细信息,请参阅:
本部分介绍如何创建后端应用程序来检索模块标识孪生并更新所需属性。
运行以下命令,在开发计算机上安装“azure-iothub”:
npm install azure-iothub --save
Registry 类公开从后端应用程序与模块标识孪生进行交互所需的所有方法。
let Registry = require('azure-iothub').Registry;
可使用以下方法将后端服务连接到 IoT 中心:
- 共享访问策略
- Microsoft Entra
重要
本文介绍使用共享访问签名连接到服务的步骤。 虽然可使用此身份验证方法进行测试和评估,但使用 Microsoft Entra ID 或托管标识对设备进行身份验证是一种更安全的方法。
使用 fromConnectionString 连接到 IoT 中心。
本节中使用的 update
方法需要“服务连接”共享访问策略权限才能将所需属性添加到模块。 作为 fromConnectionString
的参数,提供包含“服务连接”权限的共享访问策略连接字符串。 有关共享访问策略的详细信息,请参阅使用共享访问签名控制对 IoT 中心的访问。
let connectionString = '{IoT hub shared access policy connection string}';
let registry = Registry.fromConnectionString(serviceConnectionString);
使用 Microsoft Entra 的后端应用必须在连接到 IoT 中心之前成功完成身份验证并获取安全令牌凭据。 此令牌将传递给 IoT 中心连接方法。 有关为 IoT 中心设置和使用 Microsoft Entra 的一般信息,请参阅使用 Microsoft Entra ID 控制对 IoT 中心的访问。
有关 Node.js SDK 身份验证的概述,请参阅:
必须设置一个针对首选身份验证凭据进行配置的 Microsoft Entra 应用。 该应用包含由后端应用程序用来进行身份验证的参数,例如客户端机密。 可用的应用身份验证配置如下:
- 客户端机密
- 证书
- 联合标识凭据
根据正在执行的操作,Microsoft Entra 应用可能需要特定的角色权限。 例如,需要 IoT 中心孪生参与者角色才能启用对 IoT 中心设备和模块孪生的读写访问权限。 有关详细信息,请参阅使用 Azure RBAC 角色分配管理对 IoT 中心的访问。
有关设置 Microsoft Entra 应用的详细信息,请参阅快速入门:将应用程序注册到 Microsoft 标识平台。
使用 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 标识示例。
可创建一个包含模块标识孪生的标记和所需属性更新的修补程序。
更新模块标识孪生体:
调用 getModuleTwin 以检索设备 Twin 对象。
设置修补程序的格式,该修补程序包含模块标识孪生更新。 该修补程序采用 JSON 格式,如 Twin 类中所述。 后端服务修补程序包含所需属性更新。 有关修补程序格式的详细信息,请参阅标记和属性格式。
调用 update 以使用修补程序更新模块标识孪生。
在此示例中,检索 myDeviceId
和 myModuleId
的模块标识孪生。 然后将修补程序应用于包含 climate
信息的孪生。
// Insert your device ID and moduleId here.
var deviceId = 'myFirstDevice2';
var moduleId = 'myFirstModule2';
// Retrieve the current module identity twin
registry.getModuleTwin(deviceId, moduleId, function (err, twin) {
console.log('getModuleTwin returned ' + (err ? err : 'success'));
if (err) {
console.log(err);
} else {
console.log('success');
console.log('Current twin:' + JSON.stringify(twin))
// Format a desired property patch
const twinPatch1 = {
properties: {
desired: {
climate: { minTemperature: 69, maxTemperature: 77, },
},
},
};
// Send the desired property patch to IoT Hub
twin.update(twinPatch1, function(err) {
if (err) throw err;
console.log('twin state reported');
});
}
});
适用于 Node.js 的 Azure IoT SDK 提供了处理模块标识孪生任务的服务应用中的有效示例。 有关详细信息,请参阅: