你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

设备孪生入门

使用 Azure IoT 中心设备 SDK 和服务 SDK 开发处理常见设备孪生任务的应用程序。 设备孪生是存储设备状态信息(包括元数据、配置和条件)的 JSON 文档。 IoT 中心为连接到它的每台设备保留一个设备孪生。

可使用设备孪生进行以下操作:

  • 存储来自解决方案后端的设备元数据
  • 通过设备应用报告当前状态信息,例如可用功能和条件(例如,使用的连接方法)
  • 同步设备应用和后端应用之间长时间运行的工作流(例如固件和配置更新)的状态
  • 查询设备的元数据、配置或状态

有关设备孪生的详细信息(包括何时使用设备孪生),请参阅在 IoT 中心内了解并使用设备孪生

注意

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

本文介绍如何开发两种类型的应用程序:

  • 设备应用可处理更新所需属性的请求,并通过对报告属性的更改做出响应。
  • 服务应用可根据设备孪生值更新设备孪生标记、设置新的所需属性并查询设备。

注意

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

先决条件

  • IoT 中心。 某些 SDK 调用需要 IoT 中心主连接字符串,因此请记下连接字符串。

  • 已注册的设备。 某些 SDK 调用需要设备主连接字符串,因此请记下连接字符串。

  • IoT 中心服务连接字符串

    在本文中,你将创建一项后端服务,该服务将所需的属性添加到设备孪生,然后查询标识注册表,从而查找具有已相应更新的报告属性的所有设备。 服务需要“服务连接”权限才能修改设备孪生的所需属性,并且需要“注册表读取”权限才能查询标识注册表。 没有仅包含这两个权限的默认共享访问策略,因此需要创建一个。

    若要创建授予“服务连接”和“注册表读取”权限的共享访问策略并获取此策略的连接字符串,请执行以下步骤:

    1. Azure 门户中,选择“资源组”。 选择中心所在的资源组,然后从资源列表中选择中心。

    2. 在中心的左侧窗格上,选择“共享访问策略”。

    3. 在策略列表上方的顶部菜单中,选择“添加共享策略访问策略”。

    4. 在右侧的“添加共享访问策略”窗格中,为策略输入一个描述性名称,例如“serviceAndRegistryRead”。 在“权限”下,选择“注册表读取”和“服务连接”,然后选择“添加”。

    5. 从策略列表中选择新策略。

    6. 选择“主连接字符串”的复制图标并保存值。

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

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

  • 语言 SDK 要求:

    • .NET SDK - 需要 Visual Studio
    • Python SDK - 建议使用 Python 3.7 版或更高版本。 请确保根据安装程序的要求,使用 32 位或 64 位安装。 在安装过程中出现提示时,请确保将 Python 添加到特定于平台的环境变量中。
    • Java - 需要 Java SE 开发工具包 8。 请确保在“长期支持”下选择“Java 8”以导航到 JDK 8 的下载。
    • Node.js - 需要 Node.js 10.0.x 版或更高版本

概述

本文介绍如何使用适用于 .NET 的 Azure IoT SDK 为设备孪生创建设备和后端服务应用程序代码。

创建设备应用程序

设备应用程序可读写孪生报告属性,并得到后端应用程序或 IoT 中心设置的所需孪生属性更改的通知。

本部分介绍如何使用设备应用程序代码进行以下操作:

  • 检索设备孪生并检查报告属性
  • 更新报告的设备孪生属性
  • 创建所需属性更新回调处理程序

添加设备 NuGet 包

使用 C# 编写的设备客户端应用程序需要 NuGet 包“Microsoft.Azure.Devices.Client”

连接到设备

DeviceClient 类公开从设备与设备孪生进行交互所需的所有方法

使用 CreateFromConnectionString 方法以及设备连接字符串和连接传输协议连接到设备。

CreateFromConnectionString TransportType 传输协议参数支持以下传输协议:

  • Mqtt
  • Mqtt_WebSocket_Only
  • Mqtt_Tcp_Only
  • Amqp
  • Amqp_WebSocket_Only
  • Amqp_Tcp_Only

对于设备孪生更新,不支持 Http1 协议。

此示例使用 Mqtt 传输协议连接到设备。

using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;
using Newtonsoft.Json;

static string DeviceConnectionString = "{IoT hub device connection string}";
static _deviceClient = null;
_deviceClient = DeviceClient.CreateFromConnectionString(DeviceConnectionString, 
   TransportType.Mqtt);

检索设备孪生并检查属性

调用 GetTwinAsync 以检索当前设备孪生属性。 有许多孪生对象属性可用于访问 Twin JSON 数据的特定区域,包括 PropertiesStatusTagsVersion

此示例检索设备孪生属性,并输出 JSON 格式的孪生值。

Console.WriteLine("Retrieving twin...");
Twin twin = await _deviceClient.GetTwinAsync();
Console.WriteLine("\tInitial twin value received:");
Console.WriteLine($"\t{twin.ToJson()}");

更新报告的设备孪生属性

更新孪生报告属性:

  1. 为报告属性更新创建 TwinCollection 对象
  2. 更新 TwinCollection 对象中的一个或多个报告属性
  3. 使用 UpdateReportedPropertiesAsync 将报告属性更改推送到 IoT 中心服务

例如:

try
{
Console.WriteLine("Sending sample start time as reported property");
TwinCollection reportedProperties = new TwinCollection();
reportedProperties["DateTimeLastAppLaunch"] = DateTime.UtcNow;
await _deviceClient.UpdateReportedPropertiesAsync(reportedProperties);
}
catch (Exception ex)
{
   Console.WriteLine();
   Console.WriteLine("Error in sample: {0}", ex.Message);
}

创建所需属性更新回调处理程序

通过将回调处理程序方法名称传递到 SetDesiredPropertyUpdateCallbackAsync,创建在设备孪生中更改所需属性时执行的所需属性更新回调处理程序。

例如,此调用设置系统,以在更改所需属性时通知名为 OnDesiredPropertyChangedAsync 的方法。

await _deviceClient.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 _deviceClient.UpdateReportedPropertiesAsync(reportedProperties);
}

SDK 设备示例

适用于 .NET 的 Azure IoT SDK 提供了处理设备孪生任务的设备应用的工作示例。 有关详细信息,请参阅 TwinSample

创建后端应用程序

后端应用程序:

  • 通过 IoT 中心连接到设备
  • 可读取设备报告属性和所需属性、写入设备所需属性并运行设备查询

RegistryManager 类公开创建后端应用程序以从服务与设备孪生进行交互所需的所有方法。

本部分介绍如何创建后端应用程序代码进行以下操作:

  • 读取和更新设备孪生字段
  • 创建设备孪生查询

添加服务 NuGet 包

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

连接到 IoT 中心

使用 CreateFromConnectionString 将后端应用程序连接到设备。 作为一个参数,提供在“先决条件”部分创建的 IoT 中心服务连接字符串

using Microsoft.Azure.Devices;
static RegistryManager registryManager;
static string connectionString = "{IoT hub service connection string}";
registryManager = RegistryManager.CreateFromConnectionString(connectionString);

读取和更新设备孪生字段

可通过调用 GetTwinAsync,将当前设备孪生字段检索到一个孪生对象中。

Twin 类包括与设备孪生的每个部分对应的属性。 使用 Twin 类属性查看和更新设备孪生字段。 在使用 UpdateTwinAsync 将更新写入设备之前,可使用 Twin 对象属性更新多个孪生字段。

进行孪生字段更新后,调用 UpdateTwinAsyncTwin 对象字段更新写回设备。 将 trycatch 逻辑与错误处理程序结合使用,从 UpdateTwinAsync 捕获格式不正确的修补程序错误。

读取和更新设备孪生标记

使用设备孪生标记属性读写设备标记信息。

使用孪生对象更新标记

此示例创建一个 location 标记修补程序,使用 Tags 属性将其分配给 Twin 对象,然后使用 UpdateTwinAsync 应用该修补程序。

// Retrieve the device twin
var twin = await registryManager.GetTwinAsync("myDeviceId");

// Create the tag patch
var tagspatch =
   @"{
   tags: {
         location: {
            region: 'US',
            plant: 'Redmond43'
         }
   }
}";

// Assign the patch to the Twin object
twin.Tags["location"] = tagspatch;

// Apply the patch to update the device twin tags section
try
{
   await registryManager.UpdateTwinAsync(twin.DeviceId, patch, twin.ETag);
}
catch (Exception e)
{
   console.WriteLine("Twin update failed.", e.Message);
}
使用 JSON 字符串更新标记

可创建并应用 JSON 格式的设备孪生信息更新修补程序。 如果修补程序格式正确,IoT 中心会分析并应用它。

此示例调用 GetTwinAsync 将当前设备孪生字段检索到一个 Twin 对象中,创建一个包含区域和工厂位置信息的 JSON 格式的 tag 修补程序,然后调用 UpdateTwinAsync 以应用修补程序来更新设备孪生。 如果 UpdateTwinAsync 失败,随即会显示一条错误消息。

// Retrieve the device twin
var twin = await registryManager.GetTwinAsync("myDeviceId");

// Create the JSON tags patch
var patch =
   @"{
      tags: {
            location: {
               region: 'US',
               plant: 'Redmond43'
            }
      }
   }";
// Apply the patch to update the device twin tags
try
{
   await registryManager.UpdateTwinAsync(twin.DeviceId, patch, twin.ETag);
}
catch (Exception e)
{
   console.WriteLine("Twin update failed.", e.Message);
}

查看和更新孪生所需属性

使用设备孪生 TwinProperties.Desired 属性读写设备所需属性信息。 使用 JSON 格式的修补程序更新孪生 Desired 属性。

此示例调用 GetTwinAsync 将当前设备孪生字段检索到一个 Twin 对象中,更新孪生 speed 所需属性,然后调用 UpdateTwinAsync 以应用 Twin 对象来更新设备孪生。

// Retrieve the device twin
var twin = await registryManager.GetTwinAsync("myDeviceId");

twin.Properties.Desired["speed"] = "type: '5G'";
await registryManager.UpdateTwinAsync(twin.DeviceId, twin, twin.ETag);

其他孪生更新方法

还可使用以下 SDK 方法应用孪生更新:

创建设备孪生查询

本部分演示两个设备孪生查询。 设备孪生查询是类似 SQL 的查询,可返回设备孪生的结果集。

若要创建设备孪生查询,请调用 CreateQuery 以提交一个孪生 SQL 查询并获取一个 IQuery 接口。 可选择使用第二个参数来调用 CreateQuery,以指定每页的最大项数。

接着,根据需要多次调用 GetNextAsTwinAsyncGetNextAsJsonAsync 方法,以检索所有孪生结果。

IQuery 接口包括一个 HasMoreResults 布尔属性,可用于检查是否有更多的孪生结果要提取。

此示例查询仅选择位于 Redmond43 工厂中的设备的设备孪生

var query = registryManager.CreateQuery(
"SELECT * FROM devices WHERE tags.location.plant = 'Redmond43'", 100);
var twinsInRedmond43 = await query.GetNextAsTwinAsync();
Console.WriteLine("Devices in Redmond43: {0}", 
string.Join(", ", twinsInRedmond43.Select(t => t.DeviceId)));

此示例查询优化了第一个查询,以仅选择也通过手机网络连接的设备。

query = registryManager.CreateQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43' AND properties.reported.connectivity.type = 'cellular'", 100);
var twinsInRedmond43UsingCellular = await query.GetNextAsTwinAsync();
Console.WriteLine("Devices in Redmond43 using cellular network: {0}", 
string.Join(", ", twinsInRedmond43UsingCellular.Select(t => t.DeviceId)));

SDK 服务示例

适用于 .NET 的 Azure IoT SDK 提供了处理设备孪生任务的服务应用的工作示例。 有关详细信息,请参阅注册表管理器示例

概述

本文介绍如何使用适用于 Java 的 Azure IoT SDK 为设备孪生创建设备和后端服务应用程序代码。

创建设备应用程序

设备应用程序可读写孪生报告属性,并得到后端应用程序或 IoT 中心设置的所需孪生属性更改的通知。

本部分介绍如何创建设备应用程序代码进行以下操作:

  • 检索和查看设备孪生
  • 更新报告的设备孪生属性
  • 订阅所需属性更改

DeviceClient 类公开从设备与设备孪生进行交互所需的所有方法

设备导入语句

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

import com.microsoft.azure.sdk.iot.device.*;
import com.microsoft.azure.sdk.iot.device.DeviceTwin.*;

连接到设备

连接到设备:

  1. 使用 IotHubClientProtocol 选择一个传输协议。 例如:

    IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
    
  2. 使用 DeviceClient 构造函数添加设备主连接字符串和协议。

    String connString = "{IoT hub device connection string}";
    DeviceClient client = new DeviceClient(connString, protocol);
    
  3. 使用 open 将设备连接到 IoT 中心。 如果客户端已打开,该方法将不执行任何操作。

    client.open(true);
    

检索和查看设备孪生

打开客户端连接后,调用 getTwin 将当前孪生属性检索到 Twin 对象中。

例如:

private static Twin twin;
System.out.println("Getting current twin");
twin = client.getTwin();
System.out.println("Received current twin:");
System.out.println(twin);

更新设备孪生报告属性

检索当前孪生后,可开始进行报告属性更新。 只要你拥有正确的报告属性版本,你也可在不获取当前孪生的情况下进行报告属性更新。 如果你发送报告属性并收到“先决条件失败”错误,则报告属性版本已过期。 在这种情况下,再次调用 getTwin 以获取最新版本。

更新报告属性:

  1. 调用 getReportedProperties,将孪生报告属性提取到一个 TwinCollection 对象中。

  2. 使用 put 更新 TwinCollection 对象中的报告属性。 为每个报告属性更新调用 put

  3. 使用 updateReportedProperties 应用使用 put 方法更新的报告属性组。

例如:

TwinCollection reportedProperties = twin.getReportedProperties();

int newTemperature = new Random().nextInt(80);
reportedProperties.put("HomeTemp(F)", newTemperature);
System.out.println("Updating reported property \"HomeTemp(F)\" to value " + newTemperature);

ReportedPropertiesUpdateResponse response = client.updateReportedProperties(reportedProperties);
System.out.println("Successfully set property \"HomeTemp(F)\" to value " + newTemperature);

订阅所需属性更改

调用 subscribeToDesiredProperties 以订阅所需属性更改。 每次更新所需属性时,此客户端都会收到一个带有 Twin 对象的回调。 该回调包含完整的所需属性集,或者仅包含更新的所需属性,具体取决于所需属性的更改方式。

此示例订阅所需属性更改。 任何所需属性更改都传递给名为 DesiredPropertiesUpdatedHandler 的处理程序。

client.subscribeToDesiredProperties(new DesiredPropertiesUpdatedHandler(), null);

在此示例中,DesiredPropertiesUpdatedHandler 所需属性更改回调处理程序调用 getDesiredProperties 检索属性更改,然后输出更新的孪生属性。

  private static class DesiredPropertiesUpdatedHandler implements DesiredPropertiesCallback
  {
      @Override
      public void onDesiredPropertiesUpdated(Twin desiredPropertyUpdateTwin, Object context)
      {
          if (twin == null)
          {
              // No need to care about this update because these properties will be present in the twin retrieved by getTwin.
              System.out.println("Received desired properties update before getting current twin. Ignoring this update.");
              return;
          }

          // desiredPropertyUpdateTwin.getDesiredProperties() contains all the newly updated desired properties as well as the new version of the desired properties
          twin.getDesiredProperties().putAll(desiredPropertyUpdateTwin.getDesiredProperties());
          twin.getDesiredProperties().setVersion(desiredPropertyUpdateTwin.getDesiredProperties().getVersion());
          System.out.println("Received desired property update. Current twin:");
          System.out.println(twin);
      }
  }

SDK 设备示例

适用于 Java 的 Azure IoT SDK 包含一个用于测试本文中所述的设备应用概念的工作示例。 有关详细信息,请参阅设备孪生示例

创建后端应用程序

本部分介绍如何创建执行以下操作的后端应用程序:

  • 更新设备孪生标记
  • 使用针对标记和属性的筛选器来查询设备

ServiceClient DeviceTwin 类包含服务可用来访问设备孪生的方法。

服务导入语句

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

import com.microsoft.azure.sdk.iot.service.devicetwin.*;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;

连接到 IoT 中心服务客户端

连接到 IoT 中心以查看和更新设备孪生信息:

  1. 创建 DeviceTwinClientOptions 对象。 设置应用程序所需的任何选项。 这些选项被传递给 DeviceTwin 对象。
  2. 使用 DeviceTwin 构造函数创建与 IoT 中心的连接。 DeviceTwin 对象处理与 IoT 中心之间的通信。 作为参数,提供在“先决条件”部分创建的 IoT 中心服务连接字符串和 DeviceTwinClientOptions 对象
  3. DeviceTwinDevice 对象使用设备孪生的属性和标记来表示该设备孪生。

例如:

public static final String iotHubConnectionString = "{IoT hub service connection string}";
public static final String deviceId = "myDeviceId";
public static final String region = "US";
public static final String plant = "Redmond43";

// Get the DeviceTwin and DeviceTwinDevice objects
DeviceTwinClientOptions twinOptions = new DeviceTwinClientOptions();
DeviceTwin twinClient = new DeviceTwin(iotHubConnectionString,twinOptions);
DeviceTwinDevice device = new DeviceTwinDevice(deviceId);

更新设备孪生字段

更新设备孪生字段:

  1. 使用 getTwin 检索当前设备孪生字段

    此示例检索并输出设备孪生字段:

    // Get the device twin from IoT Hub
    System.out.println("Device twin before update:");
    twinClient.getTwin(device);
    System.out.println(device);
    
  2. 使用 HashSet 对象,对一组孪生标记对进行 add 操作

  3. 使用 setTags 将一组标记对从 tags 对象添加到 DeviceTwinDevice 对象

  4. 使用 updateTwin 在 IoT 中心更新孪生

    此示例更新一个设备孪生的区域和工厂设备孪生标记:

    // Update device twin tags if they are different
    // from the existing values
    String currentTags = device.tagsToString();
    if ((!currentTags.contains("region=" + region) && !currentTags.contains("plant=" + plant))) {
    
    // Create the tags and attach them to the DeviceTwinDevice object
    Set<Pair> tags = new HashSet<Pair>();
    tags.add(new Pair("region", region));
    tags.add(new Pair("plant", plant));
    device.setTags(tags);
    
    // Update the device twin in IoT Hub
    System.out.println("Updating device twin");
    twinClient.updateTwin(device);
    }
    
    // Retrieve and display the device twin with the tag values from IoT Hub
    System.out.println("Device twin after update:");
    twinClient.getTwin(device);
    System.out.println(device);
    

创建设备孪生查询

本部分演示两个设备孪生查询。 设备孪生查询是类似 SQL 的查询,可返回设备孪生的结果集。

Query 类包含可用于为孪生、作业、设备作业或原始数据创建对 IoT 中心的 SQL 样式查询的方法。

创建设备查询:

  1. 使用 createSqlQuery 生成孪生 SQL 查询

  2. 使用 queryTwin 执行查询

  3. 使用 hasNextDeviceTwin 检查结果集中是否有另一个设备孪生

  4. 使用 getNextDeviceTwin 从结果集中检索下一个设备孪生

以下示例查询最多返回 100 台设备。

此示例查询仅选择位于 Redmond43 工厂中的设备的设备孪生

// Query the device twins in IoT Hub
System.out.println("Devices in Redmond:");

// Construct the query
SqlQuery sqlQuery = SqlQuery.createSqlQuery("*", SqlQuery.FromType.DEVICES, "tags.plant='Redmond43'", null);

// Run the query, returning a maximum of 100 devices
Query twinQuery = twinClient.queryTwin(sqlQuery.getQuery(), 100);
while (twinClient.hasNextDeviceTwin(twinQuery)) {
  DeviceTwinDevice d = twinClient.getNextDeviceTwin(twinQuery);
  System.out.println(d.getDeviceId());
}

此示例查询优化了第一个查询,以仅选择也通过手机网络连接的设备。

System.out.println("Devices in Redmond using a cellular network:");

// Construct the query
sqlQuery = SqlQuery.createSqlQuery("*", SqlQuery.FromType.DEVICES, "tags.plant='Redmond43' AND properties.reported.connectivityType = 'cellular'", null);

// Run the query, returning a maximum of 100 devices
twinQuery = twinClient.queryTwin(sqlQuery.getQuery(), 3);
while (twinClient.hasNextDeviceTwin(twinQuery)) {
  DeviceTwinDevice d = twinClient.getNextDeviceTwin(twinQuery);
  System.out.println(d.getDeviceId());
}

SDK 服务示例

适用于 Java 的 Azure IoT SDK 提供了处理设备孪生任务的服务应用的工作示例。 有关详细信息,请参阅设备孪生示例

概述

本文介绍如何使用适用于 Python 的 Azure IoT SDK 为设备孪生创建设备和后端服务应用程序代码。

创建设备应用程序

设备应用程序可读写孪生报告属性,并得到后端应用程序或 IoT 中心设置的所需孪生属性更改的通知。

IoTHubDeviceClient 类包含可用于处理设备孪生的方法。

本部分介绍如何创建执行以下操作的设备应用程序代码:

  • 检索设备孪生并检查报告属性
  • 修补报告的设备孪生属性

连接到设备

本部分介绍如何使用包含共享访问密钥的设备主密钥将应用程序连接到设备。

将应用程序连接到设备:

  1. 调用 create_from_connection_string 以添加设备连接字符串
  2. 调用 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 = "{IOT hub device connection string}"
device_client = IoTHubDeviceClient.create_from_connection_string(conn_str)

# connect the application to the device
await device_client.connect()

检索设备孪生并检查报告属性

可检索和检查设备孪生信息,包括标记和属性。 检索的设备孪生信息与可在 Azure 门户中查看的设备的设备孪生 JSON 格式的数据相匹配。

调用 get_twin,从 Azure IoT 中心服务获取设备孪生。 孪生信息放置在可输出或检查的变量中。

此示例检索设备孪生,并使用 print 命令以 JSON 格式查看设备孪生。

# get the twin
twin = await device_client.get_twin()
print("Twin document:")
print("{}".format(twin))

修补报告的设备孪生属性

可应用修补程序以更新 JSON 格式的设备报告属性。

应用修补程序以更新报告属性:

  1. 将报告属性 JSON 修补程序分配给变量。
  2. 调用 patch_twin_reported_properties,将 JSON 修补程序应用于报告属性。 这是一个同步调用,意味着在修补程序被发送到服务并得到确认之前,此函数不会返回。

如果 patch_twin_reported_properties 返回一个错误,此函数会引发相应的错误。

# 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)

你还可调用这些方法来更新设备孪生:

  • 调用 replace_twin 以替换设备孪生标记和所需属性。
  • 调用 update_twin 以更新设备孪生标记和所需属性。

传入的所需属性修补程序处理程序

调用 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)

SDK 设备示例

适用于 Python 的 Azure IoT SDK 包括以下示例:

创建后端应用程序

后端应用程序通过 IoT 中心连接到设备,并可读取设备报告属性和所需属性、写入设备所需属性并运行设备查询。

本部分介绍如何创建后端应用程序进行以下操作:

  • 更新孪生标记和所需属性
  • 使用针对标记和属性的筛选器来查询设备

IoTHubRegistryManager 类公开创建后端应用程序以从服务与设备孪生进行交互所需的所有方法。

连接到 IoT 中心

使用 from_connection_string 连接到 IoT 中心。 作为一个参数,提供在“先决条件”部分创建的 IoT 中心服务连接字符串

例如:

import sys
from time import sleep
from azure.iot.hub import IoTHubRegistryManager
from azure.iot.hub.models import Twin, TwinProperties, QuerySpecification, QueryResult

# Connect to IoT hub
IOTHUB_CONNECTION_STRING = "{IoT hub service connection string}"
iothub_registry_manager = IoTHubRegistryManager.from_connection_string(IOTHUB_CONNECTION_STRING)

更新孪生标记和所需属性

可使用 update_twin 从后端应用程序同时更新设备孪生标记和所需属性。

  1. 调用 get_twin 以获取设备孪生的当前版本
  2. 使用 Twin 类,以 JSON 格式添加标记和属性。
  3. 调用 update_twin,将修补程序应用于设备孪生。 还可使用 replace_twin 替换设备孪生的所需属性和标记。

此示例更新 regionplant 标记信息,并将 power_level 所需属性设置为 1

new_tags = {
        'location' : {
            'region' : 'US',
            'plant' : 'Redmond43'
        }
    }

DEVICE_ID = "[Device Id]"
twin = iothub_registry_manager.get_twin(DEVICE_ID)
twin_patch = Twin(tags=new_tags, properties= TwinProperties(desired={'power_level' : 1}))
twin = iothub_registry_manager.update_twin(DEVICE_ID, twin_patch, twin.etag)

创建设备孪生查询

可使用设备孪生查询来查询设备孪生信息。 设备孪生查询是类似 SQL 的查询,可返回设备孪生的结果集。

使用设备孪生查询:

  1. 使用 QuerySpecification 对象以定义类似 SQL 的查询请求。

  2. 使用 query_iot_hub 查询 IoTHub 并使用类似 SQL 的查询规范检索设备孪生信息。

此示例运行两个查询。 第一个查询仅选择位于 Redmond43 工厂中的设备的设备孪生,第二个查询将查询细化为仅选择还要通过手机网络连接的设备。 每个查询后都会输出结果。

query_spec = QuerySpecification(query="SELECT * FROM devices WHERE tags.location.plant = 'Redmond43'")
query_result = iothub_registry_manager.query_iot_hub(query_spec, None, 100)
print("Devices in Redmond43 plant: {}".format(', '.join([twin.device_id for twin in query_result.items])))

print()

query_spec = QuerySpecification(query="SELECT * FROM devices WHERE tags.location.plant = 'Redmond43' AND properties.reported.connectivity = 'cellular'")
query_result = iothub_registry_manager.query_iot_hub(query_spec, None, 100)
print("Devices in Redmond43 plant using cellular network: {}".format(', '.join([twin.device_id for twin in query_result.items])))

print()

SDK 服务示例

适用于 Python 的 Azure IoT SDK 提供了处理设备孪生任务的服务应用的工作示例。 有关详细信息,请参阅注册表管理器查询示例

概述

本文介绍如何使用适用于 Node.js 的 Azure IoT SDK 为设备孪生创建设备和后端服务应用程序代码。

创建设备应用程序

设备应用程序可读写孪生报告属性,并得到后端应用程序或 IoT 中心设置的所需孪生属性更改的通知。

本部分介绍如何使用适用于 Node.js 的 Azure IoT SDK 中的 azure-iot-device 包来创建一个设备应用程序,以进行以下操作:

  • 检索设备孪生并检查报告属性
  • 更新报告的设备孪生属性
  • 接收所需属性更改的通知

安装 SDK 包

运行以下命令,在开发计算机上安装“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

在开发计算机上安装所需的传输协议。

例如,以下命令安装 Mqtt 协议:

npm install azure-iot-device-mqtt --save

有关 MQTT、AMQP 和 HTTPS 支持之间的差异的详细信息,请参阅云到设备通信指南选择通信协议

创建客户端模块

使用已安装的包创建 Client 模块。

例如:

const Client = require('azure-iot-device').Client;

创建协议模块

使用已安装的传输包创建 Protocol 模块。

此示例分配 MQTT 协议:

const Protocol = require('azure-iot-device-mqtt').Mqtt;

添加设备连接字符串和传输协议

调用 fromConnectionString 以提供设备连接参数:

  • connStr - 封装 IoT 中心的“设备连接”权限的连接字符串。 连接字符串包含主机名、设备 ID 和共享访问密钥,格式如下:“HostName=<iothub_host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>”。
  • transportCtor - 传输协议。

此示例使用 Mqtt 传输协议:

const deviceConnectionString = "{IoT hub device connection string}"
const Protocol = require('azure-iot-device-mqtt').Mqtt;
let client = Client.fromConnectionString(deviceConnectionString, Protocol);

打开到 IoT 中心的连接

使用 open 方法打开 IoT 设备和 IoT 中心之间的连接。 使用 .catch(err) 捕获错误和执行处理程序代码。

例如:

client.open()  //open the connection
.catch((err) => {
  console.error('Could not connect: ' + err.message);
});

检索设备孪生并检查报告属性

调用 getTwin,将当前设备孪生信息检索到 Twin 对象中。

例如:

client.getTwin(function(err, twin))
if (err)
    console.error('could not get twin');

更新报告的设备孪生属性

使用 update 以更新设备报告属性。 纳入 JSON 格式的修补程序作为该方法的第一个参数,以及函数执行状态回调方法作为该方法的第二个参数。

在此示例中,JSON 格式的设备孪生修补程序存储在 patch 变量中。 该修补程序包含一个 cellular 的设备孪生 connectivity 更新值。 该修补程序和错误处理程序被传递到 update 方法。 如果出现错误,随即会显示控制台错误消息。

var patch = {
    connectivity: {
        type: 'cellular'
    }
}
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));
});

在属性分组下的任何内容发生更改的情况下接收事件

如果属性分组下的任何内容发生更改,可创建一个侦听器来接收事件。

例如:

  1. minTemperaturemaxTemperature 属性位于名为 properties.desired.climate changes 的属性分组下。

  2. 后端服务应用程序应用此修补程序以更新 minTemperaturemaxTemperature 所需属性:

    const twinPatch1 = {
    properties: {
       desired: {
        climate: { minTemperature: 68, maxTemperature: 76, },
        },
      },
     };
    
  3. 此代码设置一个所需属性更改事件侦听器,该侦听器会触发 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 状态时,该代码都会输出新的相应状态。

  1. 后端应用程序应用此所需属性修补程序:

     const twinPatch2 = {
      properties: {
        desired: {
          climate: {
            hvac: {
              systemControl: { fanOn: true, },
            },
          },
        },
      },
    };
    
  2. 仅当 fanOn 属性发生更改时,侦听器才会触发:

     twin.on('properties.desired.climate.hvac.systemControl', function (fanOn) {
         console.log('setting fan state to ' + fanOn);
      });
    

设备 SDK 示例

适用于 Node.js 的 Azure IoT SDK 包含两个设备孪生示例:

创建后端应用程序

后端应用程序通过 IoT 中心连接到设备,并可读取设备报告属性和所需属性、写入设备所需属性并运行设备查询。

本部分介绍如何创建执行以下操作的后端应用程序:

  • 检索和更新设备孪生
  • 创建设备孪生查询

安装服务 SDK 包

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

npm install azure-iothub --save

Registry 类公开从后端应用程序与设备孪生进行交互所需的所有方法。

连接到 IoT 中心

使用 fromConnectionString 连接到 IoT 中心。 作为一个参数,提供在“先决条件”部分创建的 IoT 中心服务连接字符串

'use strict';
var iothub = require('azure-iothub');
var connectionString = '{Iot Hub service connection string}';
var registry = iothub.Registry.fromConnectionString(connectionString);

检索和更新设备孪生

可创建一个包含设备孪生的标记和所需属性更新的修补程序。

更新设备孪生:

  1. 调用 getTwin 以检索设备孪生对象。
  • 设置一个包含设备孪生更新的修补程序的格式。 该修补程序采用 JSON 格式,如 Twin 类中所述。 后端服务修补程序可包含标记和所需属性更新。 有关修补程序格式的详细信息,请参阅标记和属性格式
  1. 调用 update 以使用修补程序更新设备孪生。

在此示例中,检索 myDeviceId 的设备孪生,然后对孪生应用一个包含 region: 'US', plant: 'Redmond43'location 标记更新的修补程序。

     registry.getTwin('myDeviceId', function(err, twin){
         if (err) {
             console.error(err.constructor.name + ': ' + err.message);
         } else {
             var patch = {
                 tags: {
                     location: {
                         region: 'US',
                         plant: 'Redmond43'
                   }
                 }
             };

             twin.update(patch, function(err) {
               if (err) {
                 console.error('Could not update twin: ' + err.constructor.name + ': ' + err.message);
               } else {
                 console.log(twin.deviceId + ' twin updated successfully');
                 queryTwins();
               }
             });
         }
     });

创建设备孪生查询

可创建类似 SQL 的设备查询,以从设备孪生中收集信息。

使用 createQuery 创建一个可对 IoT 中心实例运行的查询,以查找有关设备或作业的信息。

createQuery 包括两个参数:

  • sqlQuery - 以 SQL 字符串形式编写的查询
  • pageSize - 每个页面所需的结果数(可选。默认值:1000,最大值:10000)

如果指定了 pageSize 参数,则查询对象包含一个 hasMoreResults 布尔属性,你可以根据需要多次检查并使用 nextAsTwin 方法来获取下一个孪生结果页,以检索所有结果。 名为 next 的方法可用于非设备孪生的结果(例如聚合查询的结果)。

此示例查询仅选择位于 Redmond43 工厂中的设备的设备孪生。

var queryTwins = function() {
var query = registry.createQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43'", 100);
query.nextAsTwin(function(err, results) {
    if (err) {
        console.error('Failed to fetch the results: ' + err.message);
    } else {
        console.log("Devices in Redmond43: " + results.map(function(twin) {return twin.deviceId}).join(','));
    }
});

此示例查询优化了第一个查询,以仅选择也通过手机网络连接的设备。

query = registry.createQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43' AND properties.reported.connectivity.type = 'cellular'", 100);
query.nextAsTwin(function(err, results) {
    if (err) {
        console.error('Failed to fetch the results: ' + err.message);
    } else {
        console.log("Devices in Redmond43 using cellular network: " + results.map(function(twin) {return twin.deviceId}).join(','));
    }
});
};

服务 SDK 示例

适用于 Node.js 的 Azure IoT SDK 提供了处理设备孪生任务的服务应用的工作示例。 有关详细信息,请参阅设备孪生后端服务 - 此项目用于为特定设备发送设备孪生修补程序更新。