如何通过 HTTP 按设备从 IoT 中心检索最新消息(事件)

How to retrieve the latest message (event) from IoT Hub, by device, via HTTP

我找到了许多关于如何从 运行 IoT 中心检索数据的示例。但是,在所有这些中,需要 WebSockets 的一些变体。

我需要一种方法来立即从 IoT 设备获取可用的最新消息。

场景

我是 运行 一个小型气象站,使用 4 台设备将数据发送到 IoT 中心。作为摆设,我要回收一个1st generation iPad。它的浏览器不支持 WebSockets,因此排除了所有现代方法。

我将通过轮询更新值,最好使用简单的 HTTP GET 请求,每 15 分钟一次。

我有上面提到的示例 运行 (qrysweathertest.azurewebsites.net),但它使用网络套接字,因此不适用于第一代 iPad.

IoT 中心不可能开箱即用。您必须将遥测值存储到存储器(例如数据库),并构建一个小型 API 来检索最新值。您可以使用 Azure Functions 存储和检索值,这将是启用您的方案的低成本方式。

或者,IoT Central 支持通过 inbuilt API 检索最新的遥测值。并且可能 IoT Central 的仪表板功能可以涵盖您的整个场景。

您的爱好项目的另一个替代方案可以考虑使用设备孪生 tags 属性 来存储最后的遥测数据。

基本上,您可以使用 EventGridTrigger 订阅者以 推送方式 [=56] 将遥测数据存储到设备孪生标签 属性 =] 或使用 拉取方式 例如, IoTHubTrigger 函数作为 iothub 流管道的消费者。

以下代码片段显示了 IoTHubTrigger 函数的示例:

run.csx:

#r "Microsoft.Azure.EventHubs"
#r "Newtonsoft.Json"
#r "..\bin\Microsoft.Azure.Devices.dll"
#r "..\bin\Microsoft.Azure.Devices.Shared.dll"


using Microsoft.Azure.Devices;
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Microsoft.Azure.EventHubs;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text;

static RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Environment.GetEnvironmentVariable("AzureIoTHubShariedAccessPolicy"));

public static async Task Run(EventData message, ILogger log)
{
    log.LogInformation($"\nSystemProperties:\n\t{string.Join(" | ", message.SystemProperties.Select(i => $"{i.Key}={i.Value}"))}");

    if (message.SystemProperties["iothub-message-source"]?.ToString() == "Telemetry")
    {    
        var connectionDeviceId = message.SystemProperties["iothub-connection-device-id"].ToString(); 
        var msg = Encoding.UTF8.GetString(message.Body.Array);
        
        log.LogInformation($"DeviceId = {connectionDeviceId}, Telemetry = {msg}");

        var twinPatch = JsonConvert.SerializeObject(new { tags = new { telemetry = new { lastUpdated = message.SystemProperties["iothub-enqueuedtime"], data = JObject.Parse(msg) }}});
        await registryManager.ReplaceTwinAsync(connectionDeviceId, twinPatch, "*");
    }
}

function.json:

{
  "bindings": [
    {
      "name": "message",
      "connection": "my_IOTHUB",
      "eventHubName": "my_IOTHUB_NAME",
      "consumerGroup": "function",
      "cardinality": "one",
      "direction": "in",
      "type": "eventHubTrigger"
    }
  ]
}

一旦遥测数据存储在设备孪生标记中 属性,我们就可以使用所有 iothub built-in 功能以编程方式或使用 Azure 门户查询和检索设备孪生。

以下示例显示了从所有设备获取遥测数据的查询字符串:

SELECT devices.id, devices.tags.telemetry FROM devices WHERE is_defined(devices.tags.telemetry)

使用REST Get Devices我们可以得到查询字符串的结果,看下面的例子:

并使用 REST Get Twin 我们可以获得特定设备的设备孪生,请参见以下示例:

备注:

  1. REST 请求需要 sas 令牌进行授权 header
  2. 上述解决方案不适用于 Basic Tier IoT Hub(没有设备孪生)
  3. 使用此解决方案适合业余项目(免费和 S1 定价层),如果有数百台设备频繁摄取遥测数据,请参阅 IoT Hub quotas and throttling 文档了解QueriesTwin updates.
  4. 的限制