IOT is very common these days. We can solve many business problems with IOT and related tooling.
How we can easily listen to live telemetry feed and present a real-time dashboard?
In this article I will show, how we can achieve it with Azure IOT Hub, Azure Functions and Azure SignalR
I will use an existing setup I used in this example I wrote previously. I have used Raspberry Pi Azure IoT Online Simulator to simulate as an IOT device and connected it to my IOT hub. Let's start from there.
I will break this exercise into three parts
- Create Azure Function with IOT Hub trigger
- Integrate Azure SignalR to the Azure Function
- Consume real-time data in a client application and plot data in a graph
01. Azure Function with IOT Hub trigger
Step 01: Create a Function App
Step 02: Select IOT Hub as the trigger
Step 03: Navigate to IOT Hub and locate the ConnectionString. Specify the ConnectionString in local.settings.json file
Step 04: Change the function
[FunctionName("GetIoTEventData")]
public static async Task Run(
[IoTHubTrigger("messages/events", Connection = "ConnectionString")]EventData message,
ILogger log)
{
log.LogInformation($"C# IoT Hub trigger function processed a message: {Encoding.UTF8.GetString(message.Body.Array)}");
}
Step 05: Let's try out by running the function locally and starting the raspberry Pi simulator
I can see the function is executed when telemetry generated
Great! now the first part of our exercise is completed!
02. Integrate Azure SignalR to the Azure Function
Step 01: Create Azure SignalR service
Step 02: Get SignalR ConnectionString and update it in local.settings.json file
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"ConnectionString":"",
"AzureSignalRConnectionString": ""
},
"Host": {
"LocalHttpPort": 7072,
"CORS": "*"
}
}
Step 03: Let's add SignalR package
dotnet add package Microsoft.Azure.WebJobs.Extensions.SignalRService
Step 04: Add the negotiate endpoint
[FunctionName("negotiate")]
public static SignalRConnectionInfo Negotiate(
[HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req,
[SignalRConnectionInfo(HubName = "IOTHub")] SignalRConnectionInfo connectionInfo)
{
return connectionInfo;
}
Step 05: Create a new class to hold the telemetry information
public class Telemetry{
public int messageId {get; set;}
public string deviceId {get; set;}
public long temperature {get; set;}
public long humidity {get; set;}
}
Step 06: Let's modify the main function
[FunctionName("GetIoTEventData")]
public static async Task Run([
IoTHubTrigger("messages/events", Connection = "ConnectionString")]EventData message,
[SignalR(HubName = "IOTHub")]IAsyncCollector signalRMessages,
ILogger log)
{
Telemetry telemetry = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(message.Body.Array));
await signalRMessages.AddAsync(
new SignalRMessage
{
Target = "iotClient",
Arguments = new[] { telemetry.temperature.ToString() }
})
.ConfigureAwait(false);
}
03. Consume real-time data in a client application and plot data in a graph
Step 01: I use the JavaScript SDK for SignalR. We need to refer the following URL
https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/3.1.7/signalr.min.js"
Step 02: Following is the code we use to plot the graph
google.charts.load("current", {
packages: ["corechart", "line"]
});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
let data = google.visualization.arrayToDataTable([
["Second", "Temperature"],
[0, 0]
]);
let options = {
title: "Device Temperature",
hAxis: {
title: "Time"
},
vAxis: {
title: "Temperature"
}
};
let chart = new google.visualization.LineChart(
document.getElementById("chart_div")
);
chart.draw(data, options);
let index = 0;
const apiBaseUrl = window.location.origin;
const connection = new signalR.HubConnectionBuilder()
.withUrl(apiBaseUrl + '/api')
.configureLogging(signalR.LogLevel.Information)
.build();
connection.on('iotClient', (message) => {
data.addRow([index, parseInt(message)]);
chart.draw(data, options);
index++;
});
connection.start()
.catch(console.error);
}
That's it!. Following is the end result
I have pushed the code to GitHub
No comments:
Post a Comment