设备孪生是存储设备状态信息的 JSON 文档,包括元数据、配置和条件。 IoT 中心为连接到它的每台设备保留设备孪生。
注释
本文中所述的功能仅在 IoT 中心的标准层中可用。 有关基本层和标准/免费 IoT 中心层的详细信息,请参阅 为解决方案选择正确的 IoT 中心层和大小。
使用设备孪生可以:
从解决方案后端存储设备元数据。
报告当前状态信息,例如可用功能和条件,例如设备应用中使用的连接方法。
在设备应用和后端应用之间同步长时间运行的工作流的状态,例如固件和配置更新。
查询设备元数据、配置或状态。
设备孪生专为同步和查询设备配置和条件而设计。 有关设备孪生的详细信息,包括何时使用设备孪生,请参阅 了解设备孪生。
IoT 中心存储设备孪生体,其中包含以下元素:
标记。 设备元数据只能由解决方案后端访问。
所需属性。 解决方案后端可修改的 JSON 对象,并且设备应用程序可对其进行观察。
报告的属性。 设备应用可修改的 JSON 对象,解决方案后端可读。
标记和属性不能包含数组,但可以包含嵌套对象。
下图显示了设备孪生结构:
此外,解决方案后端可以根据上述所有数据查询设备孪生。 有关设备孪生的详细信息,请参阅 了解设备孪生。 有关查询的详细信息,请参阅 IoT 中心查询语言。
在本文中,将创建两个 .NET 控制台应用:
AddTagsAndQuery:一个后端应用,用于添加标记和查询设备孪生。
ReportConnectivity:一个连接到 IoT 中心的模拟设备应用,并报告其连接条件。
注释
有关可用于生成设备和后端应用的 SDK 工具的详细信息,请参阅 Azure IoT SDK 。
先决条件
Visual Studio。
已注册的设备。 在 Azure 门户中注册一个。
确保已在防火墙中打开端口 8883。 本文中的设备示例使用通过端口 8883 进行通信的 MQTT 协议。 某些企业和教育网络环境中可能会阻止此端口。 有关解决此问题的详细信息和方法,请参阅“连接到 IoT 中心”(MQTT)。
获取 IoT 中心连接字符串
在本文中,你将创建一个后端服务,该服务将所需属性添加到设备孪生,然后查询标识注册表以查找报告的属性已相应地更新的所有设备。 服务需要 服务连接 权限来修改设备孪生的所需属性,并且需要 注册表读取 权限才能查询标识注册表。 没有仅包含这两个权限的默认共享访问策略,因此需要创建一个。
若要创建一个共享访问策略,用于授予 服务连接 和 注册表读取 权限并获取此策略的连接字符串,请执行以下步骤:
在 Azure 门户中,选择 资源组。 选择中心所在的资源组,然后从资源列表中选择中心。
在中心的左侧窗格中,选择 “共享访问策略”。
从策略列表上方的顶部菜单中,选择 “添加共享策略访问策略”。
在右侧的 “添加共享访问策略 ”窗格中,输入策略的描述性名称,例如 serviceAndRegistryRead。 在“权限”下,选择“注册表读取”和服务连接,然后选择“添加”。
从策略列表中选择新策略。
选择 主连接字符串 的复制图标并保存值。
有关 IoT 中心共享访问策略和权限的详细信息,请参阅 访问控制和权限。
创建更新报告属性的设备应用
在本部分中,将创建一个 .NET 控制台应用,该应用以 myDeviceId 身份连接到中心,然后更新其报告的属性,以确认它已使用手机网络进行连接。
打开 Visual Studio,然后选择“ 创建新项目”。
选择 控制台应用(.NET Framework),然后选择“ 下一步”。
在 “配置新项目”中,将项目命名为 ReportConnectivity,然后选择“ 下一步”。
在解决方案资源管理器中,右键单击 ReportConnectivity 项目,然后选择“ 管理 NuGet 包”。
保留默认的 .NET Framework,然后选择“ 创建 ”以创建项目。
选择 “浏览 ”并搜索并选择 Microsoft.Azure.Devices.Client。 选择“安装”。
此步骤下载、安装并添加对 Azure IoT 设备 SDK NuGet 包及其依赖项的引用。
在
using文件的顶部添加以下语句:using Microsoft.Azure.Devices.Client; using Microsoft.Azure.Devices.Shared; using Newtonsoft.Json;将以下字段添加到 Program 类。 替换为
{device connection string}在 IoT 中心注册设备时看到的设备连接字符串:static string DeviceConnectionString = "HostName=<yourIotHubName>.azure-devices.net;DeviceId=<yourIotDeviceName>;SharedAccessKey=<yourIotDeviceAccessKey>"; static DeviceClient Client = null;将以下方法添加到 Program 类:
public static async void InitClient() { try { Console.WriteLine("Connecting to hub"); Client = DeviceClient.CreateFromConnectionString(DeviceConnectionString, TransportType.Mqtt); Console.WriteLine("Retrieving twin"); await Client.GetTwinAsync(); } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("Error in sample: {0}", ex.Message); } }Client 对象公开了从设备与设备孪生交互所需的所有方法。 上面显示的代码初始化 Client 对象,然后检索 myDeviceId 的设备孪生。
将以下方法添加到 Program 类:
public static async void ReportConnectivity() { try { Console.WriteLine("Sending connectivity data as reported property"); TwinCollection reportedProperties, connectivity; reportedProperties = new TwinCollection(); connectivity = new TwinCollection(); connectivity["type"] = "cellular"; reportedProperties["connectivity"] = connectivity; await Client.UpdateReportedPropertiesAsync(reportedProperties); } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("Error in sample: {0}", ex.Message); } }上面的代码使用连接信息更新 myDeviceId 的报告属性。
最后,将以下行添加到 Main 方法:
try { InitClient(); ReportConnectivity(); } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("Error in sample: {0}", ex.Message); } Console.WriteLine("Press Enter to exit."); Console.ReadLine();在解决方案资源管理器中,右键单击解决方案,然后选择 “设置启动项目”。
在 “常用属性>启动项目”中,选择 “多个启动项目”。 对于 ReportConnectivity,请选择 开始 作为 操作。 选择“确定”,保存所做更改。
右键单击 ReportConnectivity 项目并选择“ 调试”,然后选择 “启动新实例”来运行此应用。 应会看到应用获取孪生信息,然后将连接作为 报告属性发送。
设备报告其连接信息后,它应出现在这两个查询中。
右键单击 AddTagsAndQuery 项目,然后选择 “调试>启动”新实例 以再次运行查询。 这一次, myDeviceId 应出现在这两个查询结果中。
创建用于更新所需属性和查询孪生的服务应用
在本部分中,你将使用 C# 创建一个 .NET 控制台应用,该应用将位置元数据添加到与 myDeviceId 关联的设备孪生。 该应用查询 IoT 中心以查找位于美国的设备,然后查询报告手机网络连接的设备。
在 Visual Studio 中,选择“ 文件 > 新建 > 项目”。 在 “创建新项目”中,选择 “控制台应用”(.NET Framework),然后选择“ 下一步”。
在 “配置新项目”中,将项目命名为 AddTagsAndQuery,然后选择“ 下一步”。
接受 .NET Framework 的默认版本,然后选择“ 创建 ”以创建项目。
在解决方案资源管理器中,右键单击 AddTagsAndQuery 项目,然后选择“ 管理 NuGet 包”。
选择 “浏览 ”并搜索并选择 “Microsoft.Azure.Devices”。 选择“安装”。
此步骤下载、安装并添加对 Azure IoT 服务 SDK NuGet 包及其依赖项的引用。
在
using文件的顶部添加以下语句:using Microsoft.Azure.Devices;将以下字段添加到 Program 类。 将
{iot hub connection string}替换为您在 获取 IoT 中心连接字符串 中复制的 IoT 中心连接字符串。static RegistryManager registryManager; static string connectionString = "{iot hub connection string}";将以下方法添加到 Program 类:
public static async Task AddTagsAndQuery() { var twin = await registryManager.GetTwinAsync("myDeviceId"); var patch = @"{ tags: { location: { region: 'US', plant: 'Redmond43' } } }"; await registryManager.UpdateTwinAsync(twin.DeviceId, patch, twin.ETag); 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))); }RegistryManager 类公开了与服务中的设备孪生交互所需的所有方法。 前面的代码首先初始化 registryManager 对象,然后检索 myDeviceId 的设备孪生,最后使用所需的位置信息更新其标记。
更新后,它会执行两个查询:第一个查询仅选择 位于 Redmond43 工厂的设备的设备孪生,第二个查询将优化查询,以仅选择也通过手机网络连接的设备。
在创建 查询 对象时,前面的代码指定返回的文档数上限。 查询对象包含一个 HasMoreResults 布尔属性,可用于多次调用 GetNextAsTwinAsync 方法以检索所有结果。 名为 GetNextAsJson 的方法可用于不是设备孪生的结果,例如聚合查询的结果。
最后,将以下行添加到 Main 方法:
registryManager = RegistryManager.CreateFromConnectionString(connectionString); AddTagsAndQuery().Wait(); Console.WriteLine("Press Enter to exit."); Console.ReadLine();右键单击 AddTagsAndQuery 项目并选择 “调试”,然后选择“ 启动新实例”来运行此应用程序。 应该会在查询结果中看到一个设备,询问 位于 Redmond43 中的所有设备,对于将结果限制为使用手机网络的设备的查询,不应看到任何设备。
本文内容:
- 从后端应用添加设备元数据作为标记
- 设备孪生中报告的设备连接信息
- 使用类似于 SQL 的 IoT 中心查询语言查询设备孪生信息
后续步骤
若要了解如何操作:
从设备发送遥测数据,请参阅 快速入门:将遥测数据从 IoT 即插即用设备发送到 Azure IoT 中心。
使用设备孪生的所需属性 配置设备,请参阅教程:从后端服务配置设备。
以交互方式控制设备,例如从用户控制的应用中打开风扇,请参阅 快速入门:控制连接到 IoT 中心的设备。