Reputation: 15742
I have found many examples on how to retrieve data from a running IoT hub. However, in all of these, some variant of WebSockets is required.
I need a way to immediately get the latest message available from an IoT device.
I am running a small weather station using 4 devices, which send their data to the IoT hub. As a display, I want to recycle a 1st generation iPad. It's browser does not support WebSockets, thus ruling out all the modern approaches.
I will update the values with polling, preferably using simple HTTP GET requests, every 15 minutes.
I have the above mentioned sample running (qrysweathertest.azurewebsites.net), but it uses web sockets, thus not working on a 1stGen iPad.
Upvotes: 0
Views: 1391
Reputation: 8265
Another alternative for your hobby project can be considered to use a device twin tags property for storing the last telemetry data.
Basically, you can use the EventGridTrigger subscriber for storing the telemetry data to the device twin tags property in the push manner or using the pull manner for instance, the IoTHubTrigger function as a consumer of the iothub stream pipeline.
The following code snippet shows an example of the IoTHubTrigger function:
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"
}
]
}
Once, the telemetry data are stored in the device twin tags property, we can use all iothub built-in features for querying and retrieving the device twins programmatically or using the azure portal.
The following example shows a query string to obtain the telemetry data from all devices:
SELECT devices.id, devices.tags.telemetry FROM devices WHERE is_defined(devices.tags.telemetry)
Using the REST Get Devices we can get the result of the query string, see the following example:
and using the REST Get Twin we can get the device twin for specific device, see the following example:
Notes:
Upvotes: 0
Reputation: 4095
This is not possible out of the box with IoT Hub. You will have to store the telemetry values to storage (a database for instance), and build a small API to retrieve the latest value. You could store and retrieve the values using Azure Functions, which would be a low-cost way to enable your scenario.
Alternatively, IoT Central does support retrieving the latest telemetry value through the inbuilt API. And possibly the dashboarding features of IoT Central can cover your entire scenario.
Upvotes: 1