使用Schedule job对多个设备进行操作
分类: Azure物联网 ◆ 标签: #Azure # #IoT Hub ◆ 发布于: 2023-06-13 20:56:14

使用Azure IoT Hub
的计划任务可以同时操作多个设备,使用计划任务可以处理如下的场景:
- 批量更新预期属性
- 批量更新Tags
- 批量调用直接方法。
本章向大家展示如何使用.Net Service SDK
来创建计划任务,并使用该任务调用直接方法,本章需要使用到之前创建的一个实例,DirectMethodCallSample
, 您可以参考文档重新创建该实例:
使用.Net Service SDK调用设备的Direct Method方法
创建一个新的项目
首先使用如下的命令取得设备simDevice
的连接字符串,当然这之前你需要先创建好Azure IoT Hub
资源以及该设备:
az iot hub device-identity connection-string show --device-id simDevice --hub-name MyIoThubByCli
得到连接字符串之后,先保存起来,后面的代码中需要使用到这个连接字符串。
使用下述的命令创建我们的项目:
dotnet new console -o ScheduleJob
cd ScheduleJob
dotnet add package Microsoft.Azure.Devices.Client
code .
打开VS code
或者其他编辑器之后,在根目录下添加一个文件GlobalUsing.cs
, 打开该文件,添加如下的引用:
global using Microsoft.Azure.Devices; global using Microsoft.Azure.Devices.Shared; global using System.Text.Json; global using System.Text; global using System.Text.Json.Serialization; global using System.Diagnostics; global using ScheduleJob;
在根目录下创建一个JobSample.cs
的文件,以下述内容替换:
namespace ScheduleJob; public class JobSample { private readonly JobClient jobClient; private readonly string deviceId; public JobSample(JobClient client, string device) { jobClient = client ?? throw new ArgumentNullException(nameof(client)); deviceId = device ?? throw new ArgumentNullException(nameof(device)); } public async Task RunSampleAsync() { Console.WriteLine("按回车键开始运行计划任务......"); Console.ReadLine(); string methodJobId = Guid.NewGuid().ToString(); await StartMethodJobAsync(methodJobId); await MonitorJobAsync(methodJobId); Console.WriteLine("按回车键继续下一个任务."); Console.ReadLine(); string twinUpdateJobId = Guid.NewGuid().ToString(); await StartTwinUpdateJobAsync(twinUpdateJobId); await MonitorJobAsync(twinUpdateJobId); Console.WriteLine("按回车键退出。"); Console.ReadLine(); } public async Task MonitorJobAsync(string jobId) { JobResponse result; do { result = await jobClient.GetJobAsync(jobId); Console.WriteLine("计划任务的状态 : " + result.Status.ToString()); Thread.Sleep(2000); } while ((result.Status != JobStatus.Completed) && (result.Status != JobStatus.Failed)); } public async Task StartMethodJobAsync(string jobId) { CloudToDeviceMethod directMethod = new CloudToDeviceMethod("WriteToConsole", TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5)); JobResponse result = await jobClient.ScheduleDeviceMethodAsync(jobId, $"DeviceId IN ['{deviceId}']", directMethod, DateTime.UtcNow, (long)TimeSpan.FromMinutes(2).TotalSeconds); Console.WriteLine("开始调用直接方法"); } public async Task StartTwinUpdateJobAsync(string jobId) { Twin twin = new Twin(deviceId); twin.Tags = new TwinCollection(); twin.Tags["Building"] = "43"; twin.Tags["Floor"] = "3"; twin.ETag = "*"; twin.Properties.Desired["LocationUpdate"] = DateTime.UtcNow; JobResponse createJobResponse = await jobClient.ScheduleTwinUpdateAsync( jobId, $"DeviceId IN ['{deviceId}']", twin, DateTime.UtcNow, (long)TimeSpan.FromMinutes(2).TotalSeconds); Console.WriteLine("开始孪生设备属性更新......"); } }
特别是需要注意这里对async
以及await
的用法,以及使用他们用于计划任务观察的异步模式。
然后打开Program.cs
,以如下的内容替换:
Console.WriteLine("使用SAS Key连接字符串连接Azure IoT Hub, 并创建计划任务......"); string s_connectionString = "<您的连接字符串>"; var deviceId = "simDevice"; //验证连接字符串是否是正确的 ValidateConnectionString(args); using var jobClient = JobClient.CreateFromConnectionString(s_connectionString); var sample = new JobSample(jobClient, deviceId); await sample.RunSampleAsync(); await jobClient.CloseAsync(); Console.WriteLine("Done."); void ValidateConnectionString(string[] appArgs) { if ( appArgs.Any() ) { try { var cs = IotHubConnectionStringBuilder.Create(appArgs[0]); s_connectionString = cs.ToString(); } catch ( Exception ) { Console.WriteLine($"错误:无法识别连接字符串参数 `{appArgs[0]}"); Environment.Exit(-1); } } else { try { _ = IotHubConnectionStringBuilder.Create(s_connectionString); } catch(Exception ) { Console.WriteLine("这个Demo需要使用连接字符串连接到Azure IoT Hub"); Environment.Exit(-1); } } }
同时运行这两个应用,即可以看到效果。