使用SAS Key登记、注册和初始化设备
分类: Azure物联网 ◆ 标签: #Azure #Azure IoT Device Provisioning Service # ◆ 发布于: 2023-06-14 20:21:08
从本节开始我们开始以代码的方式来给出实例,在操作之前,请参考文章:
创建Azure IoT Hub
服务和DPS
服务,并将Azure IoT Hub
连接到DPS
服务中。
创建好了资源之后,并且将iot hub
连接到dps
之后,我们开始使用Azure cli
来创建单个设备登记,并设定使用SAS Key
来登记设备。
请使用如下的命令创建单个设备登记:
az iot dps enrollment create -g my-sample-resource-group --dps-name my-sample-dps --enrollment-id my-first-enrollment-device --device-id my-first-dps-device --attestation-type symmetrickey
请记住这行命令里的几个重要的值:
registration id
:my-first-enrollment-device
device id
:my-first-dps-device
取回DPS
服务的idScope
:
az iot dps show --name my-sample-dps -g my-sample-resource-group | jq .properties.idScope
请注意这里需要安装工具jq, 请参考网站:https://stedolan.github.io/jq/
使用如下的取回SAS Key
az iot dps enrollment show --dps-name my-sample-dps -g my-sample-resource-group --enrollment-id my-first-enrollment-device --show-key
如下图:
请保存好我们如图所示的primary key。
创建应用
请注意我们使用.Net 6
创建的代码,请使用下图所示的命令来创建我们的应用。
dotnet new console -o SymmetricKeySample
cd SymmetricKeySample
dotnet add package CommandLineParser
dotnet add package Microsoft.Azure.Devices.Client
dotnet add package Microsoft.Azure.Devices.Provisioning.Client
dotnet add package Microsoft.Azure.Devices.Provisioning.Transport.Amqp
dotnet add package Microsoft.Azure.Devices.Provisioning.Transport.Mqtt
dotnet add package Microsoft.Azure.Devices.Provisioning.Transport.Http
code . //请安装 VS Code
使用Vs Code
打开项目之后,在根目录下添加文件GlobalUsing.cs
, 添加如下的内容:
global using Microsoft.Azure.Devices.Client; global using Microsoft.Azure.Devices.Provisioning.Client.Transport; global using Microsoft.Azure.Devices.Provisioning.Client; global using Microsoft.Azure.Devices.Shared; global using System.Text; global using CommandLine; global using SymmetricKeySample.Parameters; global using SymmetricKeySample.Samples;
作为全局包引用。
需要注意的是本实例使用包CommandLineParser
来解析命令行,因此我们需要用一个辅助类来获取命令行的参数。
在项目中创建一个文件:EnrollmentType.cs
, 用于定义登记的类型:
namespace SymmetricKeySample.Samples; public enum EnrollmentType { /// <summary> /// Enrollment for a single device. /// </summary> Individual, /// <summary> /// Enrollment for a group of devices. /// </summary> Group, }
创建文件:Parameters.cs
, 该文件主要用于获取命令行参数
namespace SymmetricKeySample.Parameters; public class OptionParameters { [Option( 's', "IdScope", Required = true, HelpText = "The Id Scope of the DPS instance")] public string? IdScope { get; set; } [Option( 'i', "Id", Required = true, HelpText = "The registration Id when using individual enrollment, or the desired device Id when using group enrollment.")] public string? Id { get; set; } [Option( 'p', "PrimaryKey", Required = true, HelpText = "The primary key of the individual enrollment or the derived primary key of the group enrollment. See the ComputeDerivedSymmetricKeySample for how to generate the derived key.")] public string? PrimaryKey { get; set; } [Option( 'e', "EnrollmentType", Default = EnrollmentType.Individual, HelpText = "The type of enrollment: Individual or Group")] public EnrollmentType EnrollmentType { get; set; } [Option( 'g', "GlobalDeviceEndpoint", Default = "global.azure-devices-provisioning.cn", HelpText = "The global endpoint for devices to connect to.")] public string? GlobalDeviceEndpoint { get; set; } [Option( 't', "TransportType", Default = TransportType.Mqtt, HelpText = "The transport to use to communicate with the device provisioning instance. Possible values include Mqtt, Mqtt_WebSocket_Only, Mqtt_Tcp_Only, Amqp, Amqp_WebSocket_Only, Amqp_Tcp_only, and Http1.")] public TransportType TransportType { get; set; } }
请参考上述的类定义,我们可以使用如下的参数说明:
D:\MyProjects\azure-demo\IoT\SymmetricKeySample>dotnet run
SymmetricKeySample 1.0.0
Copyright (C) 2021 SymmetricKeySample
ERROR(S):
Required option 's, IdScope' is missing.
Required option 'i, Id' is missing.
Required option 'p, PrimaryKey' is missing.
-s, --IdScope Required. The Id Scope of the DPS instance
-i, --Id Required. The registration Id when using individual enrollment, or the desired device Id
when using group enrollment.
-p, --PrimaryKey Required. The primary key of the individual enrollment or the derived primary key of the
group enrollment. See the ComputeDerivedSymmetricKeySample for how to generate the
derived key.
-e, --EnrollmentType (Default: Individual) The type of enrollment: Individual or Group
-g, --GlobalDeviceEndpoint (Default: global.azure-devices-provisioning.cn) The global endpoint for devices to
connect to.
-t, --TransportType (Default: Mqtt) The transport to use to communicate with the device provisioning
instance. Possible values include Mqtt, Mqtt_WebSocket_Only, Mqtt_Tcp_Only, Amqp,
Amqp_WebSocket_Only, Amqp_Tcp_only, and Http1.
--help Display this help screen.
--version Display version information.
D:\MyProjects\azure-demo\IoT\SymmetricKeySample>
在项目目录下创建文件:ProvisioningDeviceClientSample.cs
, 该文件内容如下:
namespace SymmetricKeySample.Samples; public class ProvisioningDeviceClientSample { private readonly OptionParameters _parameters; public ProvisioningDeviceClientSample(OptionParameters parameters) { _parameters = parameters; } public async Task RunSampleAsync() { Console.WriteLine($"初始化Azure IoT Hub DPS客户端..."); // For individual enrollments, the first parameter must be the registration Id, where in the enrollment // the device Id is already chosen. However, for group enrollments the device Id can be requested by // the device, as long as the key has been computed using that value. // Also, the secondary could be included, but was left out for the simplicity of this sample. using var security = new SecurityProviderSymmetricKey( _parameters.Id, _parameters.PrimaryKey, null); using var transportHandler = GetTransportHandler(); ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create( _parameters.GlobalDeviceEndpoint, _parameters.IdScope, security, transportHandler); Console.WriteLine($"初始化DPS登记: 注册ID为: {security.GetRegistrationID()}."); Console.WriteLine("通过DPS服务进行注册..."); DeviceRegistrationResult result = await provClient.RegisterAsync(); Console.WriteLine($"注册状态: {result.Status}."); if (result.Status != ProvisioningRegistrationStatusType.Assigned) { Console.WriteLine($"未能分配合适的Azure IoT Hub."); return; } Console.WriteLine($"设备ID: {result.DeviceId} 成功注册到IoT Hub: {result.AssignedHub}."); Console.WriteLine("创建IoT Hub的SAS Key认证..."); IAuthenticationMethod auth = new DeviceAuthenticationWithRegistrySymmetricKey( result.DeviceId, security.GetPrimaryKey()); Console.WriteLine($"测试连接Azure IoT Hub..."); using DeviceClient iotClient = DeviceClient.Create(result.AssignedHub, auth, _parameters.TransportType); Console.WriteLine("发送测试消息..."); using var message = new Message(Encoding.UTF8.GetBytes("TestMessage")); await iotClient.SendEventAsync(message); Console.WriteLine("完成测试退出."); } private ProvisioningTransportHandler GetTransportHandler() { return _parameters.TransportType switch { TransportType.Mqtt => new ProvisioningTransportHandlerMqtt(), TransportType.Mqtt_Tcp_Only => new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly), TransportType.Mqtt_WebSocket_Only => new ProvisioningTransportHandlerMqtt(TransportFallbackType.WebSocketOnly), TransportType.Amqp => new ProvisioningTransportHandlerAmqp(), TransportType.Amqp_Tcp_Only => new ProvisioningTransportHandlerAmqp(TransportFallbackType.TcpOnly), TransportType.Amqp_WebSocket_Only => new ProvisioningTransportHandlerAmqp(TransportFallbackType.WebSocketOnly), TransportType.Http1 => new ProvisioningTransportHandlerHttp(), _ => throw new NotSupportedException($"不支持的网络协议类型 {_parameters.TransportType}"), }; } }
最后更改Program.cs
文件内容如下:
OptionParameters parameters = null!; ParserResult<OptionParameters> result = Parser.Default.ParseArguments<OptionParameters>(args) .WithParsed(parsedParams => { parameters = parsedParams; }) .WithNotParsed(errors => { Environment.Exit(1); }); var sample = new ProvisioningDeviceClientSample(parameters); await sample.RunSampleAsync(); return 0;
至此该实例的所有代码都准备好了,您可以通过如下的命令来运行该实例:
dotnet run --s <id-scope> --i <registration-id> --p <primarykey>
注意这里需要的信息文章前面都已经有了,请在这里替换就好了。
运行结果如下:
检查Azure IoT Hub
如下:
最后不要忘记了清理资源,使用如下的命令直接删除资源组:
az group delete --name my-sample-resource-group