Отправлять сообщения на подключенные устройства IOT, когда данные поступают в очередь Azure? - PullRequest
0 голосов
/ 08 июля 2019

У меня есть Azure IOT Hub , к которому время от времени подключаются несколько устройств Arduino .У меня также есть Azure Queue , которая может содержать строки json, которые я хочу отправить отдельным устройствам, когда они подключены .

Я следовал пример для создания веб-задания, которое вызывается при поступлении данных в очередь.Я также последовал пример , который планирует задание для отправки данных на устройство IOT при подключении.Оба работают правильно, когда запускаются по отдельности.

Я объединил эти примеры так, чтобы при вызове ProcessQueueMessage () из-за того, что что-то поступило в очередь, я тогда планировал задание для отправки этих данных на устройство IOT.

public static async Task ProcessQueueMessage([QueueTrigger("inbox")] string message, ILogger logger)
{
  logger.LogInformation(message);
  Message = message;

  string methodJobId = Guid.NewGuid().ToString();
  await StartMethodJob(methodJobId, Message);
  MonitorJob(methodJobId).Wait();
}

Однако это вызвало исключение SystemNullException, и я не уверен, почему.Все функции статичны, и если я пройдусь по ним, я увижу, что входящие параметры имеют значения.В результате он перемещает элемент очереди в другую очередь «inbox-toxic».

info: Function.ProcessQueueMessage.User[0]
      {"TransId":3517,"DeviceId":"Huzz_2_2_2","PriceAlert":{"Price":"High","Variance":0.0,"DisplaySetting":1,"Duration":60}}
fail: Function.ProcessQueueMessage[0]
      Executed 'Functions.ProcessQueueMessage' (Failed, Id=556812ab-4a58-4ae1-9f4f-6336962d92d2)
Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ProcessQueueMessage ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at IncomeEligible.Alerts.Functions.StartMethodJob(String jobId, String json) in C:\source\repos\Income_Eligible_Price_Display\src\IncomeEligible.Alerts\IncomeEligible.Alerts\Functions.cs:line 46
   at IncomeEligible.Alerts.Functions.ProcessQueueMessage(String message, ILogger logger) in C:\source\repos\Income_Eligible_Price_Display\src\IncomeEligible.Alerts\IncomeEligible.Alerts\Functions.cs:line 80
   at Microsoft.Azure.WebJobs.Host.Executors.VoidTaskMethodInvoker`2.InvokeAsync(TReflected instance, Object[] arguments) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\VoidTaskMethodInvoker.cs:line 20
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.InvokeAsync(Object instance, Object[] arguments) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 52
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeAsync(IFunctionInvoker invoker, ParameterHelper parameterHelper, CancellationTokenSource timeoutTokenSource, CancellationTokenSource functionCancellationTokenSource, Boolean throwOnTimeout, TimeSpan timerInterval, IFunctionInstance instance) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 584
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 531
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, IFunctionOutputDefinition outputDefinition, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 467
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 277
   --- End of inner exception stack trace ---
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 321
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsyncCore(IFunctionInstanceEx functionInstance, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 117

Моя программа содержит следующее:

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace IncomeEligible.Alerts
{
  public class Functions
  {
    private static JobClient jobClient;
    private static int Count = 0;
    private static string Message = "";

    private static string deviceId = "Huzzah_w_DHT22";

    private const string DeviceConnectionString =
      "HostName=...";

    private const string HubConnectionString =
      "HostName=...";

    public static async Task MonitorJob(string jobId)
    {
      JobResponse result;
      do
      {
        result = await jobClient.GetJobAsync(jobId);
        Console.WriteLine("Job Status : " + result.Status.ToString());
        Thread.Sleep(2000);
      } while ((result.Status != JobStatus.Completed) &&
               (result.Status != JobStatus.Failed));
    }

    public static async Task StartMethodJob(string jobId, string json)
    {
      CloudToDeviceMethod directMethod =
        new CloudToDeviceMethod("SetPriceAlert", TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));

      directMethod.SetPayloadJson(json);

      JobResponse result = await jobClient.ScheduleDeviceMethodAsync(jobId,
        $"DeviceId IN ['{deviceId}']",
        directMethod,
        DateTime.UtcNow,
        (long)TimeSpan.FromMinutes(2).TotalSeconds);

      Console.WriteLine("Started Method Job");
    }

    public static async Task ProcessQueueMessage([QueueTrigger("inbox")] string message, ILogger logger)
    {
      logger.LogInformation(message);
      Message = message;

      string methodJobId = Guid.NewGuid().ToString();
      await StartMethodJob(methodJobId, Message);
      MonitorJob(methodJobId).Wait();

    }

  }
}

При правильной работе этот подход вызываетСмысл или лучше или настроить триггер Event Hub или IOT Hub, который определяет, когда устройство подключено, и вызывает функцию, чтобы заставить его отправлять json на подключенное устройство?

Спасибо за вашу помощь!

1 Ответ

0 голосов
/ 08 июля 2019

jobClient не присвоено никакое значение.

Также вы не хотите смешивать async с блокирующими вызовами, такими как .Wait() и Thread.Sleep(). Вместо этого используйте await и await Task.Delay().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...