IoT 中心模块标识和模块孪生(.NET)入门

模块标识和模块孪生 类似于 Azure IoT 中心设备标识和设备孪生,但提供更精细的粒度。 虽然 Azure IoT 中心设备标识和设备孪生使后端应用程序能够配置设备并提供设备条件的可见性,但模块标识和模块孪生为设备的各个组件提供这些功能。 在具有多个组件(如操作系统设备或固件设备)的设备上,模块标识和模块双胞胎允许对每个组件进行独立的配置和条件设定。

注释

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

本文末尾有两个 .NET 控制台应用:

  • CreateIdentities:创建设备标识、模块标识和关联的安全密钥来连接设备和模块客户端。

  • UpdateModuleTwinReportedProperties:将更新的模块双胞胎的报告属性上报到 IoT 中心。

注释

有关可用于生成设备和后端应用的 SDK 工具的详细信息,请参阅 Azure IoT SDK

先决条件

  • Visual Studio。

  • IoT 中心。 使用 CLIAzure 门户创建一个。

获取 IoT 中心连接字符串

在本文中,你将创建一个后端服务,用于在标识注册表中添加设备,然后将模块添加到该设备。 服务需要 注册表写入 权限。 默认情况下,每个 IoT 中心都是使用名为 registryReadWrite 的共享访问策略创建的,该策略授予此权限。

若要获取 registryReadWrite 策略的 IoT 中心连接字符串,请执行以下步骤:

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

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

  3. 从策略列表中,选择 registryReadWrite 策略。

  4. 复制“主连接字符串”并保存该值

    显示如何检索连接字符串的屏幕截图

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

创建模块标识

在本部分中,你将创建一个 .NET 控制台应用,用于在中心的标识注册表中创建设备标识和模块标识。 设备或模块无法连接到中心,除非它在标识注册表中具有条目。 有关详细信息,请参阅 IoT 中心开发人员指南的“标识注册表”部分

运行此控制台应用时,它将为设备和模块生成唯一的 ID 和密钥。 设备和模块使用这些值在将设备到云的消息发送到 IoT 中心时自行标识。 ID 是区分大小写的。

  1. 打开 Visual Studio,然后选择“ 创建新项目”。

  2. “创建新项目”中,选择“控制台应用”(.NET Framework)。

  3. 选择 “下一步 ”打开 “配置新项目”。 将项目命名为 CreateIdentities,然后选择“ 下一步”。

    显示“配置新项目”弹出窗口的屏幕截图,其中显示了“CreateIdentities”。

  4. 保留默认的 .NET Framework 选项,然后选择“ 创建 ”以创建项目。

  5. 在 Visual Studio 中,打开 工具>NuGet 包管理器>管理解决方案的 NuGet 包。 选择“浏览”选项卡。

  6. 搜索 Microsoft.Azure.Devices。 选择它,然后选择“ 安装”。

    安装 Azure IoT 中心 .NET 服务 SDK 当前版本

  7. using文件的顶部添加以下语句:

    using Microsoft.Azure.Devices;
    using Microsoft.Azure.Devices.Common.Exceptions;
    
  8. 将以下字段添加到 Program 类。 将占位符值替换为上一部分中您创建的 IoT 中心连接字符串。

    const string connectionString = "<replace_with_iothub_connection_string>";
    const string deviceID = "myFirstDevice";
    const string moduleID = "myFirstModule";
    
  9. 将以下代码添加到 Main 类。

    static void Main(string[] args)
    {
        AddDeviceAsync().Wait();
        AddModuleAsync().Wait();
    }
    
  10. 将以下方法添加到 Program 类:

    private static async Task AddDeviceAsync()
    {
       RegistryManager registryManager = 
         RegistryManager.CreateFromConnectionString(connectionString);
       Device device;
    
       try
       {
           device = await registryManager.AddDeviceAsync(new Device(deviceID));
       }
       catch (DeviceAlreadyExistsException)
        {
            device = await registryManager.GetDeviceAsync(deviceID);
        }
    
        Console.WriteLine("Generated device key: {0}", 
          device.Authentication.SymmetricKey.PrimaryKey);
    }
    
    private static async Task AddModuleAsync()
    {
        RegistryManager registryManager = 
          RegistryManager.CreateFromConnectionString(connectionString);
        Module module;
    
        try
        {
            module = 
              await registryManager.AddModuleAsync(new Module(deviceID, moduleID));
        }
        catch (ModuleAlreadyExistsException)
        {
            module = await registryManager.GetModuleAsync(deviceID, moduleID);
        }
    
        Console.WriteLine("Generated module key: {0}", module.Authentication.SymmetricKey.PrimaryKey);
    }
    

    该方法 AddDeviceAsync 使用 ID myFirstDevice 创建设备标识。 如果该设备 ID 已存在于标识注册表中,则代码只是检索现有的设备信息。 然后,应用会显示该标识的主键。 在模拟设备应用中使用此密钥连接到集线器。

    AddModuleAsync 方法在设备 myFirstDevice 下创建了一个模块标识,ID 为 myFirstModule。 如果该模块 ID 已存在于标识注册表中,则代码只是检索现有的模块信息。 然后,应用程序会显示该标识的主键。 在模拟模块应用中使用此密钥连接到中心。

    重要

    设备 ID 可能在为客户支持和故障排除收集的日志中可见,因此请确保在命名时避免任何敏感信息。

  11. 运行此应用,并记下设备密钥和模块密钥。

注释

IoT 中心标识注册表仅存储设备和模块标识,以实现对中心的安全访问。 标识注册表存储用作安全凭据的设备 ID 和密钥。 标识注册表还为每个设备存储一个启用/禁用标志,这个标志可以用于禁用该设备的访问。 如果你的应用需要存储其他特定于设备的元数据,它应使用特定于应用程序的存储。 模块标识没有启用/禁用标志。 有关详细信息,请参阅 IoT 中心开发人员指南

使用 .NET 设备 SDK 更新模块孪生

现在,让我们从模拟设备与云通信。 创建模块标识后,会在 IoT 中心隐式创建模块孪生。 在本部分中,将在模拟设备上创建一个 .NET 控制台应用,用于更新模块孪生报告属性。

若要检索模块连接字符串,请导航到 IoT 中心 ,然后选择 “设备”。 找到并选择 myFirstDevice 将其打开,然后选择 myFirstModule 将其打开。 在 “模块标识详细信息”中,复制 连接字符串(主密钥) 并将其保存到控制台应用。

显示“模块标识详细信息”页的屏幕截图。

  1. 在 Visual Studio 中,通过选择“文件>新建>项目”将新项目添加到解决方案。 在 “创建新项目”中,选择 “控制台应用”(.NET Framework),然后选择“ 下一步”。

  2. “配置新项目”中,将项目 命名为 UpdateModuleTwinReportedProperties,然后选择“ 下一步”。

    显示“配置新项目”弹出窗口的屏幕截图。

  3. 保留默认的 .NET Framework 选项,然后选择“ 创建 ”以创建项目。

  4. 在 Visual Studio 中,打开 工具>NuGet 包管理器>管理解决方案的 NuGet 包。 选择“浏览”选项卡。

  5. 搜索并选择 Microsoft.Azure.Devices.Client,然后选择“ 安装”。

    显示已选中“Microsoft.Azure.Devices.Client”的屏幕截图,并突出显示了“安装”按钮。

  6. using文件的顶部添加以下语句:

    using Microsoft.Azure.Devices.Client;
    using Microsoft.Azure.Devices.Shared;
    using System.Threading.Tasks;
    using Newtonsoft.Json;
    
  7. 将以下字段添加到 Program 类。 将占位符值替换为模块连接字符串。

    private const string ModuleConnectionString = "<Your module connection string>";
    private static ModuleClient Client = null;
    static void ConnectionStatusChangeHandler(ConnectionStatus status, 
      ConnectionStatusChangeReason reason)
    {
        Console.WriteLine("Connection Status Changed to {0}; the reason is {1}", 
          status, reason);
    }
    
  8. 将以下 OnDesiredPropertyChanged 方法添加到 Program 类:

    private static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, 
      object userContext)
        {
            Console.WriteLine("desired property change:");
            Console.WriteLine(JsonConvert.SerializeObject(desiredProperties));
            Console.WriteLine("Sending current time as reported property");
            TwinCollection reportedProperties = new TwinCollection
            {
                ["DateTimeLastDesiredPropertyChangeReceived"] = DateTime.Now
            };
    
            await Client.UpdateReportedPropertiesAsync(reportedProperties).ConfigureAwait(false);
        }
    
  9. 将以下行添加到 Main 方法:

    static void Main(string[] args)
    {
        Microsoft.Azure.Devices.Client.TransportType transport = 
          Microsoft.Azure.Devices.Client.TransportType.Amqp;
    
        try
        {
            Client = 
              ModuleClient.CreateFromConnectionString(ModuleConnectionString, transport);
            Client.SetConnectionStatusChangesHandler(ConnectionStatusChangeHandler);
            Client.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChanged, null).Wait();
    
            Console.WriteLine("Retrieving twin");
            var twinTask = Client.GetTwinAsync();
            twinTask.Wait();
            var twin = twinTask.Result;
            Console.WriteLine(JsonConvert.SerializeObject(twin.Properties)); 
    
            Console.WriteLine("Sending app start time as reported property");
            TwinCollection reportedProperties = new TwinCollection();
            reportedProperties["DateTimeLastAppLaunch"] = DateTime.Now;
    
            Client.UpdateReportedPropertiesAsync(reportedProperties);
        }
        catch (AggregateException ex)
        {
            Console.WriteLine("Error in sample: {0}", ex);
        }
    
        Console.WriteLine("Waiting for Events.  Press enter to exit...");
        Console.ReadLine();
        Client.CloseAsync().Wait();
    }
    

    现在,你已了解如何使用 AMQP 协议检索模块孪生并更新报告的属性。

  10. (可选)可以将这些语句添加到 Main 方法,以便从模块将事件发送到 IoT 中心。 将这些行放在 try catch 块的下方。

    Byte[] bytes = new Byte[2];
    bytes[0] = 0;
    bytes[1] = 1;
    var sendEventsTask = Client.SendEventAsync(new Message(bytes));
    sendEventsTask.Wait();
    Console.WriteLine("Event sent to IoT Hub.");
    

运行应用

现在可以运行应用。

  1. 在 Visual Studio 的解决方案资源管理器中,右键单击解决方案,然后选择 “设置启动项目”。

  2. “通用属性”下,选择“ 启动项目”。

  3. 选择 多个启动项目,然后选择启动作为应用的动作,然后确定以接受更改。

  4. F5 启动应用。

后续步骤

若要继续开始使用 IoT 中心并探索其他 IoT 方案,请参阅: