Introduction to Azure IoT Hub
IoT isn't anything new, in fact it's been something companies have been doing since before it was named IoT. So you might wonder, if it's not new, then why all the hype? It's a good question and the answer is complex. However these days there are a few things that have enabled IoT to take off. The internet is ubiquitous and reasonably inexpensive, makeing it easy to get devices online. The cloud is another enabler, and it's an important one, because it's helped to make it possible for individuals to do things that were once cost prohibitive. Another enabler is hardware devices such as the Raspberry Pi or Arduino. These boards make it easy for just about anyone with $40 to start prototyping.
Since the cloud is a major enabler of IoT, it's no surprise that cloud vendors are creating their own IoT solutions. Azure has a lot to offer in the IoT world, and one of the services is IoT Hub. IoT Hub is a services that provides a device registry as well as mechanisms for cloud-to-devices and device-to-cloud communication.
This course is intended to help get you up to speed on using Azure IoT Hub, and in particular, with the IoT Hub SDKs.
Getting Started With Azure IoT Hub: What You'll Learn
Lecture | What you'll learn |
---|---|
Course Intro | What to expect from this course |
Introductio to IoT Hub | A high level overview of what Azure IoT Hub is, and its basic capabilities |
Devices and Developers | What are devices |
Device Management | The IoT Hub Devices Registry |
Device to Cloud | Device to cloud messages |
Device to Cloud - Part 2 | Endpoints and file uploads |
Cloud to device | Sending messages to devices from IoT Hub |
Device Configuration | Configuring device state, and invoking messages |
Next Steps | What's next |
The source code for this course can be downloaded from Github
If you have thoughts or suggestions for this course, please contact Cloud Academy at support@cloudacademy.com.
Hi, and welcome back!
In this lesson, we’ll continue to talk about device to cloud communication, in particular we’ll talk about endpoint, as well as how to go about uploading files to IoT Hub.
IoT Hub is a container of multiple endpoints. When sending a message, your device sends the message to a device endpoint.
There’s a “device endpoint” in IoT Hub for each registered device, and it’s automatically configured by the service.
In addition to the device endpoint, you also have a service endpoint where you can consume the data.
In a device to cloud scenario, messages are received by a device endpoint and then made available from a service endpoint.
Without any further configuration, the default service endpoint for the device to cloud endpoint is named messages/send, and it is backed by an EventHub compatible service.
Having a single endpoint for all messages can be valuable, because you can send all the messages from a device to that single device endpoint; however, not all the messages are the same.
In the previous lesson, we talked about telemetry messages, however you could have all kinds of different message types. Telemetry is a common type, and so are alerts. Alerts are still messages, though they probably should be handled differently than the telemetry messages.
Devices don’t need to know or worry about message types. The job of the device is to perform its task, and to send whatever messages you want to the device endpoint.
Which means if you want to have different message types handled differently, then you have to do it somewhere other than the device. And IoT Hub provides you with a place to handle it. That way, all devices just keep sending data as usual, and IoT Hub can send the messages on to other services.
IoT Hub comes with a default service endpoint, but if want to handle multiple message types with different services, you need more.
Each service endpoint should relate to a service that can handle specific messages. I’ve mentioned that the default device to cloud endpoint is an EventHub compatible endpoint.
Let’s imagine you want to create another eventhub endpoint because, you need it to handle a large volume of messages, or you want to correlate them with some analytic processes.
Or maybe you want to create a custom endpoint backed by a service bus queue because you need a less intensive, one by one message processing option.
Or maybe you want to create a custom endpoint backed by a service bus topic because you need to notify multiple subscribers about a topic.
So, if you were going to implement each of those endpoints yourself, you would need to have multiple service endpoints, and then you’d need to dispatch your messages.
Writing a dispatcher can become complex, especially if you’re going to match the same performance levels that the individual services already have.
This is why IoT Hub provides an out of the box routing feature, which allows you to define routes, and then using a property matching expression, direct the messages to one or more endpoints.
Routing allows you to use the message properties to filter out specific messages, and then route them to the endpoints of your choosing.
For example, you can use the “Type” property, and target only alerts.
If a single message matches multiple routing rules IoT Hub delivers the message to the endpoint of each matched rule.
A route rule consists of a name, source, condition and endpoint.
The interesting properties here are condition and endpoint.
The endpoint is where you want to route the message, and the condition is an expression similar to a SQL where clause, used to select the messages you want to route.
Let’s see endpoints working in a demo.
I'm here with my Powershell script where I can launch a new instance of the IoT Hub Device Simulator application.
This is similar to the telemetry demo, except I have a command called ‘fake alert’, that simulates the generation of events. Just instead of telemetry, this time it creates alerts, which have different properties. For example, an “alert type” property, and a severity.
If I run it, you can see that it behaves almost the same as telemetry, except the simulator is generating events at a lower frequency. It’s roughly every 30 seconds.
Notice the "Type" property has a value of "alert", there’s also the alert type, and then a random number representing the severity.
So what’s IoT Hub doing with these messages?
If we go to the portal, and open up the IoT Hub service blade, and then scroll down to open the endpoints blade. Notice that there are some default endpoints for IoT Hub.
In particular, there’s the message/events endpoint, which is the default.
It is the endpoint where all messages are routed when they arrive from the devices if nothing else is specified.
When you need custom endpoints, you can create them by clicking the add button.
This blade allows you to specify a name and an endpoint type, and you can specify the type of endpoint, with the options being EventHub, service bus queue, or service bus topic.
In our case, I have already configured a custom endpoint, named alert, that is an EventHub compatible endpoint.
And you can see that it allows you to set all the settings you’d expect from EventHub.
Since we have a custom endpoint, we need to route the alert messages to this endpoint.
To do that, we go to the routes blade...Notice there’s a default rule that says if a message doesn't match any custom rule, send it to the default message event endpoint.
Then there’s a custom rule called alert, that I have already defined.
It applies to all the messages from the devices, and then filters using the condition, which is that where clause I mentioned earlier. It’s set to "Type = alert" and it’s just a text area that you can free-type your expression in.
When messages satisfy this rule, they’re routed to a specific endpoint, and you can see that the alert endpoint is specified.
Let’s see this all working. First, let’s make sure the simulator is still running...and it is.
To handle all the events, I have implemented a function in our Azure Function App.
The function is called HandleAlert, and it’s an event hub triggered function like the telemetry one. However, notice that the output is different. In this example, because it’s an alert, I wanted to send a Twilio message to my cell phone whenever an alert arrives.
Before you can use Twilio you have to configure the Azure subscription for a Twilio service. However if you’d rather use a different output, you certainly can.
Looking at the function in the develop tab, you see that the run function receives the EventHub message and the output parameter for a Twilio is Async Collector for messages.
Then in the method here I’m configuring the sms message, and then adding it to the messages collection.
Looking at the logs, you see that the function is still running, and checking my smartphone I can see that I am receiving some JSON messages.
So once we have a route to handle specific message types, we can then process those messages using whichever service we select as an endpoint.
This is really cool, because with very little code or effort I’m able to have alerts sent to my cell phone.
Let’s shift our focus to file uploads, because depending on your use case, that may be something you have to do.
Maybe you need to upload media files from a surveillance camera, large telemetry batches, or something similar. Either way, IoT Hub provides file upload functionality.
The way it works is that IoT Hub serves as a dispatcher for an Azure Storage account. You can configure IoT Hub to use a storage account, and when you upload files, they’ll be stored there.
Instead of uploading your file directly, IoT Hub has an endpoint that you can call, and it will return a SAS URI that you can use to upload the file. Keep in mind because this is based on Azure storage, you are limited to using HTTP.
Once a file has been uploaded, IoT Hub verifies that the file was uploaded correctly, and then adds a file upload notification to the new service-facing file notification messaging endpoint.
This is probably best shown with a demo, so let’s do that.
We are here in our Powershell script where we can launch the IoT Hub Service Simulator.
We have a new command called "fileupload", and a parameter for the file to upload from the device’s filesystem.
If I run this, you can see that you can upload a file, and the simulator is telling saying "uploading". And that's it, it’s finished.
So how do we handle this scenario?
To show that it is working, let’s use the storage viewer in Visual Studio to look at a file upload container.
You see that the container contains no blobs. So let’s rerun the simulator. And now let’s refresh...and there’s the new files.
There’s the name of a device, North3, and drilling into that, you see we have a file uploaded.
So this is all well and good. We have a file uploaded, but in the real world you’ll need to do something with it. So how do you know the file has been uploaded and where it resides?
Well, one option is to use an Azure function that can be triggered when a new blob is added to the storage account. And that could work, though there are other options. IoT Hub provides a file upload notification endpoint that you can use to get information about the files that have been uploaded.
By using the built in notifications, IoT Hub will return a JSON object for each file that has been uploaded and confirmed by the device. It’ll contain the notification’s create timestamp, the device id, the blob URI and name, and then the last update timestamp, and blob size.
Let’s check out uploading and notifications in the C# SDK.
When it comes to uploading the file, IoT Hub and the SDK make things pretty easy. Notice here this method call to “Upload To Blob Async” accepts a unique filename, and then the file stream.
Notice that there’s no way to specify a storage account or container. That’s because IoT Hub allows you to specify one Storage container. And while it may seem like a limitation, it’s not, because this storage is transient. You should move the file to some form of permanent storage as soon as you can.
What about file notifications in the SDK?
If we go on Visual Studio, I have another project called IoTHubDeviceService. It’s another command line application that works like the other applications.
Notice it has the same structure as the device simulator.
Here we have a command named "handleFileUpload" and if we follow the definition, you can see that we have a ServiceClient object, not a device client object. The service client will allow you to poll for file upload notifications.
Here in this loop we check for notifications, we get a notification we write the info to the console and then complete the message, so it is removed from the queue.
And we create a notification object that we can send to an Azure function that I have developed to log which files are notified.
If you want to use the ServiceClient, and handle notifications for yourself, you could then pass the information that’s returned off to some process to handle moving the file. For example, you could pass the info off to an Azure Function as I’m doing here.
So, if we go to the Function App, you see that we have a function called "HandleFileUploadNotification".
It’s triggered by an HTTP request as you can see under triggers, and it saves the notification as a JSON document on Azure DocumentDb.
Then it sends back an HTTP response.
Looking at the logs window, you can see that the function execution has been traced.
So... if we head over to DocumentDB from the portal, and scroll down to the Query Explorer. We can see our documents by querying for documents where the type equals ‘file upload’. And there are the records, each containing a blob name, a blob URI, and a device id.
Okay, that’s going to wrap up this lesson, so let’s summarize what we’ve covered.
In this lesson we talked about how IoT Hub uses endpoints to communicate with services and devices.
If a message flows from a device to the cloud, you can re-route the message to different service endpoints backed by services such as EventHub and service bus queue and topics.
We also covered file uploads with IoT Hub, using Azure Storage, and getting notifications with the file notifications endpoint.
In the next lesson, we’ll talk about cloud to device communication.
Alright, I’ll see you in the next lesson!
Marco Parenzan is a Research Lead for Microsoft Azure in Cloud Academy. He has been awarded three times as a Microsoft MVP on Microsoft Azure. He is a speaker in major community events in Italy about Azure and .NET development and he is a community lead for 1nn0va, an official Microsoft community in Pordenone, Italy. He has written a book on Azure in 2016. He loves IoT and retrogaming.