Device Administration Using Azure IoT Hub

|  Posted: April 7, 2017  |  Categories: Microsoft Azure

Azure IoT Hub allows us to communicate with billions of devices in an easy and secure manner. Built on proven Azure technologies like Service Bus and Event Hubs, IoT Hub helps us to authenticate, administrate and communicate with our devices running on various platforms and using diverse protocols.

In a series of blog posts we will see how we can leverage the power of Azure IoT Hub in this ever growing world called the Internet of Things. It will become clear how we can send our data into Azure, process it and visualize our data, as well as how we can communicate back to our devices securely. And of course, we will learn all about how we can administer all these devices remotely, and monitor them proactively to ensure maximum continuancy. In this first blog post in my IoT Hub series we will see how we can do the administration of our devices.

Scenario

For this blog post series, we will be using a scenario where we manage engines on ships. Each ship can have multiple engines from various manufacturers, sending out readings like temperature, RPM, warnings, etc. We will want to capture all this data, to make sure our engines are running optimally, and we get an early warning in case of upcoming maintenance or repairs. As these ships will often be hard to reach, being able to administrate them remotely can save a lot of time and effort, allowing our engineers to plan their activities as efficient as possible.

Ship's Engine Room

Setting up IoT Hub

To start, open the Azure Portal, go to the IoT Hub blade, and add a new IoT Hub.

IoT Hub Administration - Create IoT Hub

 

Set the options for your IoT Hub. You can have one free IoT Hub per subscription, which is ideal for testing and demo purposes, but do keep in mind you won’t be able to switch between the free and paid version.

IoT Hub Administration - Set IoT Hub Settings

 

Click Create to start deploying your IoT Hub to your subscription.

Administration Application

Now that we have created our IoT Hub, we will need to manage our devices. This can be done partly from the portal, but we will opt to create an application for this instead, which will be used by our backend team to manage our devices. We will create a simple Windows Forms application for this.

IoT Hub Administration - Create Windows Forms Project

 

Register Device

Create a simple application as the following, which will allow us to register a new engine. Later on, we will expand on this application.

Set Up Application

 

Now that we have our basic application layout setup, we will add the actual interaction with IoT Hub. For this we will need to add the Microsoft.Azure.Devices NuGet package to our solution. This package will allow us to communicate with IoT Hub and manage our devices.

Add NuGet package

 

To connect to our IoT Hub, we will need to get the connection string from the Azure portal.

Get Connection String

 

We will now use this connection string to create a RegistryManager with which we can manage our devices in IoT Hub.

private readonly RegistryManager registry = RegistryManager.CreateFromConnectionString("HostName=youriothubname.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=yoursharedaccesskey");

And to actually register a new device, we will add the following EventHandler to our Register button.

private async void ButtonRegister_Click(object sender, System.EventArgs e)
{
    await registry.AddDeviceAsync(new Device(comboBoxSerialNumber.Text));
}

Set Device Tags

This will create a device twin in our IoT Hub, a virtual representation of our device. Now the beauty of these device twins, is that we can add custom tags to them, which we can then use to query on our devices. For example, on a single ship you can have multiple engines of different manufacturers, e.g. a main engine of MAK, two generators of Caterpillar, and a pump engine of ABC. Using device twins, we could send a message to all engines made by Caterpillar, or to all generators. Let’s expand our application to set these tags as well. To do this, change the form of our application as following.

Incude Engine Properties

 

Adjust the EventHandler for our Register button to include these tags on our device twin. This is done by applying a patch on the device twin with the properties we want to set.

private async void ButtonRegister_Click(object sender, System.EventArgs e)
{
     var deviceTwin = await registry.GetTwinAsync(comboBoxSerialNumber.Text);

     if (deviceTwin == null)
     {
         await registry.AddDeviceAsync(new Device(comboBoxSerialNumber.Text));

         deviceTwin = await registry.GetTwinAsync(comboBoxSerialNumber.Text);
     }

    var patch = new
    {
        tags = new
        {
            engineType = comboBoxEngineType.Text,
            manufacturer = textBoxManufacturer.Text
        }
    };

    await registry.UpdateTwinAsync(comboBoxSerialNumber.Text, JsonConvert.SerializeObject(patch), deviceTwin.ETag);
}

Set Desired Properties

Another great thing about IoT Hub’s device twins, is that we can remotely configure devices by using Reported properties and Desired properties. Reported properties are properties which are set by the device and reported back to IoT Hub, where desired properties are properties set in IoT Hub (by our backend, in this case the Engine Management application), and will be propagated to our devices. By using desired properties, we can update settings on our device, even when the device is not currently online. When the device comes online, it will retrieve the desired properties, and update its settings accordingly. We can then be notified on our device of these changes, and execute code accordingly. We will once again start by updating our application’s form, this time to allow us to set the temperature at which the device will create an alert.

Include Maximum Temperature

 

We will expand the patch in our EventHandler for the Register button to include maximum temperature in a desired property.

private async void ButtonRegister_Click(object sender, System.EventArgs e)
{
    var deviceTwin = await registry.GetTwinAsync(comboBoxSerialNumber.Text);

    if (deviceTwin == null)
    {
        await registry.AddDeviceAsync(new Device(comboBoxSerialNumber.Text));
	
        deviceTwin = await registry.GetTwinAsync(comboBoxSerialNumber.Text);
    }

    var patch = new
    {
        properties = new
        {
            desired = new
            {
                temperatureConfig = new {
                    configId = Guid.NewGuid(),
                    maximumTemperature = numericUpDownMaximumTemperature.Value
                }
            }
        },
        tags = new
        {
            engineType = comboBoxEngineType.Text,
            manufacturer = textBoxManufacturer.Text
        }
    };

    await registry.UpdateTwinAsync(comboBoxSerialNumber.Text, JsonConvert.SerializeObject(patch), deviceTwin.ETag);
}

Get Registered Devices

Now that we can register our device, including setting the tags and properties, let’s see how we can retrieve registered devices from our IoT Hub. For each registered device, we will also want to know the key to be used when connecting our device to IoT Hub, and if the device is currently online, so firstly let’s adjust the application’s form to the following.

Add Device Key And Status

 

To easily work with the retrieved devices, we will create an object on which we can project them.

internal class Engine
{
    internal string SerialNumber { get; set; }
    internal string Manufacturer { get; set; }
    internal string EngineType { get; set; }
    internal string MaximumTemperature { get; set; }
    internal string DeviceKey { get; set; }
    internal bool IsOnline { get; set; }

    public override string ToString()
    {
        return SerialNumber;
    }	
}

Add a method to query our IoT Hub for all devices. Make sure to call this method from the constructor, as well as after adding / updating a device using the Register button.

private async void GetRegisteredEngines()
{
    comboBoxSerialNumber.Items.Clear();

    var registeredEngines = await registry.GetDevicesAsync(500);

    foreach(var engine in registeredEngines)
    {
        var deviceTwin = await registry.GetTwinAsync(engine.Id);

        var tags = deviceTwin.Tags;
        va0072 desiredProperties = deviceTwin.Properties.Desired;

        comboBoxSerialNumber.Items.Add(new Engine
        {
            SerialNumber = engine.Id,
            Manufacturer = tags["manufacturer"],
            EngineType = tags["engineType"],
            MaximumTemperature = desiredProperties["temperatureConfig"]["maximumTemperature"],
            DeviceKey = engine.Authentication.SymmetricKey.PrimaryKey,
            IsOnline = engine.ConnectionState == DeviceConnectionState.Connected
        });
    }
}

Unregister Device

Now that we can create, update and retrieve our devices, we should also be able to delete them from our IoT Hub registry. This can be needed when a device is being decommissioned, or because the device is compromised. Let’s update the application form to make this possible.

Add Unregister Button

 

Next we will add the following EventHandler to the Unregister button.

private async void ButtonUnregister_Click(object sender, EventArgs e)
{
    await registry.RemoveDeviceAsync(comboBoxSerialNumber.Text);

    GetRegisteredEngines();
}

Simulated Device

For this series of blogposts, we will use a simulated device. This will be a console app, which represents one of the engines on a ship. Start by creating a console application.

Create Simulated Engine Application

 

To communicate with IoT Hub, we will need to install the Microsoft.Azure.Devices.Client NuGet package.

Install NuGet Package

 

In our console application, we will create a DeviceClient which will be used to communicate with IoT Hub. The DeviceID is the serial number of the engine, and the device key we can get in the administration application after registering the engine in IoT Hub.

private static DeviceClient client = DeviceClient.Create("youriothubname.azure-devices.net", new DeviceAuthenticationWithRegistrySymmetricKey("yourdeviceid", "yourdevicekey"), TransportType.Mqtt);

Get Desired Properties

On startup of the application, we will retrieve the maximum temperature for our device from the desired properties.

private static async void GetMaximumTemperature()
{
    var deviceTwin = await client.GetTwinAsync();
    MaximumTemperature = deviceTwin.Properties.Desired["temperatureConfig"]["maximumTemperature"];
}

Handle Updated Desired Properties

As the maximum temperature can be changed from the administration application while the device is running, we should also implement a listener for changes on the desired properties. To do this, add the following code to the Main method.

client.SetDesiredPropertyUpdateCallback(DesiredPropertyUpdated, null);

And add the following callback method.

private static Task DesiredPropertyUpdated(TwinCollection desiredProperties, object userContext)
{
    MaximumTemperature = desiredProperties["temperatureConfig"]["maximumTemperature"];
    return null;
}

Conclusion

In this post, we have created an application we can use to administer our devices in IoT Hub, and update the settings of the device. Our simulated device uses the settings we have set, and updates it’s configuration when they get changed. The complete code for this post can be found here.

IoT Hub Blog Series

In case you missed the other articles from this IoT Hub series, take a look here.

Blog 1: Device Administration Using Azure IoT Hub
Blog 2: Implementing Device To Cloud Messaging Using IoT Hub
Blog 3: Using IoT Hub for Cloud to Device Messaging

Author: Eldert Grootenboer

Eldert is a Microsoft Integration Architect and Azure MVP from the Netherlands, currently working at Motion10, mainly focused on IoT and BizTalk Server and Azure integration. He comes from a .NET background, and has been in the IT since 2006. He has been working with BizTalk since 2010 and since then has expanded into Azure and surrounding technologies as well. Eldert loves working in integration projects, as each project brings new challenges and there is always something new to learn. In his spare time Eldert likes to be active in the integration community and get his hands dirty on new technologies. He can be found on Twitter at @egrootenboer and has a blog at http://blog.eldert.net/.

One Platform Operations, Monitoring and Analytics Software
BizTalk360

microsoft biztalk

Learn more

Over 500 customers across 30+ countries depend on BizTalk360

ServiceBus360

Azure service bus

Learn more

Start managing your Azure Service Bus namespaces in minutes

One Platform - Operations, Monitoring and Analytics Software
BizTalk360

microsoft biztalk

Learn more

Over 500 customers across 30+ countries depend on BizTalk360

One Platform - Operations, Monitoring and Analytics Software
ServiceBus360

Azure service bus

Learn more

Start managing your Azure Service Bus namespaces in minutes

Back to Top