Windows IoT Core and Azure IoT Hub – Putting the ‘I’ in IoT

Earlier this year, we announced the availability of Windows IoT Core – a new edition of Windows designed for maker boards and small devices. We’ve been busy the past few months continuing to make improvements to the platform, with the goal of making Windows IoT Core the best platform for IoT developers and makers.

Of course, we’re far from done. One challenge that we hear from the maker community is the ability to quickly and easily connect to the cloud. Certainly, we’ve seen it done, but it required jumping through a number of hoops. When you’re a maker, added tasks detract from your ultimate goal. You already have multiple priorities competing for your time, energy and attention: Connecting to the cloud shouldn’t be any harder than lighting up an LED.

Fortunately, connecting your IoT device to the cloud has just become easier than ever. The process is straightforward, and best of all, is free for makers.

Azure IoT Hub

Azure IoT Hub is a Microsoft Azure cloud service that offers reliable and secure device-to-cloud and cloud-to-device messaging that scales to millions of devices. Yet getting started is simple, with a streamlined programming model and platforms and protocols you already know. With Azure IoT Hub, makers can get started with minimum effort and scale up your solution as its needs grow, without having to rewrite it or rework what you’ve already built.

Getting started

First, to deploy applications on Windows IoT Core, you’ll need to have Microsoft Visual Studio 2015 (or download the free Community edition here). You’ll also need an active Azure subscription (you can start with a free trial subscription), and then choose a free version of the Azure IoT Hub service.

To set up an instance of the IoT Hub, log on to the Azure Portal and click “New” on the jumpbar on the left, then “Internet of Things,” then “IoT Hub.” (The process is straightforward, but if you want additional pointers, there are great tips in this article). Be sure to choose “F1 –Free” pricing and scale tier. The free option provides one IoT Hub per subscription, which includes 10 devices and 3000 messages per day.

Creating a device ID

Once you’ve set up your instance of IoT Hub, the first thing you need is to create the identity for your device. Every device must have a key that uniquely identifies it to the service. This way the IoT Hub can securely associate the data with the device that sent it.

To create a device ID, use a tool called ‘iothub-explorer’. The tool requires Node.js, so make sure it’s installed on your machine (or get it here).

Now open the command line prompt and install the iothub-explorer package:

npm install -g iothub-explorer@latest

The tool will need the connection string to connect to your instance of the Azure IoT Hub. You can find the connection string in the Azure Portal under the settings tab of your IoT Hub instance: navigate to Settings | Shared access policies | Connection string – primary key.

Now create a new device called ‘MyDevice’. Run the tool as follows:

iothub-explorer <yourConnectionString> create MyDevice

Remember to use your actual connection string in the above command. The tool will create the new device ID and output the primary key for the device, among other things. The primary key is what you’ll use to connect your device to the IoT Hub.

The tool also allows you to list and delete existing devices, as well as listen to the messages coming into the IoT Hub. It might be worth taking a few minutes to explore the tool. Type ‘iothub-explorer help’ to learn about the other commands.

Hello, Cloud!

You will use the Microsoft.Azure.Devices.Client library to connect to Azure, so go ahead and install it from the NuGet gallery. (And if you’re curious to know what’s in this library, you can check it out on GitHub here). Please note that you will use the UI NuGet and not the command-line. To do this, you’ll need to right click on “References” in the Solution Explorer, then click on “Manage NuGet Packages.”

For this example, you’ll want to add a reference to the Windows IoT Extensions for the UWP. Add these using directives at the top of the MainPage.xaml.cs file:

using System.Text;
using Microsoft.Azure.Devices.Client;

Next, in the generated project, add the following function to the MainPage class in the MainPage.xaml.cs file:

A few things need to be adjusted in the above code before you can run this app. The iotHubUri needs to be set to the Uri of your IoT Hub, the value of which you can find under the Settings tab. (This should look like your_hub_name.azure-devices.net). The deviceId and deviceKey were created earlier by the CreateDeviceIdentity tool – remember to replace them as well.

Run the app on your IoT device (if you need instructions on how to set up your device, see here) and – voila! – your data has been sent to the cloud.

Processing data in the cloud

Sending data to the cloud is only meaningful if something useful can be done with the data once it gets there. There are many ways to process data in Microsoft Azure – you can connect it to other services such as Azure Stream Analytics, store it into an Azure Blob, visualize it in PowerBI etc.

One simple example is to write an app that retrieves messages sent to the IoT Hub and displays them in a console window – not too fancy, but you can imagine doing something more interesting, such as triggering an alert or sending a command back to the device.

Create a console application in Visual Studio 2015 named ‘ReadDeviceToCloudMessages’. Add the WindowsAzure.ServiceBus library from the NuGet gallery and replace the generated Program.cs with the following code:

As before, replace the connection string with the actual connection string for your IoT Hub instance.

When you compile and run the application, it will start listening for the messages sent to the IoT Hub. To make sure it works, re-run the HelloCloud UWP application that you built before. You should see the following output coming from the ReadDeviceToCloudMessages:

Message received: ‘Hello, Cloud!’

What’s next

You can find the basic example explored here, as well as more advanced samples, on GitHub: https://github.com/ms-iot/samples. The Azure-specific examples are located in the Azure subfolder.

In the next installment of this blog series, we’ll look into more advanced ways of processing data in the cloud, as well as sending data from the cloud back to the device.

This is neither the beginning nor the end of the journey to make cloud connectivity easy and accessible. Your feedback helps us determine what we should do next, and how we prioritize our work. Please add your comments below – we look forward to hearing from you!

Post written by Artur Laksberg, a principal software engineer in Windows

Join the conversation

The link to VS2015 Community is incorrect in this blog entry. (And for some reason after logging into this site it still gives me a generic user name. Oh well.)
I’m just starting to wrap my head around what IoT means to us in these early stages, and looking forward to getting in on it soon. During this information gathering process, as with all products and technologies, we developers are being bombarded with competitive “do it our way!”. It’s browser wars all over again and we’re going to need bridges like jQuery to reduce the pain. It’s yet another example of Apple vs Android vs Windows Phone, where Xamarin serves as the bridge. In a rush to establish “standards” there is already strong competition, led by alliances of huge influential companies. *sigh* Here we go again. I’ll just ask that this time I’m hoping for closer coordination among the standards developers. We don’t care if you think your way is better. We just need to create products that work, and that could mean supporting multiple standards. Sure, just a few is better than dozens (like with JavaScript frameworks). But it doesn’t make sense to create end-to-end platforms to abstract out the difficulties of IoT if in the process entirely new difficulties are created. Let’s learn from the past and try to address this up-front rather than waiting for some third-party to do something later after we’ve already spent years trying to create cross-IoT-protocol interfaces. Microsoft – if you lead in that direction (compared to the position held with Internet Explorer vs the world) then you might get a lot more community goodwill than in the past. Thanks.

Installation of iothub-explorer requires python 2.X to be installed. And it still fails to install on my machine complaining about a too long path while building. My machine is an Azure W10 VM from the gallery with VS2015 Community with Universal Apps and Azure SDK (provided by MS).

@Windows LiveUser820: Windows 7 should work. Can you share the call stack and/or details of the exception (in particular, properties Detail and InnerException of the MessagingException)? You can also reach me directly at arturl at Microsoft dot com.

Great post.
I have an issue with the ‘ReadDeviceToCloudMessages’ Console Application in Visual C# 2015 Update 1 that retrieve data from the Azure IoT Hub. When I build the application I have a warning message because the ‘ReceiveMessagesFromDeviceAsync(receiver)’ call is not awaited.
Nevertheless if I run the application, the console application open but none message are retrieved from the Azure Iot Hub with an exception as ‘ConfigurationErrorsException’ because the Service Bus connection string is not of the expected format. The connection string I am using has the following format: “.azure-devices.net” with , the name I gave to the IoT Hub I choose.
Do you know what I am missing?
Thank you and Happy New year 2016.

@Windows LiveUser826: I think that you are using the hostname insteasd of the connection string. The connection string should be in the format of Hostname=xxx.azure-devices.net; SharedAccessKeyName=iothubowner;SharedAccessKey=xxxxxxxxxxxxxxxxxx; Check that you are using the correct connection string by checking your hub in the azure portal.

Thank you, no anymore exception but I do not have any output message on the console application. I see on my hub in the Azure portal that I have a message after running the HelloCloud UWP application but I cannot retrieve it on the console application.
Debugging the console application the partition string remains a “0” in the foreach loop. Is that expected?
Thank you.

I know this may be the wrong place, but I’m desperatly seeking an answer. Maybe you guys can tell med how to call Azure ServiceBus from a UWP app in general and not an IoT app.
The WindowsAzure.ServiceBus nuget library only support the full .net library. What to use from UWP?

Hi Artur,
Nice post!
Do you know if there’s any way to setup an IoT Hub proxy?
By that I mean, let’s say you have a device X that has no connectivity to the internet, but it could occasionally connect to a device Y which does occasionally have connectivity to the internet.
In other words, you want device X to send messages to device Y and let this guy buffer them and relay them when possible.
Make sense?
Rene

Hi Rene,
I think you’re talking about the IoT Gateway (at least this is how we call it here). We’re looking into it but nothing to announce at this point. Do you want to take it offline with me — I’m interested in understanding your requirements (arturl at microsoft dot com)

I got the demo working but several things need clarification IMHO: There are three access keys involved, one for accessing the iothubowner for which the connection string is needed in HelloCloud, but to write to MyDevice the device’s access key is needed, and I do not know how to find it. I happened to do a screen save when doing iothub-explorer device create, which showed the access key in the cmd window output. The third access key is the service connect key shown on Azure IoT portal for service, which is needed in console app ReadDeviceToCloudMessages. When completed and run, nothing was reported by
ReadDevice, but I ran the two programs concurrently and voila: A bit of output! Great demo – there is a lot going on below the covers in this application. Note also: copying the access keys from the portal results in spaces, which must be removed from the key.

Good evening. I’m working on a project now to enable communication between a website and a UWP Raspberry Pi Windows 10 IoT instance. I’m able to send messages from the Raspberry Pi and website without issue but I’m not able to receive messages on the Raspberry Pi. I can through the console app but the ReceiveAsync Message is always null on the Rapsberry Pi. There are a lot of examples receiving messages from a console app, but not the UWP. Below is my code. Any ideas? Thanks in advance.

Kevin,
Your sample looks right, but I suspect your requests are being throttled by the server. Try to add a delay (say, 10 seconds) to your loop to avoid overly frequent requests.
This is a limitation of the HTTP protocol — essentially it requires polling the server to receive cloud-to-device messages. This will be resolved once we add support for AMQP and other protocols for the UWP version of the library.

While trying to emulate the example, I ran into a teething problem with the call to Device.Client failing with the following error message:
“An exception of type ‘System.ArgumentException’ occurred in Microsoft.Azure.Devices.Client.winmd but was not handled in user code
Additional information: Key must be base64 encoded”

Thanks again, Kevin. I had one spurious character in the device key. After replacing the device key with the data from Device Explorer, everything ran fine. Appreciate the guidance on the support tools.

util.js:556
ctor.prototype = Object.create(superCtor.prototype, {
^
TypeError: Object prototype may only be an Object or null
at Function.create (native)
at Object.exports.inherits (util.js:556:27)
at Object. (C:\Users\esharapov\AppData\Roaming\npm\node_modules\iothub-explorer\node_modules\azure-iothub\node_modules\azure-iot-amqp-base\lib\amqp_receiver.js:43:6)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object. (C:\Users\esharapov\AppData\Roaming\npm\node_modules\iothub-explorer\node_modules\azure-iothub\node_modules\azure-iot-amqp-base\lib\amqp.js:8:20)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)

Step 2) If you did Step1 and keep errors arise, you should check
‘App.config’ file of ‘ReadDeviceToCloudMessages’ Project.
App.config has variables for Iot hub authentication also,
So you should do Step1 for App.config file’s’ part too.
(This article doesn’t have any mention for this…..)

Total Noob here so please forgive the ignorance, I put the example in as shown above, I literally copied and pasted. I get the following error:

Unhandled Exception: System.ArgumentException: Some of the configuration is missing a required component. Make sure all or none of the following properties are defined as part of ‘Microsoft.ServiceBus.ConnectionString’ key within ‘appSettings’ section, or Windows Azure configuration settings: [SharedAccessKeyName,SharedAccessKey]
Parameter name: connectionString —> System.Configuration.ConfigurationErrorsException: Some of the configuration is missing a required component. Make sure all or none of the following properties are defined as part of ‘Microsoft.ServiceBus.ConnectionString’ key within ‘appSettings’ section, or Windows Azure configuration settings: [SharedAccessKeyName,SharedAccessKey]
at Microsoft.ServiceBus.Messaging.Configuration.KeyValueConfigurationManager.Validate()
at Microsoft.ServiceBus.ServiceBusConnectionStringBuilder.InitializeFromKeyValueManager(KeyValueConfigurationManager manager)
— End of inner exception stack trace —
at Microsoft.ServiceBus.ServiceBusConnectionStringBuilder.InitializeFromKeyValueManager(KeyValueConfigurationManager manager)
at Microsoft.ServiceBus.Messaging.EventHubClient.CreateFromConnectionString(String connectionString, String path)
at Program.Main(String[] args) in c:\users\mreng\onedrive\documents\visual studio 2017\Projects\ReadDeviceToCloudMessages\ReadDeviceToCloudMessages\Program.cs:line 13

I am at a complete loss, the connection string I am using is copied from the azure portal device details page, “Connection String-primary key”. Can someone let me know what I am doing wrong.