© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2023
A. Satapathi, A. MishraDeveloping Cloud-Native Solutions with Microsoft Azure and .NET https://doi.org/10.1007/978-1-4842-9004-0_8

8. Build an IoT Solution with Azure IoT Hub, Azure Functions, and Azure Cosmos DB

Ashirwad Satapathi1   and Abhishek Mishra2
(1)
Gajapati, Odisha, India
(2)
Navi MUmbai, India
 

With the rapid development in technology, we are living in a world full of smart devices. Starting from our smartphones to refrigerators, electronics good have been getting smart each passing day. Almost all devices have the capability to generate information and transmit the same over the Internet directly or via channels of communication. This capability enables us to gather information and insights that were unthinkable a few decades back. With all this progress, the Internet of Things (IoT) market is growing like never before. The impact of IoT in different industries is huge, and many organizations have been investing heavily over the past few years to build IoT solutions for various use cases such as smart manufacturing, smart power grids, and connected vehicles.

The focus of this chapter is to demonstrate how to build an IoT solution using different Azure services. We will explore ways to tap into the power of Azure IoT Hub to register IoT devices and process incoming events from it using Azure Functions by building a real-time health monitoring system. Later in the chapter we’ll see how to persist the data coming from the IoT hub in Azure Cosmos DB. This chapter will give you the skills required to get started on your IoT journey.

Structure

In this chapter, we will explore the following topics:
  • Introduction to IoT

  • What is Azure IoT Hub?

  • What is Azure Cosmos DB?

  • Provision an IoT hub and a Cosmos DB instance

  • Develop a solution using IoT Hub, Azure Function, and Cosmos DB

Objectives

After studying this chapter, you should be able to:
  • Understand the fundamentals of Azure IoT Hub

  • Develop an IoT solution leveraging the power of Microsoft Azure

Introduction to IoT

The Internet of Things refers to a network of devices (“things”) that consist of sensors, software, and/or hardware to connect and share information with other devices or a system over the Internet. Over the past decade, IoT has become one of the most popular and impactful technologies in the 21st century. Its impact can be felt everywhere in the world, as many devices that we use in our day-to-day activities are smart devices. These devices can be anything ranging from a smartphone to a smartwatch. According to a report by IoT Analytics, the number of active IoT devices as of 2021 is around 12.2 billion and is expected to grow to approximately 27 billion by 2025 (https://iot-analytics.com/number-connected-iot-devices/).

What Is Azure IoT?

To build IoT solutions, Microsoft Azure provides a suite of managed cloud services. We can leverage these services to build highly scalable, mission-critical solutions. Some of the key services provided by the Azure IoT suite are Azure IoT Hub, Azure IoT Central, Azure IoT Edge. We can use this set of services to build solutions that are able to gather telemetry data from devices, process that data, and generate insights. This describes the bare minimum that we can do with these services. We can perform a plethora of operations using this set of services. For example, with services like Azure IoT Edge, we can process data at the device level and send alerts, if necessary, without sending the data to the cloud. If we provision devices at scale, we can do it with ease by using services like Azure DPS.

A typical IoT solution consists of three components:

  • Things: Any device that is able to send data to the cloud. Things can be industrial equipment, sensors, home appliances, and a range of other devices.

  • Insights: Refers to the processing of the data collected by IoT devices over time to generate actionable insights by using artificial intelligence (AI).

  • Actions: Refers to steps taken by the system or applications once they get the insights after processing the data generated by the IoT devices. Actions can be anything ranging from sending alerts to initiating a workflow to perform a chain of steps.

For the purpose of this chapter, we are going to use a managed Azure IoT service i.e., Azure IoT hub, Azure Functions, and Azure Cosmos DB. Let’s discuss Azure IoT Hub, Azure Functions, and Cosmos DB briefly in the following sections.

What Is Azure IoT Hub?

Azure IoT Hub is a fully managed cloud service offered by Microsoft Azure to build IoT solutions. It provides various features like device registration, event routing, send device to cloud, and cloud-to-device commands. Azure IoT Hub acts as a message gateway and stores telemetry data generated by the IoT devices until a listener or consumer of these events starts consuming them. Azure IoT Hub has first-class integration support for different Azure services like Azure Stream Analytics, Azure Functions, Azure Logic Apps, Azure Event Grid, and so on. Azure IoT Hub provides a secure mechanism for devices to connect to it by use shared access signature (SAS) tokens or certificates. Azure IoT Hub supports multiple communication protocols like Advanced Message Queuing Protocol (AMQP), MQTT, and HTTPS. Apart from that, IoT Hub provides a rich set of client libraries for different languages to manage devices and services.

In this chapter, we explore ways to provision an IoT Hub instance in the Azure portal and register a device in it.

What Is Azure Functions?

Azure Functions is a part of the Function-as-a-Service (FaaS), serverless offering of Microsoft Azure. With Azure Functions, we can build a variety of applications, ranging from serverless Web APIs to event-driven solutions. Azure Functions provides us with a mechanism to deploy our code as functions that scale on demand. We don’t need to worry about configuring the scaling configurations for our functions because it is handled by the service itself. It is handled internally by a scale controller that looks at the amount of traffic coming to the functions and scales it out as needed. When the number of requests decreases, the scale controller automatically scales down the function instances. If we want to limit the number of instances our functions scale out to, we can also do that.

Azure Functions comes with a rich set of triggers and bindings. Triggers in Azure Functions are simply events that initiate function execution. Some examples of triggers are the HTTP trigger, ServiceBus trigger, and IoT Hub trigger. Bindings provide a way to declaratively connect with other resources. There are two classifications of bindings in Azure Functions: input and output. Input bindings let you read data from resources, while output bindings let you write data into the resources or persist them. Azure Cosmos DB and Azure Blob Storage are a few resources for which input and output bindings are currently available. For the purpose of this chapter, we will be developing an IoT Hub Triggered Azure Function that will use the Cosmos DB output binding.

What Is Azure Cosmos DB?

Azure Cosmos DB is the flagship NoSQL offering of Microsoft Azure. It is a fully managed NoSQL database of Azure. It is the successor of DocumentDB. Cosmos DB provides single-digit millisecond response time, offers enterprise-grade security, and has SLA-backed availability. Since the service is fully managed by Microsoft Azure, we need not worry about the scaling in and scaling out of the services. Cosmos DB also provides a mechanism to take automatic backups periodically.

Cosmos DB provides various APIs such as Core SQL API, MongoDB API, Gremlin API, Cassandra API, and Table API. This allows developers with previous experience with any NoSQL database to leverage their previous experience to work with Cosmos DB. For any green field project, Core SQL API is the recommended API to use for the Cosmos DB instances. Core SQL API enables us to perform query operations using SQL syntaxes. Cosmos DB also offers various client libraries in different languages. It is ideal for any web, mobile, or IoT workloads that need a NoSQL backend along with massive scalability.

With that introduction to Cosmos DB and IoT Hub, let’s have a look at the problem statement that we are trying to solve in this chapter.

Problem Statement

You are working for a fictional company that is working toward building an IoT solution to gather healthcare information from patients and store it in a persistent form of storage. The IoT device is going to collect information like pulse rate and body temperature. This data needs to be collected and stored in persistent storage every second. The leadership team of your company wants to develop a proof of concept (PoC) to build the capability. Since you had previously shown interest in the area of IoT, your manager has asked you to come up with a solution and PoC to solve this problem. Your manager has requested that you design the solution using Azure IoT services (as management is keen to continue their cloud journey with Microsoft Azure) and to build a simulator to send telemetry data for the PoC because the team lacks sufficient budget right now.

Proposed Solution

Now that you have a brief understanding of the problem to solve, we will be working as a team toward designing and developing a solution to complete the requirements of our fictional company. After careful consideration, we have come up with a solution to solve the problem. We plan to use Azure IoT Hub to receive telemetry data and manage our IoT devices. Once the telemetry events (i.e., data) are sent from the IoT devices, they lie dormant in the IoT hub. We need to have a way to process these events. We have decided to use Azure Function for processing these events from Azure IoT Hub. This Azure Function is going to process the events and store the data in a Cosmos DB instance.

Since we don’t have an IoT device with us, we have decided to build a console application that is going to acts as a virtual IoT device.

Before we start building the solution, we need a couple of things in place. The following are the prerequisites to start development activities:
  1. 1.

    Create an Azure IoT Hub instance

     
  2. 2.

    Register an IoT device in the Azure IoT hub

     
  3. 3.

    Create a Cosmos DB instance

     

Once we have the prerequisites in place, we will start building our solution using Visual Studio 2022.

Create an Azure IoT Hub in Azure Portal

Go to the Azure portal and search for IoT Hub. Click IoT Hub in the results as shown in Figure 8-1.
Figure 8-1

Search for IoT Hub

Click Create to create an Azure IoT hub, as shown in Figure 8-2.
Figure 8-2

Click Create

Provide the resource group, subscription, IoT hub name, and region in the corresponding fields, as shown in Figure 8-3, and then click Next: Networking. The IoT hub name needs to be globally unique.
Figure 8-3

Click Next: Networking

Select Public access as the connectivity configuration and click Next: Management as shown in Figure 8-4.
Figure 8-4

Click on Next: Management

In the Pricing and scale tier field, select F1: Free tier and click Review + create as shown in Figure 8-5. For the purpose of this chapter, we used the F1 tier, but for a production workload, choosing a higher tier is recommended. And we can only have one IoT hub with the F1 tier in a subscription.
Figure 8-5

Click Review + create

Figure 8-6 shows a summary of all the configuration details entered in the previous screen. A validation will be done for the same. Once the validation is successful, click Create.
Figure 8-6

Click Create

Once the resource is provisioned, click Go to resource as shown in Figure 8-7.
Figure 8-7

Click Go to resource

Now, we need to get the endpoint and Event Hub–compatible name of the provisioned IoT hub. This information will be required by our Azure Function to subscribe for messages coming to the IoT hub. You might be confused about why we are talking about getting the Event Hub–compatible name while we are dealing with the IoT hub in our scenario. The reason is that the IoT hub is built on top of Event Hub. To get the required information, click the Built-in endpoints option in the Hub setting section of our IoT hub resource, as shown in Figure 8-8. From there, we need to take the event hub-compatible name and event hub-compatible endpoint.
Figure 8-8

Click Built-in endpoints

Now that we have provisioned the IoT hub and copied the necessary details, we will explore ways to register a device in IoT Hub.

Register an IoT Device to IoT Hub in Azure Portal

For any device to be able send telemetry data or events to an IoT hub, it needs to be registered with that IoT hub. Unless your device is registered with the IoT hub, it can’t send or receive any events or commands to or from the IoT hub. To register a device with the IoT hub, go to the Devices options present under the Device management section of the IoT hub and click + Add Device as shown in Figure 8-9.
Figure 8-9

Click +Add Device

In the next screen, shown in Figure 8-10, enter the device ID in the Device ID field, select Symmetric key in the Authentication type field, check the Auto-generate keys check box, select Enable for Connect this device to an IoT hub, and click Save.
Figure 8-10

Click Save

Now this device is going to get registered with our IoT hub, as shown in Figure 8-11. As we have registered the device, we need to collect the connection string for the device to use it in our console application, which will work as our virtual IoT device. To get this connection string, click the newly created device under Device ID.
Figure 8-11

Click the device

We need to get the primary connection string for this page for later use in the chapter, so copy the value in the Primary Connection String field as shown in Figure 8-12.
Figure 8-12

Get the primary connection string

We will use this primary connection string in our console event to send telemetry events to the IoT hub. In the next section, we are going to look into ways to provision a Cosmos DB instance.

Create an Azure Cosmos DB Instance in Azure Portal

Go to the Azure portal and search for Azure Cosmos DB. Click Azure Cosmos DB in the search results as shown in Figure 8-13.
Figure 8-13

Click Azure Cosmos DB

Click Create to create an Azure Cosmos DB instance, as shown in Figure 8-14.
Figure 8-14

Click Create

Select Core (SQL) as the API, as shown in Figure 8-15, and then click Create.
Figure 8-15

Select Core (SQL) API

We need to select the Subscription and Resource Group and then provide the account name, location and capacity mode in the corresponding fields as shown in Figure 8-16. Go ahead with the default options here. Once you have entered the required information, click Review + create.
Figure 8-16

Click on Review + create

Figure 8-17 shows a summary of all the configuration selected for this resource in the previous screen. A validation will be done. Once the validation is successful, click Create.
Figure 8-17

Click Create

Once the resource has been provisioned, click Go to resource as shown in Figure 8-18.
Figure 8-18

Click Go to resource

Now that we have provisioned our Cosmos DB instance, we have to create a Cosmos database and Cosmos container to store the data generated by our IoT device. A container is equivalent to a table in a relational database management system (RDMS). To create a container, click Data Explorer and then click New Container as shown in Figure 8-19.
Figure 8-19

Click Data Explorer

Next, provide the database name, database throughput, database max RU, container name, and partition key (see Figure 8-20). Once provided, click OK to provision your container.
Figure 8-20

Click OK

We can view the newly created container in the Data Explorer as shown in Figure 8-21.
Figure 8-21

Container was created

Now that we have created all the resources, we have to collect the connection string of our cosmos db to interact with it. To do so, go to the Keys section of the cosmos db resource, as shown in Figure 8-22, and copy the primary connection string.
Figure 8-22

Copy primary connection string

Create a Console App to Act As a Virtual IoT Device

Now that we have covered the business requirement, let’s start building our virtual IoT device by using the Console App Template. Open Visual Studio 2022 and click Create a new project. Select the Console App template and click Next.

In the Configure your new project window, enter the project name, location, and solution name in the corresponding fields and then click Next.

In the Additional information window, choose your target framework and select the Do not use top level-statements check box. Once you have provided all the information, click Create. Visual Studio creates a console app with the configuration that you entered.

The first thing that we have to do here is install the Device SDK of Azure IoT hub and Netwonsoft.Json NuGet package. To do this, open the Package Manager Console and type the following:
Install-Package Microsoft.Azure.Devices.Client -Version 1.41.2
Install-Package Newtonsoft.Json
Next, create a new class called HealthModel.cs and enter the following code. This class is going to represent the telemetry data that will be sent by our device to the IoT hub.
public class HealthModel
{
        public string Id { get; set; }
        public int PluseRate { get; set; }
        public int Temprature { get; set; }
        public DateTime RecordedAt { get; set; }
}
Now replace the program.cs class with the following code. This code generates a randomly generated pulse rate and temperature values using the GetRandomNumberInRange method and uses it construct the HealthModel object. This model is then serialized and sent to the IoT hub using the SendEventAsync method of the DeviceClient instance. The DeviceClient is created using the connection string that we had previously collected for the registered device.
public class Program
{
    private static DeviceClient deviceClient;
    private readonly static string connectionString = "<enter your device connection string>";
    static void Main(string[] args)
    {
        Console.WriteLine("Sending Messages");
        Task.Delay(10000).Wait();
        deviceClient = DeviceClient.CreateFromConnectionString(connectionString, TransportType.Mqtt);
        int i = 0;
        bool result;
        //sends sensor data from the device simulator every second for 10 minutes
        while (i < 1)
        {
            Task.Delay(6000).Wait();
            result = SendMessages(deviceClient);
            if (result)
            {
                Console.WriteLine($"Message {i} delivered");
            }
            else
            {
                Console.WriteLine("Message failed");
            }
            i++;
        }
    }
    /// <summary>
    /// Method to send data from the device simulator to IoT Hub
    /// </summary>
    /// <param name="deviceClient"></param>
    /// <returns></returns>
    public static bool SendMessages(DeviceClient deviceClient)
    {
        var sensorData = new HealthModel()
        {
            Id = Guid.NewGuid().ToString(),
            PluseRate = GetRandomNumberInRange(90, 110),
            RecordedAt = DateTime.UtcNow,
            Temprature = GetRandomNumberInRange(90, 110)
        };
        var jsonData = JsonConvert.SerializeObject(sensorData);
        try
        {
            var data = new Message(Encoding.ASCII.GetBytes(jsonData));
            deviceClient.SendEventAsync(data).GetAwaiter().GetResult();
            //Console.WriteLine("Message Sent");
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error Info - {ex.Message}");
            return false;
        }
    }
    /// <summary>
    /// Method to generate random value to mock the Soil Moisture level values
    /// </summary>
    /// <param name="minNumber"></param>
    /// <param name="maxNumber"></param>
    /// <returns></returns>
    public static int GetRandomNumberInRange(int minNumber, int maxNumber)
    {
        return new Random().Next(minNumber,maxNumber);
    }
}

Now we will have to run our program and it will send one message to the IoT hub. Once the message is sent, you can view that the field with the number of messages used today will have changed in the usage section of the overview page of your IoT hub. You can find the source code for our virtual IoT device at https://github.com/AshirwadSatapathi/MyVirtualIoTDevice.

Create an IoT Hub Triggered Azure Function to Store Data in Cosmos DB

Now that we have our virtual IoT device up and running, it is capable of sending messages to the IoT hub. Next, we need to build the function that is going to process the message and store it in Cosmos DB.

Before we start creating our function project, make sure that you have installed the Azure development workload for your workload. If you have not done so, you can open Visual Studio Installer and install it.

Now, Open Visual Studio 2022 and click Create a new project. Select the Azure Function template and click Next.

In the Configure your new project window, enter your project name, location, and solution name and then click Next.

In the Additional information section, select the Function worker as .NET 6 LTS, select the Function type as IoT Hub trigger, enter the connection string setting name as the key name where you will store the IoT hub endpoint that we have gathered earlier, and provide the path. The path is the Event Hub–compatible name. Once you have entered all the information, click Next. This will generate an IoT hub triggered function out of the box.

Now open the Package Manager Console and type the following command to install the NuGet package for the Cosmos DB extension and Newtonsoft.Json. We need to install the Cosmos DB extension because we want to use cosmos db output binding for azure function.
Install-Package Microsoft.Azure.WebJobs.Extensions.CosmosDB
Install-Package Newtonsoft.Json

Open the local.settings.json file and add the IoT hub connection string and the Cosmos DB connection for the keys iotHubConn and dbConn, respectively. While storing the IoT hub connection string, make sure that you remove the entity path section from the Event Hub–compatible endpoint.

Next, create the HealthModel class that we had created for our Virtual IoT device earlier.

Replace the Function1 class with the following code. This function listens to the messages coming to the Azure IoT hub and consumes them, thanks to the IoT hub trigger, and later gets the deserializes the message to the HealthModel type. Finally, it uses the cosmos Db output binding to write the data to our cosmos db container that we had provisioned earlier.
public class Function1
{
    private static HttpClient client = new HttpClient();
    [FunctionName("IoTHubEventProcessor")]
    public void Run(
        [IoTHubTrigger("<event hub compatible name>", Connection = "iotHubConn")]string message,
        [CosmosDB(
            databaseName:"<database name>",
            collectionName:"<container name>",
            ConnectionStringSetting ="dbConn"
        )] IAsyncCollector<dynamic> documentsOut,
        ILogger log)
    {
        log.LogInformation($"C# IoT Hub trigger function processed a message: {message}");
        HealthModel data = JsonConvert.DeserializeObject<HealthModel>(message);
        documentsOut.AddAsync(
            new
            {
                id = data.Id,
                pulseRate = data.PluseRate,
                temprature = data.Temprature,
                recordedAt = data.RecordedAt
            }
            ).Wait();
    }
}
As Figure 8-23 shows, our function was able to process the messages sent by our virtual IoT device to the IoT hub.
Figure 8-23

IoTHubEventProcessor process the events

We can now go to the cosmos db container to check if the data was written there or not. As can be confirmed from Figure 8-24, our function was able to write the data in cosmos db.
Figure 8-24

View the data in cosmos db container

You might observe there are few additional keys present in the record. These are auto-generated by Cosmos DB for each document and we should not be worried about it. And with this, we have built our proof of concept for the IoT solutions. You can find the source code at https://github.com/AshirwadSatapathi/IoTHubEventProcessor.

Summary

The world of IoT is an interesting and is rapidly evolving. To enable customers to tap into the full potential of IoT, Microsoft Azure provides a suite of IoT services. We have briefly explored one of the key IoT services offered by Azure, IoT Hub. We examined ways to build an IoT solution using Azure IoT Hub, Cosmos DB, and Azure Functions. While also explored ways to provision an IoT Hub instance in the Azure portal and ways to register an IoT device. The sheer amount of scope that these IoT service let’s us is immense. As one example, we could build solutions focused on agriculture, a potential use case being smart irrigation. There are many such use cases. We only touched the tip of the iceberg in this chapter, but you can leverage what you have learned to build wonderful solutions.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset