IOT

Download as pdf or txt
Download as pdf or txt
You are on page 1of 1341

Table of Contents

Azure IoT Fundamentals


IoT Hub Documentation
Overview
What is Azure IoT Hub?
Quickstarts
Send telemetry (Node.js)
Send telemetry (.NET)
Send telemetry (Java)
Send telemetry (Python)
Send telemetry (iOS)
Control a device (Node.js)
Control a device (.NET)
Control a device (Java)
Control a device (Python)
Tutorials
Routing messages
Configure your devices
Test device connectivity
Send cloud-to-device messages
.NET
Java
Node.js
Python
Get started with device management
Node.js back end/Node.js device
.NET back end/Node.js device
.NET back end/.NET device
Java back end/Java device
Python back end/Python device
Use device jobs to update device firmware
Node back end/Node device
.NET back end/Node.js device
.NET back end/.NET device
Java back end/Java device
Python back end/Python device
Bulk manage IoT devices
Concepts
Overview of device management
Compare IoT Hub and Event Hubs
Choose the right tier
High availability and disaster recovery
Supporting additional protocols
Compare message and event routing
Developer guide
Device-to-cloud feature guide
Cloud-to-device feature guide
Send and receive messages
Upload files from a device
Manage device identities
Control access to IoT Hub
Understand device twins
Invoke direct methods on a device
Schedule jobs on multiple devices
IoT Hub endpoints
Query language
Quotas and throttling
Pricing examples
Device and service SDKs
Develop for constrained devices
Develop for mobile devices
MQTT support
Glossary
Set up your device
Simulate a device on your PC
Use the IoT device SDK for C
Use the IoTHubClient
Use the serializer
Security from the ground up
Security best practices
Security architecture
Secure your IoT deployment
Secure using X.509 CA certificates
X.509 CA certificate security overview
Get started on X.509 CA certificate security
Extended IoT scenarios
Use MXChip IoT DevKit
How-to guides
Plan
Compare IoT Hub and Event Hubs
Choose the right tier
High availability and disaster recovery
Supporting additional protocols
Compare message and event routing
Develop
Developer guide
Use the IoT device SDK for C
Develop for constrained devices
Develop for mobile devices
Query Avro data from a hub route
Send cloud-to-device messages
Get started with device twins
Upload files from devices
Get started with device twins
Get started with module twins
Use direct methods
Get started with device management
How to use twin properties
Use device twins to update device firmware
Schedule and broadcast jobs
Upload files from devices
.NET
Java
Node.js
Python
Create an IoT hub
Use Azure portal
Use Azure PowerShell
Use Azure CLI
Use CLI
Use the REST API
Use a template from Azure PowerShell
Use a template from .NET
Configure file upload
Use Azure portal
Use Azure PowerShell
Use Azure CLI
Monitor with diagnostics
Migrate to diagnostics settings
Operations monitoring
Use real devices
Get started
Use an online simulator
Use a physical device
Upgrade an IoT hub
Usage metrics
Configure IP filtering
Configure devices at scale
Reference
Code samples
Azure CLI
.NET (Service)
.NET (Devices)
Java (Service)
Java (Devices)
Node.js (Devices)
Node.js (Service)
C device SDK
Azure IoT Edge
REST (Resource Provider)
REST (Device Identities)
REST (Device Twins)
REST (Device Messaging)
REST (Jobs)
Related
Solutions
IoT solution accelerators
IoT Central
Platform Services
IoT Hub
IoT Hub Device Provisioning Service
IoT Service SDKs
Maps
Time Series Insights
Edge
IoT Edge
IoT Device SDKs
Resources
Azure Certified for IoT device catalog
Azure Certified for IoT device catalog
Azure IoT Developer Center
Customer data requests
Azure Roadmap
DeviceExplorer tool
iothub-diagnostics tool
iothub-explorer tool
Learning path
MSDN forum
Pricing
Pricing calculator
Service updates
Stack Overflow
Technical case studies
Videos
What is Azure IoT Hub?
5/29/2018 • 3 min to read • Edit Online

IoT Hub is a managed service, hosted in the cloud, that acts as a central message hub for bi-directional
communication between your IoT application and the devices it manages. You can use Azure IoT Hub to build IoT
solutions with reliable and secure communications between millions of IoT devices and a cloud-hosted solution
backend. You can connect virtually any device to IoT Hub.
IoT Hub supports communications both from the device to the cloud and from the cloud to the device. IoT Hub
supports multiple messaging patterns such as device-to-cloud telemetry, file upload from devices, and request-
reply methods to control your devices from the cloud. IoT Hub monitoring helps you maintain the health of your
solution by tracking events such as device creation, device failures, and device connections.
IoT Hub's capabilities help you build scalable, full-featured IoT solutions such as managing industrial equipment
used in manufacturing, tracking valuable assets in healthcare, and monitoring office building usage.

Scale your solution


IoT Hub scales to millions of simultaneously connected devices and millions of events per second to support your
IoT workloads. IoT Hub offers several tiers of service to best fit your scalability needs. Learn more.

Secure your communications


IoT Hub gives you a secure communication channel for your devices to send data.
Per-device authentication enables each device to connect securely to IoT Hub and for each device to be
managed securely.
You have complete control over device access and can control connections at the per-device level.
The IoT Hub Device Provisioning Service automatically provisions devices to the right IoT hub when the device
first boots up.
Multiple authentication types support a variety of device capabilities:
SAS token-based authentication to quickly get started with your IoT solution.
Individual X.509 certificate authentication for secure, standards-based authentication.
X.509 CA authentication for simple, standards-based enrollment.

Route device data


Built-in message routing functionality gives you flexibility to setup automatic rules-based message fan-out:
Use message routing to control where your hub sends device telemetry.
There is no additional cost to route messages to multiple endpoints.
No-code routing rules take the place of custom message dispatcher code.

Integrate with other services


You can integrate IoT Hub with other Azure services to build complete, end-to-end solutions. For example, use:
Azure Event Grid to enable your business to react quickly to critical events in a reliable, scalable, and secure
manner.
Azure Logic Apps to automate business processes.
Azure Machine Learning to add machine learning and AI models to your solution.
Azure Stream Analytics to run real-time analytic computations on the data streaming from your devices.

Configure and control your devices


You can manage your devices connected to IoT Hub with an array of built-in functionality.
Store, synchronize, and query device metadata and state information for all your devices.
Set device state either per-device or based on common characteristics of devices.
Automatically respond to a device-reported state change with message routing integration.

Make your solution highly available


There's a 99.9% Service Level Agreement for IoT Hub. The full Azure SL A explains the guaranteed availability of
Azure as a whole.

Connect your devices


Use the Azure IoT device SDK libraries to build applications that run on your devices and interact with IoT Hub.
Supported platforms include multiple Linux distributions, Windows, and real-time operating systems. Supported
languages include:
C
C#
Java
Python
Node.js.
IoT Hub and the device SDKs support the following protocols for connecting devices:
HTTPS
AMQP
AMQP over WebSockets
MQTT
MQTT over WebSockets
If your solution cannot use the device libraries, devices can use the MQTT v3.1.1, HTTPS 1.1, or AMQP 1.0
protocols to connect natively to your hub.
If your solution cannot use one of the supported protocols, you can extend IoT Hub to support custom protocols:
Use Azure IoT Edge to create a field gateway to perform protocol translation on the edge.
Customize the Azure IoT protocol gateway to perform protocol translation in the cloud.

Quotas and limits


Each Azure subscription has default quota limits in place to prevent service abuse, and these limits could impact
the scope of your IoT solution. The current limit on a per-subscription basis is 10 IoT hubs per subscription. You
can request quota increases by contacting support. For more details on quota limits:
Azure subscription service limits
IoT Hub throttling and you

Next steps
To try out an end-to-end IoT solution, check out the IoT Hub quickstarts:
Quickstart: Send telemetry from a device to an IoT hub
Quickstart: Send telemetry from a device to an IoT
hub and read the telemetry from the hub with a
back-end application (Node.js)
5/29/2018 • 5 min to read • Edit Online

IoT Hub is an Azure service that enables you to ingest high volumes of telemetry from your IoT devices into the
cloud for storage or processing. In this quickstart, you send telemetry from a simulated device application,
through IoT Hub, to a back-end application for processing.
The quickstart uses two pre-written Node.js applications, one to send the telemetry and one to read the telemetry
from the hub. Before you run these two applications, you create an IoT hub and register a device with the hub.

Open Azure Cloud Shell


Azure Cloud Shell is a free, interactive shell that you can use to run the steps in this article. Common Azure tools
are preinstalled and configured in Cloud Shell for you to use with your account. Just select the Copy button to
copy the code, paste it in Cloud Shell, and then press Enter to run it. There are a few ways to open Cloud Shell:

Select Try It in the upper-right corner of a code block.

Open Cloud Shell in your browser.

Select the Cloud Shell button on the menu in the upper-right


corner of the Azure portal.

If you don’t have an Azure subscription, create a free account before you begin.

Prerequisites
The two sample applications you run in this quickstart are written using Node.js. You need Node.js v4.x.x or later
on your development machine.
You can download Node.js for multiple platforms from nodejs.org.
You can verify the current version of Node.js on your development machine using the following command:

node --version

Download the sample Node.js project from https://github.com/Azure-Samples/azure-iot-samples-


node/archive/master.zip and extract the ZIP archive.

Create an IoT hub


The first step is to use the Azure portal to create an IoT hub in your subscription. The IoT hub enables you to
ingest high volumes of telemetry into the cloud from many devices. The hub then enables one or more back-end
services running in the cloud to read and process that telemetry.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.

Register a device
A device must be registered with your IoT hub before it can connect. In this quickstart, you use the Azure CLI to
register a simulated device.
1. Add the IoT Hub CLI extension and create the device identity. Replace {YourIoTHubName} with the name you
chose for your IoT hub:

az extension add --name azure-cli-iot-ext


az iot hub device-identity create --hub-name {YourIoTHubName} --device-id MyNodeDevice

If you choose a different name for your device, update the device name in the sample applications before
you run them.
2. Run the following command to get the device connection string for the device you just registered:

az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id MyNodeDevice


--output table

Make a note of the device connection string, which looks like Hostname=...= . You use this value later in the
quickstart.
3. You also need a service connection string to enable the back-end application to connect to your IoT hub and
retrieve the messages. The following command retrieves the service connection string for your IoT hub:

az iot hub show-connection-string --hub-name {YourIoTHubName} --output table

Make a note of the service connection string, which looks like Hostname=...= . You use this value later in the
quickstart. The service connection string is different from the device connection string.

Send simulated telemetry


The simulated device application connects to a device-specific endpoint on your IoT hub and sends simulated
temperature and humidity telemetry.
1. In a terminal window, navigate to the root folder of the sample Node.js project. Then navigate to the iot-
hub\Quickstarts\simulated-device folder.
2. Open the SimulatedDevice.js file in a text editor of your choice.
Replace the value of the connectionString variable with the device connection string you made a note of
previously. Then save your changes to SimulatedDevice.js file.
3. In the terminal window, run the following commands to install the required libraries and run the simulated
device application:

npm install
node SimulatedDevice.js

The following screenshot shows the output as the simulated device application sends telemetry to your IoT
hub:
Read the telemetry from your hub
The back-end application connects to the service-side Events endpoint on your IoT Hub. The application receives
the device-to-cloud messages sent from your simulated device. An IoT Hub back-end application typically runs in
the cloud to receive and process device-to-cloud messages.
1. In another terminal window, navigate to the root folder of the sample Node.js project. Then navigate to the
read-d2c-messages folder.
2. Open the iot-hub\Quickstarts\ReadDeviceToCloudMessages.js file in a text editor of your choice.
Replace the value of the connectionString variable with the service connection string you made a note of
previously. Then save your changes to the ReadDeviceToCloudMessages.js file.
3. In the terminal window, run the following commands to install the required libraries and run the back-end
application:

npm install
node ReadDeviceToCloudMessages.js

The following screenshot shows the output as the back-end application receives telemetry sent by the
simulated device to the hub:
Clean up resources
If you plan to complete the next quickstart, leave the resource group and IoT hub and reuse them later.
If you don't need the IoT hub any longer, delete it and the resource group in the portal. To do so, select the qs-iot-
hub-rg resource group that contains your IoT hub and click Delete.

Next steps
In this quickstart, you've setup an IoT hub, registered a device, sent simulated telemetry to the hub using a Node.js
application, and read the telemetry from the hub using a simple back-end application.
To learn how to control your simulated device from a back-end application, continue to the next quickstart.
Quickstart: Control a device connected to an IoT hub
Quickstart: Send telemetry from a device to an IoT
hub and read the telemetry from the hub with a
back-end application (C#)
5/29/2018 • 5 min to read • Edit Online

IoT Hub is an Azure service that enables you to ingest high volumes of telemetry from your IoT devices into the
cloud for storage or processing. In this quickstart, you send telemetry from a simulated device application,
through IoT Hub, to a back-end application for processing.
The quickstart uses two pre-written C# applications, one to send the telemetry and one to read the telemetry from
the hub. Before you run these two applications, you create an IoT hub and register a device with the hub.

Open Azure Cloud Shell


Azure Cloud Shell is a free, interactive shell that you can use to run the steps in this article. Common Azure tools
are preinstalled and configured in Cloud Shell for you to use with your account. Just select the Copy button to
copy the code, paste it in Cloud Shell, and then press Enter to run it. There are a few ways to open Cloud Shell:

Select Try It in the upper-right corner of a code block.

Open Cloud Shell in your browser.

Select the Cloud Shell button on the menu in the upper-


right corner of the Azure portal.

If you don’t have an Azure subscription, create a free account before you begin.

Prerequisites
The two sample applications you run in this quickstart are written using C#. You need the .NET Core SDK 2.1.0 or
greater on your development machine.
You can download the .NET Core SDK for multiple platforms from .NET.
You can verify the current version of C# on your development machine using the following command:

dotnet --version

Download the sample C# project from https://github.com/Azure-Samples/azure-iot-samples-


csharp/archive/master.zip and extract the ZIP archive.

Create an IoT hub


The first step is to use the Azure portal to create an IoT hub in your subscription. The IoT hub enables you to
ingest high volumes of telemetry into the cloud from many devices. The hub then enables one or more back-end
services running in the cloud to read and process that telemetry.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.

Register a device
A device must be registered with your IoT hub before it can connect. In this quickstart, you use the Azure CLI to
register a simulated device.
1. Add the IoT Hub CLI extension and create the device identity. Replace {YourIoTHubName} with the name you
chose for your IoT hub:

az extension add --name azure-cli-iot-ext


az iot hub device-identity create --hub-name {YourIoTHubName} --device-id MyDotnetDevice

If you choose a different name for your device, update the device name in the sample applications before
you run them.
2. Run the following command to get the device connection string for the device you just registered:

az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id


MyDotnetDevice --output table

Make a note of the device connection string, which looks like Hostname=...= . You use this value later in the
quickstart.
3. You also need the Event Hubs-compatible endpoint, Event Hubs-compatible path, and iothubowner
primary key from your IoT hub to enable the back-end application to connect to your IoT hub and retrieve
the messages. The following commands retrieve these values for your IoT hub:

az iot hub show --query properties.eventHubEndpoints.events.endpoint --name {YourIoTHubName}

az iot hub show --query properties.eventHubEndpoints.events.path --name {YourIoTHubName}

az iot hub policy show --name iothubowner --query primaryKey --hub-name {your IoT Hub name}

Make a note of these three values, which you use later in the quickstart.

Send simulated telemetry


The simulated device application connects to a device-specific endpoint on your IoT hub and sends simulated
temperature and humidity telemetry.
1. In a terminal window, navigate to the root folder of the sample C# project. Then navigate to the iot-
hub\Quickstarts\simulated-device folder.
2. Open the SimulatedDevice.cs file in a text editor of your choice.
Replace the value of the connectionString variable with the device connection string you made a note of
previously. Then save your changes to SimulatedDevice.cs file.
3. In the terminal window, run the following commands to install the required packages for simulated device
application:

dotnet restore
4. In the terminal window, run the following command to build and run the simulated device application:

dotnet run

The following screenshot shows the output as the simulated device application sends telemetry to your IoT
hub:

Read the telemetry from your hub


The back-end application connects to the service-side Events endpoint on your IoT Hub. The application receives
the device-to-cloud messages sent from your simulated device. An IoT Hub back-end application typically runs in
the cloud to receive and process device-to-cloud messages.
1. In another terminal window, navigate to the root folder of the sample C# project. Then navigate to the iot-
hub\Quickstarts\read-d2c-messages folder.
2. Open the ReadDeviceToCloudMessages.cs file in a text editor of your choice.
Replace the value of the eventHubsCompatibleEndpoint variable with the Event Hubs-compatible endpoint
you made a note of previously.
Replace the value of the eventHubsCompatiblePath variable with the Event Hubs-compatible path you made
a note of previously.
Replace the value of the iotHubSasKey variable with the iothubowner primary key you made a note of
previously. Then save your changes to the ReadDeviceToCloudMessages.cs file.
3. In the terminal window, run the following commands to install the required libraries for the back-end
application:

dotnet restore

4. In the terminal window, run the following commands to build and run the back-end application:

dotnet run
The following screenshot shows the output as the back-end application receives telemetry sent by the
simulated device to the hub:

Clean up resources
If you plan to complete the next quickstart, leave the resource group and IoT hub and reuse them later.
If you don't need the IoT hub any longer, delete it and the resource group in the portal. To do so, select the qs-iot-
hub-rg resource group that contains your IoT hub and click Delete.

Next steps
In this quickstart, you've setup an IoT hub, registered a device, sent simulated telemetry to the hub using a C#
application, and read the telemetry from the hub using a simple back-end application.
To learn how to control your simulated device from a back-end application, continue to the next quickstart.
Quickstart: Control a device connected to an IoT hub
Quickstart: Send telemetry from a device to an IoT
hub and read the telemetry from the hub with a
back-end application (Java)
5/29/2018 • 6 min to read • Edit Online

IoT Hub is an Azure service that enables you to ingest high volumes of telemetry from your IoT devices into the
cloud for storage or processing. In this quickstart, you send telemetry from a simulated device application,
through IoT Hub, to a back-end application for processing.
The quickstart uses two pre-written Java applications, one to send the telemetry and one to read the telemetry
from the hub. Before you run these two applications, you create an IoT hub and register a device with the hub.

Open Azure Cloud Shell


Azure Cloud Shell is a free, interactive shell that you can use to run the steps in this article. Common Azure tools
are preinstalled and configured in Cloud Shell for you to use with your account. Just select the Copy button to
copy the code, paste it in Cloud Shell, and then press Enter to run it. There are a few ways to open Cloud Shell:

Select Try It in the upper-right corner of a code block.

Open Cloud Shell in your browser.

Select the Cloud Shell button on the menu in the upper-


right corner of the Azure portal.

If you don’t have an Azure subscription, create a free account before you begin.

Prerequisites
The two sample applications you run in this quickstart are written using Java. You need Java SE 8 or later on your
development machine.
You can download Java for multiple platforms from Oracle.
You can verify the current version of Java on your development machine using the following command:

java --version

To build the samples, you need to install Maven 3. You can download Maven for multiple platforms from Apache
Maven.
You can verify the current version of Maven on your development machine using the following command:

mvn --version
Download the sample Java project from https://github.com/Azure-Samples/azure-iot-samples-
java/archive/master.zip and extract the ZIP archive.

Create an IoT hub


The first step is to use the Azure portal to create an IoT hub in your subscription. The IoT hub enables you to
ingest high volumes of telemetry into the cloud from many devices. The hub then enables one or more back-end
services running in the cloud to read and process that telemetry.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.

Register a device
A device must be registered with your IoT hub before it can connect. In this quickstart, you use the Azure CLI to
register a simulated device.
1. Add the IoT Hub CLI extension and create the device identity. Replace {YourIoTHubName} with the name you
chose for your IoT hub:

az extension add --name azure-cli-iot-ext


az iot hub device-identity create --hub-name {YourIoTHubName} --device-id MyJavaDevice

If you choose a different name for your device, update the device name in the sample applications before
you run them.
2. Run the following command to get the device connection string for the device you just registered:

az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id MyJavaDevice


--output table

Make a note of the device connection string, which looks like Hostname=...= . You use this value later in the
quickstart.
3. You also need the Event Hubs-compatible endpoint, Event Hubs-compatible path, and iothubowner
primary key from your IoT hub to enable the back-end application to connect to your IoT hub and retrieve
the messages. The following commands retrieve these values for your IoT hub:

az iot hub show --query properties.eventHubEndpoints.events.endpoint --name {YourIoTHubName}

az iot hub show --query properties.eventHubEndpoints.events.path --name {YourIoTHubName}

az iot hub policy show --name iothubowner --query primaryKey --hub-name {your IoT Hub name}

Make a note of these three values, which you use later in the quickstart.

Send simulated telemetry


The simulated device application connects to a device-specific endpoint on your IoT hub and sends simulated
temperature and humidity telemetry.
1. In a terminal window, navigate to the root folder of the sample Java project. Then navigate to the iot-
hub\Quickstarts\simulated-device folder.
2. Open the src/main/java/com/microsoft/docs/iothub/samples/SimulatedDevice.java file in a text
editor of your choice.
Replace the value of the connString variable with the device connection string you made a note of
previously. Then save your changes to SimulatedDevice.java file.
3. In the terminal window, run the following commands to install the required libraries and build the
simulated device application:

mvn clean package


4. In the terminal window, run the following commands to run the simulated device application:

java -jar target/simulated-device-1.0.0-with-deps.jar

The following screenshot shows the output as the simulated device application sends telemetry to your IoT
hub:

Read the telemetry from your hub


The back-end application connects to the service-side Events endpoint on your IoT Hub. The application receives
the device-to-cloud messages sent from your simulated device. An IoT Hub back-end application typically runs in
the cloud to receive and process device-to-cloud messages.
1. In another terminal window, navigate to the root folder of the sample Java project. Then navigate to the
iot-hub\Quickstarts\read-d2c-messages folder.
2. Open the src/main/java/com/microsoft/docs/iothub/samples/ReadDeviceToCloudMessages.java
file in a text editor of your choice.
Replace the value of the eventHubsCompatibleEndpoint variable with the Event Hubs-compatible endpoint
you made a note of previously.
Replace the value of the eventHubsCompatiblePath variable with the Event Hubs-compatible path you made
a note of previously.
Replace the value of the iotHubSasKey variable with the iothubowner primary key you made a note of
previously. Then save your changes to the ReadDeviceToCloudMessages.java file.
3. In the terminal window, run the following commands to install the required libraries and build the back-end
application:

mvn clean package

4. In the terminal window, run the following commands to run the back-end application:

java -jar target/read-d2c-messages-1.0.0-with-deps.jar


The following screenshot shows the output as the back-end application receives telemetry sent by the
simulated device to the hub:

Clean up resources
If you plan to complete the next quickstart, leave the resource group and IoT hub and reuse them later.
If you don't need the IoT hub any longer, delete it and the resource group in the portal. To do so, select the qs-iot-
hub-rg resource group that contains your IoT hub and click Delete.

Next steps
In this quickstart, you've setup an IoT hub, registered a device, sent simulated telemetry to the hub using a Java
application, and read the telemetry from the hub using a simple back-end application.
To learn how to control your simulated device from a back-end application, continue to the next quickstart.
Quickstart: Control a device connected to an IoT hub
Quickstart: Send telemetry from a device to an IoT
hub and read the telemetry from the hub with a
back-end application (Python)
5/29/2018 • 5 min to read • Edit Online

IoT Hub is an Azure service that enables you to ingest high volumes of telemetry from your IoT devices into the
cloud for storage or processing. In this quickstart, you send telemetry from a simulated device application,
through IoT Hub, to a back-end application for processing.
The quickstart uses a pre-written Python application to send the telemetry and a CLI utility to read the telemetry
from the hub. Before you run these two applications, you create an IoT hub and register a device with the hub.

Open Azure Cloud Shell


Azure Cloud Shell is a free, interactive shell that you can use to run the steps in this article. Common Azure tools
are preinstalled and configured in Cloud Shell for you to use with your account. Just select the Copy button to
copy the code, paste it in Cloud Shell, and then press Enter to run it. There are a few ways to open Cloud Shell:

Select Try It in the upper-right corner of a code block.

Open Cloud Shell in your browser.

Select the Cloud Shell button on the menu in the upper-


right corner of the Azure portal.

If you don’t have an Azure subscription, create a free account before you begin.

Prerequisites
The two sample applications you run in this quickstart are written using Python. You need either Python 2.7.x or
3.5.x on your development machine.
You can download Python for multiple platforms from Python.org.
You can verify the current version of Python on your development machine using one of the following
commands:

python --version

python3 --version

Download the sample Python project from https://github.com/Azure-Samples/azure-iot-samples-


python/archive/master.zip and extract the ZIP archive.
To install the CLI utility that reads telemetry from the IoT hub, first install Node.js v4.x.x or later on your
development machine. You can download Node.js for multiple platforms from nodejs.org.
You can verify the current version of Node.js on your development machine using the following command:

node --version

To install the iothub-explorer CLI utility, run the following command:

npm install -g iothub-explorer

Create an IoT hub


The first step is to use the Azure portal to create an IoT hub in your subscription. The IoT hub enables you to
ingest high volumes of telemetry into the cloud from many devices. The hub then enables one or more back-end
services running in the cloud to read and process that telemetry.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.

Register a device
A device must be registered with your IoT hub before it can connect. In this quickstart, you use the Azure CLI to
register a simulated device.
1. Add the IoT Hub CLI extension and create the device identity. Replace {YourIoTHubName} with the name
you chose for your IoT hub:

az extension add --name azure-cli-iot-ext


az iot hub device-identity create --hub-name {YourIoTHubName} --device-id MyPythonDevice

If you choose a different name for your device, update the device name in the sample application before
you run it.
2. Run the following command to get the device connection string for the device you just registered:

az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id


MyPythonDevice --output table

Make a note of the device connection string, which looks like Hostname=...= . You use this value later in the
quickstart.
3. You also need a service connection string to enable the iothub-explorer CLI utility to connect to your IoT
hub and retrieve the messages. The following command retrieves the service connection string for your
IoT hub:
az iot hub show-connection-string --hub-name {YourIoTHubName} --output table

Make a note of the service connection string, which looks like Hostname=...= . You use this value later in the
quickstart. The service connection string is different from the device connection string.

Send simulated telemetry


The simulated device application connects to a device-specific endpoint on your IoT hub and sends simulated
temperature and humidity telemetry.
1. In a terminal window, navigate to the root folder of the sample Python project. Then navigate to the iot-
hub\Quickstarts\simulated-device folder.
2. Open the SimulatedDevice.py file in a text editor of your choice.
Replace the value of the CONNECTION_STRING variable with the device connection string you made a note of
previously. Then save your changes to SimulatedDevice.py file.
3. In the terminal window, run the following commands to install the required libraries for the simulated
device application:

pip install azure-iothub-device-client

4. In the terminal window, run the following commands to run the simulated device application:

python SimulatedDevice.py

The following screenshot shows the output as the simulated device application sends telemetry to your IoT
hub:

Read the telemetry from your hub


The iothub-explorer CLI utility connects to the service-side Events endpoint on your IoT Hub. The utility
receives the device-to-cloud messages sent from your simulated device. An IoT Hub back-end application
typically runs in the cloud to receive and process device-to-cloud messages.
In another terminal window, run the following commands replacing {your hub service connection string} with
the service connection string you made a note of previously:

iothub-explorer monitor-events MyPythonDevice --login {your hub service connection string}

The following screenshot shows the output as the utility receives telemetry sent by the simulated device to the
hub:

Clean up resources
If you plan to complete the next quickstart, leave the resource group and IoT hub and reuse them later.
If you don't need the IoT hub any longer, delete it and the resource group in the portal. To do so, select the qs-iot-
hub-rg resource group that contains your IoT hub and click Delete.

Next steps
In this quickstart, you've setup an IoT hub, registered a device, sent simulated telemetry to the hub using a Python
application, and read the telemetry from the hub using a simple back-end application.
To learn how to control your simulated device from a back-end application, continue to the next quickstart.
Quickstart: Control a device connected to an IoT hub
Quickstart: Send telemetry from a device to an IoT
hub (iOS)
6/6/2018 • 6 min to read • Edit Online

IoT Hub is an Azure service that enables you to ingest high volumes of telemetry from your IoT devices into the
cloud for storage or processing. In this article, you send telemetry from a simulated device application to IoT Hub.
Then you can view the data from a back-end application.
This article uses a pre-written Swift application to send the telemetry and a CLI utility to read the telemetry from
IoT Hub.

Open Azure Cloud Shell


Azure Cloud Shell is a free, interactive shell that you can use to run the steps in this article. Common Azure tools
are preinstalled and configured in Cloud Shell for you to use with your account. Just select the Copy button to
copy the code, paste it in Cloud Shell, and then press Enter to run it. There are a few ways to open Cloud Shell:

Select Try It in the upper-right corner of a code block.

Open Cloud Shell in your browser.

Select the Cloud Shell button on the menu in the upper-


right corner of the Azure portal.

If you don’t have an Azure subscription, create a free account before you begin.

Prerequisites
Download the code sample from Azure samples
The latest version of XCode, running the latest version of the iOS SDK. This quickstart was tested with XCode
9.3 and iOS 11.3.
The latest version of CocoaPods.
The iothub-explorer CLI utility, which reads telemetry from IoT Hub. To install, first install Node.js v4.x.x or
higher, then run the following command:

sudo npm install -g iothub-explorer

Create an IoT hub


The first step is to use the Azure portal to create an IoT hub in your subscription. The IoT hub enables you to
ingest high volumes of telemetry into the cloud from many devices. The hub then enables one or more back-end
services running in the cloud to read and process that telemetry.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.

Register a device
A device must be registered with your IoT hub before it can connect. In this quickstart, you use the Azure CLI to
register a simulated device.
1. Add the IoT Hub CLI extension and create the device identity. Replace {YourIoTHubName} with a name for
your IoT hub:

az extension add --name azure-cli-iot-ext


az iot hub device-identity create --hub-name {YourIoTHubName} --device-id myiOSdevice

If you choose a different name for your device, update the device name in the sample applications before
you run them.
2. Run the following command to get the device connection string for the device you just registered:

az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id myiOSdevice


--output table

Make a note of the device connection string, which looks like Hostname=...= . You use this value later in the
article.
3. You also need a service connection string to enable back-end applications to connect to your IoT hub and
retrieve device-to-cloud messages. The following command retrieves the service connection string for
your IoT hub:

az iot hub show-connection-string --hub-name {YourIoTHubName} --output table

Make a note of the service connection string, which looks like Hostname=...= . You use this value later in
the article.

Send simulated telemetry


The sample application runs on an iOS device, which connects to a device-specific endpoint on your IoT hub and
sends simulated temperature and humidity telemetry.
Install CocoaPods
CocoaPods manage dependencies for iOS projects that use third-party libraries.
In a terminal window, navigate to the Azure-IoT-Samples-iOS folder that you downloaded in the prerequisites.
Then, navigate to the sample project:

cd quickstart/sample-device

Make sure that XCode is closed, then run the following command to install the CocoaPods that are declared in
the podfile file:

pod install

Along with installing the pods required for your project, the installation command also created an XCode
workspace file that is already configured to use the pods for dependencies.
Run the sample application
1. Open the sample workspace in XCode.

open "MQTT Client Sample.xcworkspace"

2. Expand the MQTT Client Sample project and then expand the folder of the same name.
3. Open ViewController.swift for editing in XCode.
4. Search for the connectionString variable and update the value with the device connection string that you
made a note of previously.
5. Save your changes.
6. Run the project in the device emulator with the Build and run button or the key combo command + r.

7. When the emulator opens, select Start in the sample app.


The following screenshot shows some example output as the application sends simulated telemetry to your IoT
hub:
Read the telemetry from your hub
The sample app that you ran on the XCode emulator shows data about messages sent from the device. You can
also view the data through your IoT hub as it is received. The iothub-explorer CLI utility connects to the service-
side Events endpoint on your IoT Hub.
Open a new terminal window. Run the following command replacing {your hub service connection string} with
the service connection string that you retrieved at the beginning of this article:

iothub-explorer monitor-events myiOSdevice --login "{your hub service connection string}"

The following screenshot shows the type of telemetry that you see in your terminal window:
If you get an error when you run the iothub-explorer command, double check that you're using the service
connection string for your IoT hub, rather than the device connection string for your IoT device. Both connection
strings start with Hostname={iothubname} but the service connection string contains the
SharedAccessKeyName property while the device connection string contains DeviceID.

Clean up resources
If you plan to continue testing IoT Hub with other articles, leave the your resource group and IoT hub and reuse
them later.
If you don't need the IoT hub any longer, delete it and the resource group in the portal. To do so, select the
resource group that contains your IoT hub and click Delete.

Next steps
In this article, you set up an IoT hub, registered a device, sent simulated telemetry to the hub from an iOS device,
and read the telemetry from the hub.
To learn how to control your simulated device from a back-end application, continue to the next quickstart.
Quickstart: Control a device connected to an IoT hub
Quickstart: Control a device connected to an IoT hub
(Node.js)
6/6/2018 • 6 min to read • Edit Online

IoT Hub is an Azure service that enables you to ingest high volumes of telemetry from your IoT devices into the
cloud and manage your devices from the cloud. In this quickstart, you use a direct method to control a simulated
device connected to your IoT hub. You can use direct methods to remotely change the behavior of a device
connected to your IoT hub.
The quickstart uses two pre-written Node.js applications:
A simulated device application that responds to direct methods called from a back-end application. To receive
the direct method calls, this application connects to a device-specific endpoint on your IoT hub.
A back-end application that calls the direct methods on the simulated device. To call a direct method on a
device, this application connects to service-side endpoint on your IoT hub.

Open Azure Cloud Shell


Azure Cloud Shell is a free, interactive shell that you can use to run the steps in this article. Common Azure tools
are preinstalled and configured in Cloud Shell for you to use with your account. Just select the Copy button to
copy the code, paste it in Cloud Shell, and then press Enter to run it. There are a few ways to open Cloud Shell:

Select Try It in the upper-right corner of a code block.

Open Cloud Shell in your browser.

Select the Cloud Shell button on the menu in the upper-


right corner of the Azure portal.

If you don’t have an Azure subscription, create a free account before you begin.

Prerequisites
The two sample applications you run in this quickstart are written using Node.js. You need Node.js v4.x.x or later
on your development machine.
You can download Node.js for multiple platforms from nodejs.org.
You can verify the current version of Node.js on your development machine using the following command:

node --version

If you haven't already done so, download the sample Node.js project from https://github.com/Azure-
Samples/azure-iot-samples-node/archive/master.zip and extract the ZIP archive.

Create an IoT hub


If you completed the previous Quickstart: Send telemetry from a device to an IoT hub, you can skip this step.
The first step is to use the Azure portal to create an IoT hub in your subscription. The IoT hub enables you to
ingest high volumes of telemetry into the cloud from many devices. The hub then enables one or more back-end
services running in the cloud to read and process that telemetry.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.

Register a device
If you completed the previous Quickstart: Send telemetry from a device to an IoT hub, you can skip this step.
A device must be registered with your IoT hub before it can connect. In this quickstart, you use the Azure CLI to
register a simulated device.
1. Add the IoT Hub CLI extension and create the device identity. Replace {YourIoTHubName} with the name of
your IoT hub:

az extension add --name azure-cli-iot-ext


az iot hub device-identity create --hub-name {YourIoTHubName} --device-id MyNodeDevice

If you choose a different name for your device, update the device name in the sample applications before
you run them.
2. Run the following command to get the device connection string for the device you just registered:

az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id MyNodeDevice


--output table

Make a note of the device connection string, which looks like Hostname=...= . You use this value later in the
quickstart.
3. You also need a service connection string to enable the back-end application to connect to your IoT hub and
retrieve the messages. The following command retrieves the service connection string for your IoT hub:

az iot hub show-connection-string --hub-name {YourIoTHubName} --output table

Make a note of the service connection string, which looks like Hostname=...= . You use this value later in the
quickstart. The service connection string is different from the device connection string.

Listen for direct method calls


The simulated device application connects to a device-specific endpoint on your IoT hub, sends simulated
telemetry, and listens for direct method calls from your hub. In this quickstart, the direct method call from the hub
tells the device to change the interval at which it sends telemetry. The simulated device sends an
acknowledgement back to your hub after it executes the direct method.
1. In a terminal window, navigate to the root folder of the sample Node.js project. Then navigate to the iot-
hub\Quickstarts\simulated-device-2 folder.
2. Open the SimulatedDevice.js file in a text editor of your choice.
Replace the value of the connectionString variable with the device connection string you made a note of
previously. Then save your changes to SimulatedDevice.js file.
3. In the terminal window, run the following commands to install the required libraries and run the simulated
device application:
npm install
node SimulatedDevice.js

The following screenshot shows the output as the simulated device application sends telemetry to your IoT
hub:

Call the direct method


The back-end application connects to a service-side endpoint on your IoT Hub. The application makes direct
method calls to a device through your IoT hub and listens for acknowledgements. An IoT Hub back-end
application typically runs in the cloud.
1. In another terminal window, navigate to the root folder of the sample Node.js project. Then navigate to the
iot-hub\Quickstarts\back-end-application folder.
2. Open the BackEndApplication.js file in a text editor of your choice.
Replace the value of the connectionString variable with the service connection string you made a note of
previously. Then save your changes to the BackEndApplication.js file.
3. In the terminal window, run the following commands to install the required libraries and run the back-end
application:

npm install
node BackEndApplication.js

The following screenshot shows the output as the application makes a direct method call to the device and
receives an acknowledgement:
After you run the back-end application, you see a message in the console window running the simulated
device, and the rate at which it sends messages changes:

Clean up resources
If you plan to move on to the tutorials, leave the resource group and IoT hub and reuse them later.
If you don't need the IoT hub any longer, delete it and the resource group in the portal. To do so, select the
resource group that contains your IoT hub and click Delete.

Next steps
In this quickstart, you've called a direct method on a device from a back-end application, and responded to the
direct method call in a simulated device application.
To learn how to route device-to-cloud messages to different destinations in the cloud, continue to the next tutorial.
Tutorial: Route telemetry to different endpoints for processing
Quickstart: Control a device connected to an IoT hub
(.NET)
6/6/2018 • 6 min to read • Edit Online

IoT Hub is an Azure service that enables you to ingest high volumes of telemetry from your IoT devices into the
cloud and manage your devices from the cloud. In this quickstart, you use a direct method to control a simulated
device connected to your IoT hub. You can use direct methods to remotely change the behavior of a device
connected to your IoT hub.
The quickstart uses two pre-written .NET applications:
A simulated device application that responds to direct methods called from a back-end application. To receive
the direct method calls, this application connects to a device-specific endpoint on your IoT hub.
A back-end application that calls the direct methods on the simulated device. To call a direct method on a
device, this application connects to service-side endpoint on your IoT hub.

Open Azure Cloud Shell


Azure Cloud Shell is a free, interactive shell that you can use to run the steps in this article. Common Azure tools
are preinstalled and configured in Cloud Shell for you to use with your account. Just select the Copy button to
copy the code, paste it in Cloud Shell, and then press Enter to run it. There are a few ways to open Cloud Shell:

Select Try It in the upper-right corner of a code block.

Open Cloud Shell in your browser.

Select the Cloud Shell button on the menu in the upper-right


corner of the Azure portal.

If you don’t have an Azure subscription, create a free account before you begin.

Prerequisites
The two sample applications you run in this quickstart are written using C#. You need the .NET Core SDK 2.1.0 or
greater on your development machine.
You can download the .NET Core SDK for multiple platforms from .NET.
You can verify the current version of C# on your development machine using the following command:

dotnet --version

If you haven't already done so, download the sample C# project from https://github.com/Azure-Samples/azure-
iot-samples-csharp/archive/master.zip and extract the ZIP archive.

Create an IoT hub


If you completed the previous Quickstart: Send telemetry from a device to an IoT hub, you can skip this step.
The first step is to use the Azure portal to create an IoT hub in your subscription. The IoT hub enables you to
ingest high volumes of telemetry into the cloud from many devices. The hub then enables one or more back-end
services running in the cloud to read and process that telemetry.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.

Register a device
If you completed the previous Quickstart: Send telemetry from a device to an IoT hub, you can skip this step.
A device must be registered with your IoT hub before it can connect. In this quickstart, you use the Azure CLI to
register a simulated device.
1. Add the IoT Hub CLI extension and create the device identity. Replace {YourIoTHubName} with the name you
chose for your IoT hub:

az extension add --name azure-cli-iot-ext


az iot hub device-identity create --hub-name {YourIoTHubName} --device-id MyDotnetDevice

If you choose a different name for your device, update the device name in the sample applications before
you run them.
2. Run the following command to get the device connection string for the device you just registered:

az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id


MyDotnetDevice --output table

Make a note of the device connection string, which looks like Hostname=...= . You use this value later in the
quickstart.

Retrieve the service connection string


You also need your IoT hub service connection string to enable the back-end application to connect to the hub and
retrieve the messages. The following command retrieves the service connection string for your IoT hub:

az iot hub show-connection-string --hub-name {YourIoTHubName} --output table

Make a note of the service connection string, which looks like Hostname=...= . You use this value later in the
quickstart.

Listen for direct method calls


The simulated device application connects to a device-specific endpoint on your IoT hub, sends simulated
telemetry, and listens for direct method calls from your hub. In this quickstart, the direct method call from the hub
tells the device to change the interval at which it sends telemetry. The simulated device sends an
acknowledgement back to your hub after it executes the direct method.
1. In a terminal window, navigate to the root folder of the sample C# project. Then navigate to the iot-
hub\Quickstarts\simulated-device-2 folder.
2. Open the SimulatedDevice.cs file in a text editor of your choice.
Replace the value of the connectionString variable with the device connection string you made a note of
previously. Then save your changes to SimulatedDevice.cs file.
3. In the terminal window, run the following commands to install the required packages for simulated device
application:
dotnet restore

4. In the terminal window, run the following command to build and run the simulated device application:

dotnet run

The following screenshot shows the output as the simulated device application sends telemetry to your IoT
hub:

Call the direct method


The back-end application connects to a service-side endpoint on your IoT Hub. The application makes direct
method calls to a device through your IoT hub and listens for acknowledgements. An IoT Hub back-end
application typically runs in the cloud.
1. In another terminal window, navigate to the root folder of the sample C# project. Then navigate to the iot-
hub\Quickstarts\back-end-application folder.
2. Open the BackEndApplication.cs file in a text editor of your choice.
Replace the value of the connectionString variable with the service connection string you made a note of
previously. Then save your changes to the BackEndApplication.cs file.
3. In the terminal window, run the following commands to install the required libraries for the back-end
application:

dotnet restore

4. In the terminal window, run the following commands to build and run the back-end application:

dotnet run

The following screenshot shows the output as the application makes a direct method call to the device and
receives an acknowledgement:
After you run the back-end application, you see a message in the console window running the simulated
device, and the rate at which it sends messages changes:

Clean up resources
If you plan to move on to the tutorials, leave the resource group and IoT hub and reuse them later.
If you don't need the IoT hub any longer, delete it and the resource group in the portal. To do so, select the
resource group that contains your IoT hub and click Delete.

Next steps
In this quickstart, you've called a direct method on a device from a back-end application, and responded to the
direct method call in a simulated device application.
To learn how to route device-to-cloud messages to different destinations in the cloud, continue to the next tutorial.
Tutorial: Route telemetry to different endpoints for processing
Quickstart: Control a device connected to an IoT hub
(Java)
6/6/2018 • 6 min to read • Edit Online

IoT Hub is an Azure service that enables you to ingest high volumes of telemetry from your IoT devices into the
cloud and manage your devices from the cloud. In this quickstart, you use a direct method to control a simulated
device connected to your IoT hub. You can use direct methods to remotely change the behavior of a device
connected to your IoT hub.
The quickstart uses two pre-written Java applications:
A simulated device application that responds to direct methods called from a back-end application. To receive
the direct method calls, this application connects to a device-specific endpoint on your IoT hub.
A back-end application that calls the direct methods on the simulated device. To call a direct method on a
device, this application connects to service-side endpoint on your IoT hub.

Open Azure Cloud Shell


Azure Cloud Shell is a free, interactive shell that you can use to run the steps in this article. Common Azure tools
are preinstalled and configured in Cloud Shell for you to use with your account. Just select the Copy button to
copy the code, paste it in Cloud Shell, and then press Enter to run it. There are a few ways to open Cloud Shell:

Select Try It in the upper-right corner of a code block.

Open Cloud Shell in your browser.

Select the Cloud Shell button on the menu in the upper-


right corner of the Azure portal.

If you don’t have an Azure subscription, create a free account before you begin.

Prerequisites
The two sample applications you run in this quickstart are written using Java. You need Java SE 8 or later on your
development machine.
You can download Java for multiple platforms from Oracle.
You can verify the current version of Java on your development machine using the following command:

java --version

To build the samples, you need to install Maven 3. You can download Maven for multiple platforms from Apache
Maven.
You can verify the current version of Maven on your development machine using the following command:
mvn --version

If you haven't already done so, download the sample Java project from https://github.com/Azure-Samples/azure-
iot-samples-java/archive/master.zip and extract the ZIP archive.

Create an IoT hub


If you completed the previous Quickstart: Send telemetry from a device to an IoT hub, you can skip this step.
The first step is to use the Azure portal to create an IoT hub in your subscription. The IoT hub enables you to
ingest high volumes of telemetry into the cloud from many devices. The hub then enables one or more back-end
services running in the cloud to read and process that telemetry.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.
IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.

Register a device
If you completed the previous Quickstart: Send telemetry from a device to an IoT hub, you can skip this step.
A device must be registered with your IoT hub before it can connect. In this quickstart, you use the Azure CLI to
register a simulated device.
1. Add the IoT Hub CLI extension and create the device identity. Replace {YourIoTHubName} with the name you
chose for your IoT hub:

az extension add --name azure-cli-iot-ext


az iot hub device-identity create --hub-name {YourIoTHubName} --device-id MyJavaDevice

If you choose a different name for your device, update the device name in the sample applications before
you run them.
2. Run the following command to get the device connection string for the device you just registered:

az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id MyJavaDevice


--output table

Make a note of the device connection string, which looks like Hostname=...= . You use this value later in the
quickstart.

Retrieve the service connection string


You also need your IoT hub service connection string to enable the back-end application to connect to the hub and
retrieve the messages. The following command retrieves the service connection string for your IoT hub:

az iot hub show-connection-string --hub-name {YourIoTHubName} --output table

Make a note of the service connection string, which looks like Hostname=...= . You use this value later in the
quickstart.

Listen for direct method calls


The simulated device application connects to a device-specific endpoint on your IoT hub, sends simulated
telemetry, and listens for direct method calls from your hub. In this quickstart, the direct method call from the hub
tells the device to change the interval at which it sends telemetry. The simulated device sends an
acknowledgement back to your hub after it executes the direct method.
1. In a terminal window, navigate to the root folder of the sample Java project. Then navigate to the iot-
hub\Quickstarts\simulated-device-2 folder.
2. Open the src/main/java/com/microsoft/docs/iothub/samples/SimulatedDevice.java file in a text
editor of your choice.
Replace the value of the connString variable with the device connection string you made a note of
previously. Then save your changes to SimulatedDevice.java file.
3. In the terminal window, run the following commands to install the required libraries and build the
simulated device application:

mvn clean package

4. In the terminal window, run the following commands to run the simulated device application:

java -jar target/simulated-device-2-1.0.0-with-deps.jar

The following screenshot shows the output as the simulated device application sends telemetry to your IoT
hub:
Call the direct method
The back-end application connects to a service-side endpoint on your IoT Hub. The application makes direct
method calls to a device through your IoT hub and listens for acknowledgements. An IoT Hub back-end
application typically runs in the cloud.
1. In another terminal window, navigate to the root folder of the sample Java project. Then navigate to the
iot-hub\Quickstarts\back-end-application folder.
2. Open the src/main/java/com/microsoft/docs/iothub/samples/BackEndApplication.java file in a
text editor of your choice.
Replace the value of the iotHubConnectionString variable with the service connection string you made a
note of previously. Then save your changes to the BackEndApplication.java file.
3. In the terminal window, run the following commands to install the required libraries and build the back-end
application:

mvn clean package

4. In the terminal window, run the following commands to run the back-end application:

java -jar target/back-end-application-1.0.0-with-deps.jar

The following screenshot shows the output as the application makes a direct method call to the device and
receives an acknowledgement:

After you run the back-end application, you see a message in the console window running the simulated
device, and the rate at which it sends messages changes:
Clean up resources
If you plan to move on to the tutorials, leave the resource group and IoT hub and reuse them later.
If you don't need the IoT hub any longer, delete it and the resource group in the portal. To do so, select the
resource group that contains your IoT hub and click Delete.

Next steps
In this quickstart, you've called a direct method on a device from a back-end application, and responded to the
direct method call in a simulated device application.
To learn how to route device-to-cloud messages to different destinations in the cloud, continue to the next tutorial.
Tutorial: Route telemetry to different endpoints for processing
Quickstart: Control a device connected to an IoT hub
(Python)
6/6/2018 • 6 min to read • Edit Online

IoT Hub is an Azure service that enables you to ingest high volumes of telemetry from your IoT devices into the
cloud and manage your devices from the cloud. In this quickstart, you use a direct method to control a simulated
device connected to your IoT hub. You can use direct methods to remotely change the behavior of a device
connected to your IoT hub.
The quickstart uses two pre-written Python applications:
A simulated device application that responds to direct methods called from a back-end application. To receive
the direct method calls, this application connects to a device-specific endpoint on your IoT hub.
A back-end application that calls the direct methods on the simulated device. To call a direct method on a
device, this application connects to service-side endpoint on your IoT hub.

Open Azure Cloud Shell


Azure Cloud Shell is a free, interactive shell that you can use to run the steps in this article. Common Azure tools
are preinstalled and configured in Cloud Shell for you to use with your account. Just select the Copy button to
copy the code, paste it in Cloud Shell, and then press Enter to run it. There are a few ways to open Cloud Shell:

Select Try It in the upper-right corner of a code block.

Open Cloud Shell in your browser.

Select the Cloud Shell button on the menu in the upper-


right corner of the Azure portal.

If you don’t have an Azure subscription, create a free account before you begin.

Prerequisites
The two sample applications you run in this quickstart are written using Python. You need either Python 2.7.x or
3.5.x on your development machine.
You can download Python for multiple platforms from Python.org.
You can verify the current version of Python on your development machine using one of the following commands:

python --version

python3 --version

If you haven't already done so, download the sample Python project from https://github.com/Azure-
Samples/azure-iot-samples-python/archive/master.zip and extract the ZIP archive.

Create an IoT hub


If you completed the previous Quickstart: Send telemetry from a device to an IoT hub, you can skip this step.
The first step is to use the Azure portal to create an IoT hub in your subscription. The IoT hub enables you to
ingest high volumes of telemetry into the cloud from many devices. The hub then enables one or more back-end
services running in the cloud to read and process that telemetry.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.
IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.

Register a device
If you completed the previous Quickstart: Send telemetry from a device to an IoT hub, you can skip this step.
A device must be registered with your IoT hub before it can connect. In this quickstart, you use the Azure CLI to
register a simulated device.
1. Add the IoT Hub CLI extension and create the device identity. Replace {YourIoTHubName} with the name of
your IoT hub:

az extension add --name azure-cli-iot-ext


az iot hub device-identity create --hub-name {YourIoTHubName} --device-id MyPythonDevice

If you choose a different name for your device, update the device name in the sample applications before
you run them.
2. Run the following command to get the device connection string for the device you just registered:

az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id


MyPythonDevice --output table

Make a note of the device connection string, which looks like Hostname=...= . You use this value later in the
quickstart.
3. You also need a service connection string to enable the back-end application to connect to your IoT hub and
retrieve the messages. The following command retrieves the service connection string for your IoT hub:
az iot hub show-connection-string --hub-name {YourIoTHubName} --output table

Make a note of the service connection string, which looks like Hostname=...= . You use this value later in the
quickstart. The service connection string is different from the device connection string.

Listen for direct method calls


The simulated device application connects to a device-specific endpoint on your IoT hub, sends simulated
telemetry, and listens for direct method calls from your hub. In this quickstart, the direct method call from the hub
tells the device to change the interval at which it sends telemetry. The simulated device sends an
acknowledgement back to your hub after it executes the direct method.
1. In a terminal window, navigate to the root folder of the sample Python project. Then navigate to the iot-
hub\Quickstarts\simulated-device-2 folder.
2. Open the SimulatedDevice.py file in a text editor of your choice.
Replace the value of the CONNECTION_STRING variable with the device connection string you made a note of
previously. Then save your changes to SimulatedDevice.py file.
3. In the terminal window, run the following commands to install the required libraries for the simulated
device application:

pip install azure-iothub-device-client

4. In the terminal window, run the following commands to run the simulated device application:

python SimulatedDevice.py

The following screenshot shows the output as the simulated device application sends telemetry to your IoT
hub:

Call the direct method


The back-end application connects to a service-side endpoint on your IoT Hub. The application makes direct
method calls to a device through your IoT hub and listens for acknowledgements. An IoT Hub back-end
application typically runs in the cloud.
1. In another terminal window, navigate to the root folder of the sample Python project. Then navigate to the
iot-hub\Quickstarts\back-end-application folder.
2. Open the BackEndApplication.py file in a text editor of your choice.
Replace the value of the CONNECTION_STRING variable with the service connection string you made a note of
previously. Then save your changes to the BackEndApplication.py file.
3. In the terminal window, run the following commands to install the required libraries for the simulated
device application:

pip install azure-iothub-service-client future

4. In the terminal window, run the following commands to run the back-end application:

python BackEndApplication.py

The following screenshot shows the output as the application makes a direct method call to the device and
receives an acknowledgement:

After you run the back-end application, you see a message in the console window running the simulated
device, and the rate at which it sends messages changes:
Clean up resources
If you plan to move on to the tutorials, leave the resource group and IoT hub and reuse them later.
If you don't need the IoT hub any longer, delete it and the resource group in the portal. To do so, select the
resource group that contains your IoT hub and click Delete.

Next steps
In this quickstart, you've called a direct method on a device from a back-end application, and responded to the
direct method call in a simulated device application.
To learn how to route device-to-cloud messages to different destinations in the cloud, continue to the next tutorial.
Tutorial: Route telemetry to different endpoints for processing
Tutorial: Configure message routing with IoT Hub
5/31/2018 • 21 min to read • Edit Online

Message routing enables sending telemetry data from your IoT devices to built-in Event Hub-compatible
endpoints or custom endpoints such as blob storage, Service Bus Queue, Service Bus Topic, and Event Hubs.
While configuring message routing, you can create routing rules to customize the route that matches a certain
rule. Once set up, the incoming data is automatically routed to the endpoints by the IoT Hub.
In this tutorial, you learn how to set up and use routing rules with IoT Hub. You will route messages from an IoT
device to one of multiple services, including blob storage and a Service Bus queue. Messages to the Service Bus
queue will be picked up by a Logic App and sent via e-mail. Messages that do not have routing specifically set
up are sent to the default endpoint, and viewed in a Power BI visualization.
In this tutorial, you perform the following tasks:
Using Azure CLI or PowerShell, set up the base resources -- an IoT hub, a storage account, a Service Bus
queue, and a simulated device.
Configure endpoints and routes in IoT hub for the storage account and Service Bus queue.
Create a Logic App that is triggered and sends e-mail when a message is added to the Service Bus queue.
Download and run an app that simulates an IoT Device sending messages to the hub for the different
routing options.
Create a Power BI visualization for data sent to the default endpoint.
View the results ...
...in the Service Bus queue and e-mails.
...in the storage account.
...in the Power BI visualization.

Prerequisites
An Azure subscription. If you don't have an Azure subscription, create a free account before you begin.
Install Visual Studio for Windows.
A Power BI account to analyze the default endpoint's stream analytics. (Try Power BI for free.)
An Office 365 account to send notification e-mails.
You need either Azure CLI or Azure PowerShell to do the setup steps for this tutorial.
To use Azure CLI, while you can install Azure CLI locally, we recommend you use the Azure Cloud Shell. Azure
Cloud Shell is a free, interactive shell that you can use to run Azure CLI scripts. Common Azure tools are
preinstalled and configured in Cloud Shell for you to use with your account, so you don't have to install them
locally.
To use PowerShell, install it locally using the instructions below.
Azure Cloud Shell
There are a few ways to open Cloud Shell:
Select Try It in the upper-right corner of a code block.

Open Cloud Shell in your browser.

Select the Cloud Shell button on the menu in the upper-


right corner of the Azure portal.

Using Azure CLI locally


If you would rather use CLI locally than use Cloud Shell, you must have Azure CLI module version 2.0.30.0 or
later. Run az --version to find the version. If you need to install or upgrade, see Install Azure CLI 2.0.
Using PowerShell locally
This tutorial requires Azure PowerShell module version 5.7 or later. Run Get-Module -ListAvailable AzureRM to
find the version. If you need to install or upgrade, see Install Azure PowerShell module.

Set up resources
For this tutorial, you need an IoT hub, a storage account, and a Service Bus queue. These resources can all be
created using Azure CLI or Azure PowerShell. Use the same resource group and location for all of the
resources. Then at the end, you can remove everything in one step by deleting the resource group.
The following sections describe how to do these required steps. Follow the CLI or the PowerShell instructinos.
1. Create a resource group.
2. Create an IoT hub in the S1 tier. Add a consumer group to your IoT hub. The consumer group is used by
the Azure Stream Analytics when retrieving data.
3. Create a standard V1 storage account with Standard_LRS replication.
4. Create a Service Bus namespace and queue.
5. Create a device identity for the simulated device that sends messages to your hub. Save the key for the
testing phase.
Azure CLI instructions
The easiest way to use this script is to copy it and paste it into Cloud Shell. Assuming you are already logged in,
it will run the script one line at a time.

# This is the IOT Extension for Azure CLI.


# You only need to install this the first time.
# You need it to create the device identity.
az extension add --name azure-cli-iot-ext

# Set the values for the resource names that don't have to be globally unique.
# The resources that have to have unique names are named in the script below
# with a random number concatenated to the name so you can probably just
# run this script, and it will work with no conflicts.
location=westus
resourceGroup=ContosoResources
iotHubConsumerGroup=ContosoConsumers
containerName=contosoresults
iotDeviceName=Contoso-Test-Device

# Create the resource group to be used


# Create the resource group to be used
# for all the resources for this tutorial.
az group create --name $resourceGroup \
--location $location

# The IoT hub name must be globally unique, so add a random number to the end.
iotHubName=ContosoTestHub$RANDOM
echo "IoT hub name = " $iotHubName

# Create the IoT hub.


az iot hub create --name $iotHubName \
--resource-group $resourceGroup \
--sku S1 --location $location

# Add a consumer group to the IoT hub.


az iot hub consumer-group create --hub-name $iotHubName \
--name $iotHubConsumerGroup

# The storage account name must be globally unique, so add a random number to the end.
storageAccountName=contosostorage$RANDOM
echo "Storage account name = " $storageAccountName

# Create the storage account to be used as a routing destination.


az storage account create --name $storageAccountName \
--resource-group $resourceGroup \
--location $location \
--sku Standard_LRS

# Get the primary storage account key.


# You need this to create the container.
storageAccountKey=$(az storage account keys list \
--resource-group $resourceGroup \
--account-name $storageAccountName \
--query "[0].value" | tr -d '"')

# See the value of the storage account key.


echo "$storageAccountKey"

# Create the container in the storage account.


az storage container create --name $containerName \
--account-name $storageAccountName \
--account-key $storageAccountKey \
--public-access off

# The Service Bus namespace must be globally unique, so add a random number to the end.
sbNameSpace=ContosoSBNamespace$RANDOM
echo "Service Bus namespace = " $sbNameSpace

# Create the Service Bus namespace.


az servicebus namespace create --resource-group $resourceGroup \
--name $sbNameSpace \
--location $location

# The Service Bus queue name must be globally unique, so add a random number to the end.
sbQueueName=ContosoSBQueue$RANDOM
echo "Service Bus queue name = " $sbQueueName

# Create the Service Bus queue to be used as a routing destination.


az servicebus queue create --name $sbQueueName \
--namespace-name $sbNameSpace \
--resource-group $resourceGroup

# Create the IoT device identity to be used for testing.


az iot hub device-identity create --device-id $iotDeviceName \
--hub-name $iotHubName

# Retrieve the information about the device identity, then copy the primary key to
# Notepad. You need this to run the device simulation during the testing phase.
az iot hub device-identity show --device-id $iotDeviceName \
--hub-name $iotHubName

PowerShell instructions
The easiest way to use this script is to open PowerShell ISE, copy the script to the clipboard, and then paste the
whole script into the script window. Then you can change the values for the resource names (if you wish), and
run the entire script.

# Log into Azure account.


Login-AzureRMAccount

# Set the values for the resource names that don't have to be globally unique.
# The resources that have to have unique names are named in the script below
# with a random number concatenated to the name so you can probably just
# run this script, and it will work with no conflicts.
$location = "West US"
$resourceGroup = "ContosoResources"
$iotHubConsumerGroup = "ContosoConsumers"
$containerName = "contosoresults"
$iotDeviceName = "Contoso-Test-Device"

# Create the resource group to be used


# for all resources for this tutorial.
New-AzureRmResourceGroup -Name $resourceGroup -Location $location

# The IoT hub name must be globally unique, so add a random number to the end.
$iotHubName = "ContosoTestHub$(Get-Random)"
Write-Host "IoT hub name is " $iotHubName

# Create the IoT hub.


New-AzureRmIotHub -ResourceGroupName $resourceGroup `
-Name $iotHubName `
-SkuName "S1" `
-Location $location `
-Units 1

# Add a consumer group to the IoT hub for the 'events' endpoint.
Add-AzureRmIotHubEventHubConsumerGroup -ResourceGroupName $resourceGroup `
-Name $iotHubName `
-EventHubConsumerGroupName $iotHubConsumerGroup `
-EventHubEndpointName "events"

# The storage account name must be globally unique, so add a random number to the end.
$storageAccountName = "contosostorage$(Get-Random)"
Write-Host "storage account name is " $storageAccountName

# Create the storage account to be used as a routing destination.


# Save the context for the storage account
# to be used when creating a container.
$storageAccount = New-AzureRmStorageAccount -ResourceGroupName $resourceGroup `
-Name $storageAccountName `
-Location $location `
-SkuName Standard_LRS `
-Kind Storage
$storageContext = $storageAccount.Context

# Create the container in the storage account.


New-AzureStorageContainer -Name $containerName `
-Context $storageContext

# The Service Bus namespace must be globally unique,


# so add a random number to the end.
$serviceBusNamespace = "ContosoSBNamespace$(Get-Random)"
Write-Host "Service Bus namespace is " $serviceBusNamespace

# Create the Service Bus namespace.


New-AzureRmServiceBusNamespace -ResourceGroupName $resourceGroup `
New-AzureRmServiceBusNamespace -ResourceGroupName $resourceGroup `
-Location $location `
-Name $serviceBusNamespace

# The Service Bus queue name must be globally unique,


# so add a random number to the end.
$serviceBusQueueName = "ContosoSBQueue$(Get-Random)"
Write-Host "Service Bus queue name is " $serviceBusQueueName

# Create the Service Bus queue to be used as a routing destination.


New-AzureRmServiceBusQueue -ResourceGroupName $resourceGroup `
-Namespace $serviceBusNamespace `
-Name $serviceBusQueueName

Next, create a device identity and save its key for later use. This device identity is used by the simulation
application to send messages to the IoT hub. This capability is not available in PowerShell, but you can create
the device in the Azure portal.
1. Open the Azure portal and log into your Azure account.
2. Click on Resource groups and select your resource group. This tutorial uses ContosoResources.
3. In the list of resources, click your IoT hub. This tutorial uses ContosoTestHub. Select IoT Devices from
the Hub pane.
4. Click + Add. On the Add Device pane, fill in the device ID. This tutorial uses Contoso-Test-Device.
Leave the keys empty, and check Auto Generate Keys. Make sure Connect device to IoT hub is
enabled. Click Save.

5. Now that it's been created, click on the device to see the generated keys. Click the Copy icon on the
Primary key and save it somewhere such as Notepad for the testing phase of this tutorial.
Set up message routing
You are going to route messages to different resources based on properties attached to the message by the
simulated device. Messages that are not custom routed are sent to the default endpoint (messages/events).

VALUE RESULT

level="storage" Write to Azure Storage.

level="critical" Write to a Service Bus queue. A Logic App retrieves the


message from the queue and uses Office 365 to e-mail the
message.

default Display this data using Power BI.

Routing to a storage account


Now set up the routing for the storage account. Define an endpoint, and then set up a route for that endpoint.
Messages where the level property is set to storage are written to a storage account automatically.
1. In the Azure portal, click Resource Groups, then select your resource group. This tutorial uses
ContosoResources. Click the IoT hub under the list of resources. This tutorial uses ContosoTestHub.
Click Endpoints. In the Endpoints pane, click +Add. Enter the following information:
Name: Enter a name for the endpoint. This tutorial uses StorageContainer.
Endpoint Type: Select Azure Storage Container from the dropdown list.
Click Pick a container to see the list of storage accounts. Select your storage account. This tutorial uses
contosostorage. Next, select the container. This tutorial uses contosoresults. Click Select, which
returns you to the Add endpoint pane.
Click OK to finish adding the endpoint.
2. Click Routes on your IoT hub. You're going to create a routing rule that routes messages to the storage
container you just added as an endpoint. Click +Add at the top of the Routes pane. Fill in the fields on
the screen.
Name: Enter a name for your routing rule. This tutorial uses StorageRule.
Data source: Select Device Messages from the dropdown list.
Endpoint: Select the endpoint you just set up. This tutorial uses StorageContainer.
Query string: Enter level="storage" as the query string.
Click Save. When it finishes, it returns to the Routes pane, where you can see your new routing rule for
storage. Close the Routes pane, which returns you to the Resource group page.
Routing to a Service Bus queue
Now set up the routing for the Service Bus queue. Define an endpoint, and then set up a route for that endpoint.
Messages where the level property is set to critical are written to the Service Bus queue, which triggers a
Logic App, which then sends an e-mail with the information.
1. On the Resource group page, click your IoT hub, then click Endpoints. In the Endpoints pane, click
+Add. Enter the following information.
Name: Enter a name for the endpoint. This tutorial uses CriticalQueue.
Endpoint Type: Select Service Bus queue from the dropdown list.
Service Bus namespace: Select the Service Bus namespace for this tutorial from the dropdown list.
This tutorial uses ContosoSBNamespace.
Service Bus queue: Select the Service Bus queue from the dropdown list. This tutorial uses
contososbqueue.
Click OK to save the endpoint. After it's finished, close the Endpoints pane.
2. Click Routes on your IoT hub. You're going to create a routing rule that routes messages to the Service
Bus queue you just added as an endpoint. Click +Add at the top of the Routes pane. Fill in the fields on
the screen.
Name: Enter a name for your routing rule. This tutorial uses SBQueueRule.
Data source: Select Device Messages from the dropdown list.
Endpoint: Select the endpoint you just set up, CriticalQueue.
Query string: Enter level="critical" as the query string.
Click Save. When it returns to the Routes pane, you see both of your new routing rules, as displayed
here.

Close the Routes pane, which returns you to the Resource group page.
Create a Logic App
The Service Bus queue is to be used for receiving messages designated as critical. Set up a Logic app to monitor
the Service Bus queue, and send an e-mail when a message is added to the queue.
1. In the Azure portal, click + Create a resource. Put logic app in the search box and click Enter. From the
search results displayed, select Logic App, then click Create to continue to the Create logic app pane.
Fill in the fields.
Name: This field is the name of the logic app. This tutorial uses ContosoLogicApp.
Subscription: Select your Azure subscription.
Resource group: Click Use existing and select your resource group. This tutorial uses
ContosoResources.
Location: Use your location. This tutorial uses West US.
Log Analytics: This toggle should be turned off.

Click Create.
2. Now go to the Logic App. The easiest way to get to the Logic App is to click on Resource groups, select
your resource group (this tutorial uses ContosoResources), then select the Logic App from the list of
resources. The Logic Apps Designer page appears (you might have to scroll over to the right to see the
full page). On the Logic Apps Designer page, scroll down until you see the tile that says Blank Logic
App + and click it.
3. A list of connectors is displayed. Select Service Bus.
4. A list of triggers is displayed. Select Service Bus - When a message is received in a queue (auto-
complete).

5. On the next screen, fill in the Connection Name. This tutorial uses ContosoConnection.
Click the Service Bus namespace. This tutorial uses ContosoSBNamespace. When you select the
namespace, the portal queries the Service Bus namespace to retrieve the keys. Select
RootManageSharedAccessKey and click Create.

6. On the next screen, select the name of the queue (this tutorial uses contososbqueue) from the
dropdown list. You can use the defaults for the rest of the fields.

7. Now set up the action to send an e-mail when a message is received in the queue. In the Logic Apps
Designer, click + New step to add a step, then click Add an action. In the Choose an action pane, find
and click Office 365 Outlook. On the triggers screen, select Office 365 Outlook - Send an email.
8. Next, log into your Office 365 account to set up the connection. Specify the e-mail addresses for the
recipient(s) of the e-mails. Also specify the subject, and type what message you'd like the recipient to see
in the body. For testing, fill in your own e-mail address as the recipient.
Click Add dynamic content to show the content from the message that you can include. Select
Content -- it will include the message in the e-mail.
9. Click Save. Then close the Logic App Designer.

Set up Azure Stream Analytics


To see the data in a Power BI visualization, first set up a Stream Analytics job to retrieve the data. Remember
that only the messages where the level is normal are sent to the default endpoint, and will be retrieved by the
Stream Analytics job for the Power BI visualization.
Create the Stream Analytics job
1. In the Azure portal, click Create a resource > Internet of Things > Stream Analytics job.
2. Enter the following information for the job.
Job name: The name of the job. The name must be globally unique. This tutorial uses contosoJob.
Resource group: Use the same resource group used by your IoT hub. This tutorial uses
ContosoResources.
Location: Use the same location used in the setup script. This tutorial uses West US.
3. Click Create to create the job. To get back to the job, click Resource groups. This tutorial uses
ContosoResources. Select the resource group, then click the Stream Analytics job in the list of
resources.
Add an input to the Stream Analytics job
1. Under Job Topology, click Inputs.
2. In the Inputs pane, click Add stream input and select IoT Hub. On the screen that comes up, fill in the
following fields:
Input alias: This tutorial uses contosoinputs.
Subscription: Select your subscription.
IoT Hub: Select the IoT Hub. This tutorial uses ContosoTestHub.
Endpoint: Select Messaging. (If you select Operations Monitoring, you get the telemetry data about the
IoT hub rather than the data you're sending through.)
Shared access policy name: Select iothubowner. The portal fills in the Shared Access Policy Key for
you.
Consumer group: Select the consumer group you created earlier. This tutorial uses contosoconsumers.
For the rest of the fields, accept the defaults.
3. Click Save.
Add an output to the Stream Analytics job
1. Under Job Topology, click Outputs.
2. In the Outputs pane, click Add, and then select Power BI. On the screen that comes up, fill in the
following fields:
Output alias: The unique alias for the output. This tutorial uses contosooutputs.
Dataset name: Name of the dataset to be used in Power BI. This tutorial uses contosodataset.
Table name: Name of the table to be used in Power BI. This tutorial uses contosotable.
Accept the defaults for the rest of the fields.
3. Click Authorize, and sign into your Power BI account.
4. Click Save.
Configure the query of the Stream Analytics job
1. Under Job Topology, click Query.
2. Replace [YourInputAlias] with the input alias of the job. This tutorial uses contosoinputs.
3. Replace [YourOutputAlias] with the output alias of the job. This tutorial uses contosooutputs.

4. Click Save.
5. Close the Query pane. This returns you to the view of the resources in the Resource Group. Click the
Stream Analytics job. This tutorial calls it contosoJob.
Run the Stream Analytics job
In the Stream Analytics job, click Start > Now > Start. Once the job successfully starts, the job status changes
from Stopped to Running.
To set up the Power BI report, you need data, so you'll set up Power BI after creating the device and running the
device simulation application.

Run Simulated Device app


Earlier in the script setup section, you set up a device to simulate using an IoT device. In this section, you
download a .NET console app that simulates a device that sends device-to-cloud messages to an IoT hub. This
application sends messages for each of the different routing methods.
Download the solution for the IoT Device Simulation. This downloads a repo with several applications in it; the
solution you are looking for is in iot-hub/Tutorials/Routing/SimulatedDevice/.
Double-click on the solution file (SimulatedDevice.sln) to open the code in Visual Studio, then open Program.cs.
Substitute {iot hub hostname} with the IoT hub host name. The format of the IoT hub host name is {iot-hub-
name}.azure-devices.net. For this tutorial, the hub host name is ContosoTestHub.azure-devices.net. Next,
substitute {device key} with the device key you saved earlier when setting up the simulated device.

static string myDeviceId = "contoso-test-device";


static string iotHubUri = "ContosoTestHub.azure-devices.net";
// This is the primary key for the device. This is in the portal.
// Find your IoT hub in the portal > IoT devices > select your device > copy the key.
static string deviceKey = "{your device key here}";

Run and test


Run the console application. Wait a few minutes. You can see the messages being sent on the console screen of
the application.
The app sends a new device-to-cloud message to the IoT hub every second. The message contains a JSON -
serialized object with the device ID, temperature, humidity, and message level, which defaults to normal . It
randomly assigns a level of critical or storage , causing the message to be routed to the storage account or
to the Service Bus queue (which triggers your Logic App to send an e-mail). The default ( normal ) readings will
be displayed in the BI report you set up next.
If everything is set up correctly, at this point you should see the following results:
1. You start getting e-mails about critical messages.

This means the following:


The routing to the Service Bus queue is working correctly.
The Logic App retrieving the message from the Service Bus queue is working correctly.
The Logic App connector to Outlook is working correctly.
2. In the Azure portal, click Resource groups and select your Resource Group. This tutorial uses
ContosoResources. Select the storage account, click Blobs, then select the Container. This tutorial uses
contosoresults. You should see a folder, and you can drill down through the directories until you see one
or more files. Open one of those files; they contain the entries routed to the storage account.

This means the following:


The routing to the storage account is working correctly.
Now with the application still running, set up the Power BI visualization to see the messages coming through
the default routing.

Set up the Power BI Visualizations


1. Sign in to your Power BI account.
2. Go to Workspaces and select the workspace that you set when you created the output for the Stream
Analytics job. This tutorial uses My Workspace.
3. Click Datasets.
You should see the listed dataset that you specified when you created the output for the Stream Analytics
job. This tutorial uses contosodataset. (It may take 5-10 minutes for the dataset to show up the first
time.)
4. Under ACTIONS, click the first icon to create a report.

5. Create a line chart to show real-time temperature over time.


a. On the report creation page, add a line chart by clicking the line chart icon.
b. On the Fields pane, expand the table that you specified when you created the output for the Stream
Analytics job. This tutorial uses contosotable.
c. Drag EventEnqueuedUtcTime to Axis on the Visualizations pane.
d. Drag temperature to Values.
A line chart is created. The x-axis displays date and time in the UTC time zone. The y-axis displays
temperature from the sensor.
6. Create another line chart to show real-time humidity over time. To set up the second chart, follow the
same steps above and place EventEnqueuedUtcTime on the x-axis and humidity on the y-axis.

7. Click Save to save the report.


You should be able to see data on both charts. This means the following:
The routing to the default endpoint is working correctly.
The Azure Stream Analytics job is streaming correctly.
The Power BI Visualization is set up correctly.
You can refresh the charts to see the most recent data by clicking the Refresh button on the top of the Power BI
window.

Clean up resources
If you want to remove all of the resources you've created, delete the resource group. This action deletes all
resources contained within the group. In this case, it removes the IoT hub, the Service Bus namespace and
queue, the Logic App, the storage account, and the resource group itself.
Clean up resources in the Power BI visualization
Log into your Power BI account. Go to your workspace. This tutorial uses My Workspace. To remove the Power
BI visualization, go to DataSets and click the trash can icon to delete the dataset. This tutorial uses
contosodataset. When you remove the dataset, the report is removed as well.
Clean up resources using Azure CLI
To remove the resource group, use the az group delete command.

az group delete --name $resourceGroup

Clean up resources using PowerShell


To remove the resource group, use the Remove-AzureRmResourceGroup command. $resourceGroup was set
to ContosoIoTRG1 back at the beginning of this tutorial.

Remove-AzureRmResourceGroup -Name $resourceGroup

Next steps
In this tutorial, you learned how to use message routing to route IoT Hub messages to different destinations by
performing the following tasks.
Using Azure CLI or PowerShell, set up the base resources -- an IoT hub, a storage account, a Service Bus
queue, and a simulated device.
Configure endpoints and routes in IoT hub for the storage account and Service Bus queue.
Create a Logic App that is triggered and sends e-mail when a message is added to the Service Bus queue.
Download and run an app that simulates an IoT Device sending messages to the hub for the different
routing options.
Create a Power BI visualization for data sent to the default endpoint.
View the results ...
...in the Service Bus queue and e-mails.
...in the storage account.
...in the Power BI visualization.
Advance to the next tutorial to learn how to manage the state of an IoT device.
Configure your devices from a back-end service
Tutorial: Configure your devices from a back-end
service
5/30/2018 • 13 min to read • Edit Online

As well as receiving telemetry from your devices, you may need to configure your devices from your back-end
service. When you send a desired configuration to your devices, you may also want to receive status and
compliance updates from those devices. For example, you might set a target operational temperature range for a
device or collect firmware version information from your devices.
To synchronize state information between a device and an IoT hub, you use device twins. A device twin is a JSON
document, associated with a specific device, and stored by IoT Hub in the cloud where you can query them. A
device twin contains desired properties, reported properties, and tags. A desired property is set by a back-end
application and read by a device. A reported property is set by a device and read by a back-end application. A tag is
set by a back-end application and is never sent to a device. You use tags to organize your devices. This tutorial
shows you how to use desired and reported properties to synchronize state information:

In this tutorial, you perform the following tasks:


Create an IoT hub and add a test device to the identity registry.
Use desired properties to send state information to your simulated device.
Use reported properties to receive state information from your simulated device.

Open Azure Cloud Shell


Azure Cloud Shell is a free, interactive shell that you can use to run the steps in this article. Common Azure tools
are preinstalled and configured in Cloud Shell for you to use with your account. Just select the Copy button to
copy the code, paste it in Cloud Shell, and then press Enter to run it. There are a few ways to open Cloud Shell:
Select Try It in the upper-right corner of a code block.

Open Cloud Shell in your browser.

Select the Cloud Shell button on the menu in the upper-right


corner of the Azure portal.

If you don’t have an Azure subscription, create a free account before you begin.

Prerequisites
The two sample applications you run in this quickstart are written using Node.js. You need Node.js v4.x.x or later
on your development machine.
You can download Node.js for multiple platforms from nodejs.org.
You can verify the current version of Node.js on your development machine using the following command:

node --version

Download the sample Node.js project from https://github.com/Azure-Samples/azure-iot-samples-


node/archive/master.zip and extract the ZIP archive.

Set up Azure resources


To complete this tutorial, your Azure subscription must contain an IoT hub with a device added to the device
identity registry. The entry in the device identity registry enables the simulated device you run in this tutorial to
connect to your hub.
If you don't already have an IoT hub set up in your subscription, you can set one up with following CLI script. This
script uses the name tutorial-iot-hub for the IoT hub, you should replace this name with your own unique name
when you run it. The script creates the resource group and hub in the Central US region, which you can change to
a region closer to you. The script retrieves your IoT hub service connection string, which you use in the back-end
sample to connect to your IoT hub:

hubname=tutorial-iot-hub
location=centralus

# Install the IoT extension if it's not already installed:


az extension add --name azure-cli-iot-ext

# Create a resource group:


az group create --name tutorial-iot-hub-rg --location $location

# Create your free-tier IoT Hub. You can only have one free IoT Hub per subscription:
az iot hub create --name $hubname --location $location --resource-group tutorial-iot-hub-rg --sku S1

# Make a note of the service connection string, you need it later:


az iot hub show-connection-string --hub-name $hub-name -o table

This tutorial uses a simulated device called MyTwinDevice. The following script adds this device to your identity
registry and retrieves its connection string:
# Set the name of your IoT hub:
hubname=tutorial-iot-hub

# Create the device in the identity registry:


az iot hub device-identity create --device-id MyTwinDevice --hub-name $hubname --resource-group tutorial-iot-
hub-rg

# Retrieve the device connection string, you need this later:


az iot hub device-identity show-connection-string --device-id MyTwinDevice --hub-name $hubname --resource-
group tutorial-iot-hub-rg -o table

Send state information


You use desired properties to send state information from a back-end application to a device. In this section, you
see how to:
Receive and process desired properties on a device.
Send desired properties from a back-end application.
To view the simulated device sample code that receives desired properties, navigate to the iot-
hub/Tutorials/DeviceTwins folder in the sample Node.js project you downloaded. Then open the
SimulatedDevice.js file in a text editor.
The following sections describe the the code that runs on the simulated device that responds to desired property
changes sent from the back end application:
Retrieve the device twin object
The following code connects to your IoT hub using a device connection string:

// Get the device connection string from a command line argument


var connectionString = process.argv[2];

The following code gets a twin from the client object:

// Get the device twin


client.getTwin(function(err, twin) {
if (err) {
console.error(chalk.red('Could not get device twin'));
} else {
console.log(chalk.green('Device twin created'));

Sample desired properties


You can structure your desired properties in any way that's convenient to your application. This example uses one
top-level property called fanOn and groups the remaining properties into separate components. The following
JSON snippet shows the structure of the desired properties this tutorial uses:
{
"fanOn": "true",
"components": {
"system": {
"id": "17",
"units": "farenheit",
"firmwareVersion": "9.75"
},
"wifi" : {
"channel" : "6",
"ssid": "my_network"
},
"climate" : {
"minTemperature": "68",
"maxTemperature": "76"
}
}
}

Create handlers
You can create handlers for desired property updates that respond to updates at different levels in the JSON
hierarchy. For example, this handler sees all desired property changes sent to the device from a back-end
application. The delta variable contains the desired properties sent from the solution back end:

// Handle all desired property updates


twin.on('properties.desired', function(delta) {
console.log(chalk.yellow('\nNew desired properties received in patch:'));

The following handler only reacts to changes made to the fanOn desired property:

// Handle changes to the fanOn desired property


twin.on('properties.desired.fanOn', function(fanOn) {
console.log(chalk.green('\nSetting fan state to ' + fanOn));

// Update the reported property after processing the desired property


reportedPropertiesPatch.fanOn = fanOn ? fanOn : '{unknown}';
});

Handlers for multiple properties


In the example desired properties JSON shown previously, the climate node under components contains two
properties, minTemperature and maxTemperature.
A device's local twin object stores a complete set of desired and reported properties. The delta sent from the back
end might update just a subset of desired properties. In the following code snippet, if the simulated device receives
an update to just one of minTemperature and maxTemperature, it uses the value in the local twin for the other
value to configure the device:
// Handle desired properties updates to the climate component
twin.on('properties.desired.components.climate', function(delta) {
if (delta.minTemperature || delta.maxTemperature) {
console.log(chalk.green('\nUpdating desired tempertures in climate component:'));
console.log('Configuring minimum temperature: ' +
twin.properties.desired.components.climate.minTemperature);
console.log('Configuring maximum temperture: ' +
twin.properties.desired.components.climate.maxTemperature);

// Update the reported properties and send them to the hub


reportedPropertiesPatch.minTemperature = twin.properties.desired.components.climate.minTemperature;
reportedPropertiesPatch.maxTemperature = twin.properties.desired.components.climate.maxTemperature;
sendReportedProperties();
}
});

The local twin object stores a complete set of desired and reported properties. The delta sent from the back end
might update just a subset of desired properties.
Handle insert, update, and delete operations
The desired properties sent from the back end don't indicate what operation is being performed on a particular
desired property. Your code needs to infer the operation from the current set of desired properties stored locally
and the changes sent from the hub.
The following snippet shows how the simulated device handles insert, update, and delete operations on the list of
components in the desired properties. You can see how to use null values to indicate that a component should be
deleted:
// Keep track of all the components the device knows about
var componentList = {};

// Use this componentList list and compare it to the delta to infer


// if anything was added, deleted, or updated.
twin.on('properties.desired.components', function(delta) {
if (delta === null) {
componentList = {};
}
else {
Object.keys(delta).forEach(function(key) {

if (delta[key] === null && componentList[key]) {


// The delta contains a null value, and the
// device has a record of this component.
// Must be a delete operation.
console.log(chalk.green('\nDeleting component ' + key));
delete componentList[key];

} else if (delta[key]) {
if (componentList[key]) {
// The delta contains a component, and the
// device has a record of it.
// Must be an update operation.
console.log(chalk.green('\nUpdating component ' + key + ':'));
console.log(JSON.stringify(delta[key]));
// Store the complete object instead of just the delta
componentList[key] = twin.properties.desired.components[key];

} else {
// The delta contains a component, and the
// device has no record of it.
// Must be an add operation.
console.log(chalk.green('\nAdding component ' + key + ':'));
console.log(JSON.stringify(delta[key]));
// Store the complete object instead of just the delta
componentList[key] = twin.properties.desired.components[key];
}
}
});
}
});

Send desired properties to a device from the back end


You've seen how a device implements handlers for receiving desired property updates. This section shows you
how to send desired property changes to a device from a back-end application.
To view the simulated device sample code that receives desired properties, navigate to the iot-
hub/Tutorials/DeviceTwins folder in the sample Node.js project you downloaded. Then open the
ServiceClient.js file in a text editor.
The following code snippet shows how to connect to the device identity registry and access the twin for a specific
device:
// Create a device identity registry object
var registry = Registry.fromConnectionString(connectionString);

// Get the device twin and send desired property update patches at intervals.
// Print the reported properties after some of the desired property updates.
registry.getTwin(deviceId, async (err, twin) => {
if (err) {
console.error(err.message);
} else {
console.log('Got device twin');

The following snippet shows different desired property patches the back end application sends to the device:
// Turn the fan on
var twinPatchFanOn = {
properties: {
desired: {
patchId: "Switch fan on",
fanOn: "false",
}
}
};

// Set the maximum temperature for the climate component


var twinPatchSetMaxTemperature = {
properties: {
desired: {
patchId: "Set maximum temperature",
components: {
climate: {
maxTemperature: "92"
}
}
}
}
};

// Add a new component


var twinPatchAddWifiComponent = {
properties: {
desired: {
patchId: "Add WiFi component",
components: {
wifi: {
channel: "6",
ssid: "my_network"
}
}
}
}
};

// Update the WiFi component


var twinPatchUpdateWifiComponent = {
properties: {
desired: {
patchId: "Update WiFi component",
components: {
wifi: {
channel: "13",
ssid: "my_other_network"
}
}
}
}
};

// Delete the WiFi component


var twinPatchDeleteWifiComponent = {
properties: {
desired: {
patchId: "Delete WiFi component",
components: {
wifi: null
}
}
}
};
The following snippet shows how the back-end application sends a desired property update to a device:

// Send a desired property update patch


async function sendDesiredProperties(twin, patch) {
twin.update(patch, (err, twin) => {
if (err) {
console.error(err.message);
} else {
console.log(chalk.green(`\nSent ${twin.properties.desired.patchId} patch:`));
console.log(JSON.stringify(patch, null, 2));
}
});
}

Run the applications


In this section, you run two sample applications to observe as a back-end application sends desired property
updates to a simulated device application.
To run the simulated device and back-end applications, you need the device and service connection strings. You
made a note of the connection strings when you created the resources at the start of this tutorial.
To run the simulated device application, open a shell or command prompt window and navigate to the iot-
hub/Tutorials/DeviceTwins folder in the Node.js project you downloaded. Then run the following commands:

npm install
node SimulatedDevice.js "{your device connection string}"

To run the back-end application, open another shell or command prompt window. Then navigate to the iot-
hub/Tutorials/DeviceTwins folder in the Node.js project you downloaded. Then run the following commands:

npm install
node ServiceClient.js "{your service connection string}"

The following screenshot shows the output from the simulated device application and highlights how it handles an
update to the maxTemperature desired property. You can see how both the top-level handler and the climate
component handlers run:
The following screenshot shows the output from the back-end application and highlights how it sends an update to
the maxTemperature desired property:

Receive state information


Your back-end application receives state information from a device as reported properties. A device sets the
reported properties, and sends them to your hub. A back-end application can read the current values of the
reported properties from the device twin stored in your hub.
Send reported properties from a device
You can send updates to reported property values as a patch. The following snippet shows a template for the patch
the simulated device sends. The simulated device updates the fields in the patch before sending it to the hub:
// Create a patch to send to the hub
var reportedPropertiesPatch = {
firmwareVersion:'1.2.1',
lastPatchReceivedId: '',
fanOn:'',
minTemperature:'',
maxTemperature:''
};

The simulated device uses the following function to send the patch that contains the reported properties to the
hub:

// Send the reported properties patch to the hub


function sendReportedProperties() {
twin.properties.reported.update(reportedPropertiesPatch, function(err) {
if (err) throw err;
console.log(chalk.blue('\nTwin state reported'));
console.log(JSON.stringify(reportedPropertiesPatch, null, 2));
});
}

Process reported properties


A back-end application accesses the current reported property values for a device through the device twin. The
following snippet shows you how the back-end application reads the reported property values for the simulated
device:

// Display the reported properties from the device


function printReportedProperties(twin) {
console.log("Last received patch: " + twin.properties.reported.lastPatchReceivedId);
console.log("Firmware version: " + twin.properties.reported.firmwareVersion);
console.log("Fan status: " + twin.properties.reported.fanOn);
console.log("Min temperature set: " + twin.properties.reported.minTemperature);
console.log("Max temperature set: " + twin.properties.reported.maxTemperature);
}

Run the applications


In this section, you run two sample applications to observe as a simulated device application sends reported
property updates to a back-end application.
You run the same two sample applications that you ran to see how desired properties are sent to a device.
To run the simulated device and back-end applications, you need the device and service connection strings. You
made a note of the connection strings when you created the resources at the start of this tutorial.
To run the simulated device application, open a shell or command prompt window and navigate to the iot-
hub/Tutorials/DeviceTwins folder in the Node.js project you downloaded. Then run the following commands:

npm install
node SimulatedDevice.js "{your device connection string}"

To run the back-end application, open another shell or command prompt window. Then navigate to the iot-
hub/Tutorials/DeviceTwins folder in the Node.js project you downloaded. Then run the following commands:

npm install
node ServiceClient.js "{your service connection string}"
The following screenshot shows the output from the simulated device application and highlights how it sends a
reported property update to your hub:

The following screenshot shows the output from the back-end application and highlights how it receieves and
processes a reported property update from a device:

Clean up resources
If you plan to complete the next tutorial, leave the resource group and IoT hub and reuse them later.
If you don't need the IoT hub any longer, delete it and the resource group in the portal. To do so, select the
tutorial-iot-hub-rg resource group that contains your IoT hub and click Delete.
Alternatively, use the CLI:
# Delete your resource group and its contents
az group delete --name tutorial-iot-hub-rg

Next steps
In this tutorial, you learned how to synchronize state information between your devices and your IoT hub by
performing the following tasks:
Create an IoT hub and add a test device to the identity registry.
Use desired properties to send state information to your simulated device.
Use reported properties to receive state information from your simulated device.
Advance to the next tutorial to learn how to use device twins to implement a firmware update process.
Use a simulated device to test connectivity with your IoT hub
Tutorial: Use a simulated device to test connectivity
with your IoT hub
5/30/2018 • 8 min to read • Edit Online

In this tutorial, you use Azure IoT Hub portal tools and Azure CLI commands to test device connectivity. This
tutorial also uses a simple device simulator that you run on your desktop machine.
If you don't have an Azure subscription, create a free account before you begin.
In this tutorial, you learn how to:
Check your device authentication
Check device-to-cloud connectivity
Check cloud-to-device connectivity
Check device twin synchronization

Open Azure Cloud Shell


Azure Cloud Shell is a free, interactive shell that you can use to run the steps in this article. Common Azure tools
are preinstalled and configured in Cloud Shell for you to use with your account. Just select the Copy button to
copy the code, paste it in Cloud Shell, and then press Enter to run it. There are a few ways to open Cloud Shell:

Select Try It in the upper-right corner of a code block.

Open Cloud Shell in your browser.

Select the Cloud Shell button on the menu in the upper-right


corner of the Azure portal.

Prerequisites
The CLI scripts you run in this tutorial use the Microsoft Azure IoT Extension for Azure CLI 2.0. To install this
extension, run the following CLI command:

az extension add --name azure-cli-iot-ext

The device simulator application you run in this tutorial is written using Node.js. You need Node.js v4.x.x or later on
your development machine.
You can download Node.js for multiple platforms from nodejs.org.
You can verify the current version of Node.js on your development machine using the following command:

node --version
Download the sample device simulator Node.js project from https://github.com/Azure-Samples/iot-hub-tutorials-
node/archive/master.zip and extract the ZIP archive.

Create an IoT hub


If you created a free or standard tier IoT hub in a previous quickstart or tutorial, you can skip this step.
To create an IoT Hub using the Azure portal:
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. To create your free-tier IoT hub, use the values in the following tables:

SETTING VALUE

Subscription Select your Azure subscription in the drop-down.

Resource group Create new. This tutorial uses the name tutorials-iot-hub-
rg.

Region This tutorial uses West US. You can choose the region
closest to you.

Name The following screenshot uses the name tutorials-iot-


hub. You must choose your own unique name when you
create your hub.
SETTING VALUE

Pricing and scale tier F1 Free. You can only have one free tier hub in a
subscription.

IoT Hub units 1

4. Click Create. It can take several minutes for the hub to be created.
5. Make a note of the IoT hub name you chose. You use this value later in the tutorial.

Check device authentication


A device must authenticate with your hub before it can exchange any data with the hub. You can use the IoT
Devices tool in the Device Management section of the portal to manage your devices and check the
authentication keys they're using. In this section of the tutorial, you add a new test device, retrieve its key, and
check that the test device can connect to the hub. Later you reset the authentication key to observe what happens
when a device tries to use an outdated key. This section of the tutorial uses the Azure portal to create, manage, and
monitor a device, and the sample Node.js device simulator.
Sign in to the portal and navigate to your IoT hub. Then navigate to the IoT Devices tool:

To register a new device, click + Add, set Device ID to MyTestDevice, and click Save:
To retrieve the connection string for MyTestDevice, click on it in the list of devices and then copy the Connection
string-primary key value. The connection string includes the shared access key for the device.

To simulate MyTestDevice sending telemetry to your IoT hub, run the Node.js simulated device application you
downloaded previously.
In a terminal window on your development machine, navigate to the root folder of the sample Node.js project you
downloaded. Then navigate to the iot-hub\Tutorials\ConnectivityTests\simulated-device folder.
In the terminal window, run the following commands to install the required libraries and run the simulated device
application. Use the device connectin string you made a note of when you added the device in the portal.

npm install
node SimulatedDevice-1.js "{your device connection string}"

The terminal window displays information as it tries to connect to your hub:


You've now successfully authenticated from a device using a device key generated by your IoT hub.
Reset keys
In this section, you reset the device key and observe the error when the simulated device tries to connect.
To reset the primary device key for MyTestDevice, run the following commands:

# Generate a new Base64 encoded key using the current date


read key < <(date +%s | sha256sum | base64 | head -c 32)

# Requires the IoT Extension for Azure CLI 2.0


# az extension add --name azure-cli-iot-ext

# Reset the primary device key for MyTestDevice


az iot hub device-identity update --device-id MyTestDevice --set authentication.symmetricKey.primaryKey=$key -
-hub-name {YourIoTHubName}

In the terminal window on your development machine, run the simulated device application again:

npm install
node SimulatedDevice-1.js "{your device connection string}"

This time you see an authentication error when the application tries to connect:
Generate shared access signature (SAS ) token
If your device uses one of the IoT Hub device SDKs, the SDK library code generates the SAS token used to
authenticate with the hub. A SAS token is generated from the name of your hub, the name of your device, and the
device key.
In some scenarios, such as in a cloud protocol gateway or as part of a custom authentication scheme, you may
need to generate the SAS token yourself. To troubleshoot issues with your SAS generation code, it's useful to be
able to generate a known-good SAS token to use during testing.
To generate a known-good SAS token using the CLI, run the following command:

az iot hub generate-sas-token --device-id MyTestDevice --hub-name {YourIoTHubName}

Make a note of the full text of the generated SAS token. A SAS token looks like the following:
'SharedAccessSignature sr=tutorials-iot-hub.azure-devices.net%2Fdevices%2FMyTestDevice&sig=....&se=1524155307'

In a terminal window on your development machine, navigate to the root folder of the sample Node.js project you
downloaded. Then navigate to the iot-hub\Tutorials\ConnectivityTests\simulated-device folder.
In the terminal window, run the following commands to install the required libraries and run the simulated device
application:

npm install
node SimulatedDevice-2.js "{Your SAS token}"

The terminal window displays information as it tries to connect to your hub using the SAS token:
You've now successfully authenticated from a device using a test SAS token generated by a CLI command. The
SimulatedDevice-2.js file includes sample code that shows you how to generate a SAS token in code.
Protocols
A device can use any of the following protocols to connect to your IoT hub:

PROTOCOL OUTBOUND PORT

MQTT 8883

MQTT over WebSockets 443

AMQP 5671

AMQP over WebSockets 443

HTTPS 443

If the outbound port is blocked by a firewall, the device can't connect:


Check device-to-cloud connectivity
After a device connects, it typically tries to send telemetry to your IoT hub. This section shows you how you can
verify that the telemetry sent by the device reaches your hub.
First, retrieve the current connection string for your simulated device using the following command:

az iot hub device-identity show-connection-string --device-id MyTestDevice --output table --hub-name


{YourIoTHubName}

To run a simulated device that sends messages, navigate to the iot-


hub\Tutorials\ConnectivityTests\simulated-device folder in the code you downloaded.
In the terminal window, run the following commands to install the required libraries and run the simulated device
application:

npm install
node SimulatedDevice-3.js "{your device connection string}"

The terminal window displays information as it sends telemetry to your hub:


You can use Metrics in the portal to verify that the telemetry messages are reaching your IoT hub:

Select your IoT hub in the Resource drop-down, select Telemetry messages sent as the metric, and set the time
range to Past hour. The chart shows the aggregate count of messages sent by the simulated device:
It takes a few minutes for the metrics to become available after you start the simulated device.

Check cloud-to-device connectivity


This section shows how you can make a test direct method call to a device to check cloud-to-device connectivity.
You run a simulated device on your development machine to listen for direct method calls from your hub.
In a terminal window, use the following command to run the simulated device application:

node SimulatedDevice-3.js "{your device connection string}"

Use a CLI command to call a direct method on the device:

az iot hub invoke-device-method --device-id MyTestDevice --method-name TestMethod --timeout 10 --method-


payload '{"key":"value"}' --hub-name {YourIoTHubName}

The simulated device prints a message to the console when it receives a direct method call:
When the simulated device successfully receives the direct method call, it sends an acknowledgement back to the
hub:

Check twin synchronization


Devices use twins to synchronize state between the device and the hub. In this section, you use CLI commands to
send desired properties to a device and read the reported properties sent by the device.
The simulated device you use in this section sends reported properties to the hub whenever it starts up, and prints
desired properties to the console whenever it receives them.
In a terminal window, use the following command to run the simulated device application:

node SimulatedDevice-3.js "{your device connection string}"

To verify that the hub received the reported properties from the device, use the following CLI command:

az iot hub device-twin show --device-id MyTestDevice --hub-name {YourIoTHubName}

In the output from the command, you can see the devicelaststarted property in the reported properties section.
This property shows the date and time you last started the simulated device.
To verify that the hub can send desired property values to the device, use the following CLI command:

az iot hub device-twin update --set properties.desired='{"mydesiredproperty":"propertyvalue"}' --device-id


MyTestDevice --hub-name {YourIoTHubName}

The simulated device prints a message when it receives a desired property update from the hub:

In addition to receiving desired property changes as they're made, the simulated device automatically checks for
desired properties when it starts up.

Clean up resources
If you don't need the IoT hub any longer, delete it and the resource group in the portal. To do so, select the
tutorials-iot-hub-rg resource group that contains your IoT hub and click Delete.

Next steps
In this tutorial, you've seen how to check your device keys, check device-to-cloud connectivity, check cloud-to-
device connectivity, and check device twin synchronization. To learn more about how to monitor your IoT hub, visit
the how -to article for IoT Hub monitoring.
Monitor with diagnostics
Send messages from the cloud to your device with
IoT Hub (.NET)
5/29/2018 • 6 min to read • Edit Online

Introduction
Azure IoT Hub is a fully managed service that helps enable reliable and secure bi-directional communications
between millions of devices and a solution back end. The Get started with IoT Hub tutorial shows how to create an
IoT hub, provision a device identity in it, and code a device app that sends device-to-cloud messages.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial builds on Get started with IoT Hub. It shows you how to:
From your solution back end, send cloud-to-device messages to a single device through IoT Hub.
Receive cloud-to-device messages on a device.
From your solution back end, request delivery acknowledgement (feedback) for messages sent to a device from
IoT Hub.
You can find more information on cloud-to-device messages in the IoT Hub developer guide.
At the end of this tutorial, you run two .NET console apps:
SimulatedDevice, a modified version of the app created in Get started with IoT Hub, which connects to your
IoT hub and receives cloud-to-device messages.
SendCloudToDevice, which sends a cloud-to-device message to the device app through IoT Hub, and then
receives its delivery acknowledgement.

NOTE
IoT Hub has SDK support for many device platforms and languages (including C, Java, and Javascript) through Azure IoT
device SDKs. For step-by-step instructions on how to connect your device to this tutorial's code, and generally to Azure IoT
Hub, see the IoT Hub developer guide.

To complete this tutorial, you need the following:


Visual Studio 2015 or Visual Studio 2017
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Receive messages in the device app


In this section, you'll modify the device app you created in Get started with IoT Hub to receive cloud-to-device
messages from the IoT hub.
1. In Visual Studio, in the SimulatedDevice project, add the following method to the Program class.
private static async void ReceiveC2dAsync()
{
Console.WriteLine("\nReceiving cloud to device messages from service");
while (true)
{
Message receivedMessage = await deviceClient.ReceiveAsync();
if (receivedMessage == null) continue;

Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Received message: {0}",
Encoding.ASCII.GetString(receivedMessage.GetBytes()));
Console.ResetColor();

await deviceClient.CompleteAsync(receivedMessage);
}
}

The ReceiveAsync method asynchronously returns the received message at the time that it is received by the
device. It returns null after a specifiable timeout period (in this case, the default of one minute is used). When
the app receives a null, it should continue to wait for new messages. This requirement is the reason for the
if (receivedMessage == null) continue line.

The call to CompleteAsync() notifies IoT Hub that the message has been successfully processed. The
message can be safely removed from the device queue. If something happened that prevented the device
app from completing the processing of the message, IoT Hub delivers it again. It is then important that
message processing logic in the device app is idempotent, so that receiving the same message multiple
times produces the same result. An application can also temporarily abandon a message, which results in IoT
hub retaining the message in the queue for future consumption. Or, the application can reject a message,
which permanently removes the message from the queue. For more information about the cloud-to-device
message lifecycle, see the IoT Hub developer guide.

NOTE
When using HTTPS instead of MQTT or AMQP as a transport, the ReceiveAsync method returns immediately. The
supported pattern for cloud-to-device messages with HTTPS is intermittently connected devices that check for
messages infrequently (less than every 25 minutes). Issuing more HTTPS receives results in IoT Hub throttling the
requests. For more information about the differences between MQTT, AMQP and HTTPS support, and IoT Hub
throttling, see the IoT Hub developer guide.

2. Add the following method in the Main method, right before the Console.ReadLine() line:

ReceiveC2dAsync();

NOTE
For simplicity's sake, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Send a cloud-to-device message


In this section, you write a .NET console app that sends cloud-to-device messages to the device app.
1. In the current Visual Studio solution, create a Visual C# Desktop App project by using the Console
Application project template. Name the project SendCloudToDevice.
2. In Solution Explorer, right-click the solution, and then click Manage NuGet Packages for Solution....
This action opens the Manage NuGet Packages window.
3. Search for Microsoft.Azure.Devices, click Install, and accept the terms of use.
This downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package.
4. Add the following using statement at the top of the Program.cs file:

using Microsoft.Azure.Devices;

5. Add the following fields to the Program class. Substitute the placeholder value with the IoT hub connection
string from Get started with IoT Hub:

static ServiceClient serviceClient;


static string connectionString = "{iot hub connection string}";

6. Add the following method to the Program class:

private async static Task SendCloudToDeviceMessageAsync()


{
var commandMessage = new Message(Encoding.ASCII.GetBytes("Cloud to device message."));
await serviceClient.SendAsync("myFirstDevice", commandMessage);
}

This method sends a new cloud-to-device message to the device with the ID, myFirstDevice . Change this
parameter only if you modified it from the one used in Get started with IoT Hub.
7. Finally, add the following lines to the Main method:
Console.WriteLine("Send Cloud-to-Device message\n");
serviceClient = ServiceClient.CreateFromConnectionString(connectionString);

Console.WriteLine("Press any key to send a C2D message.");


Console.ReadLine();
SendCloudToDeviceMessageAsync().Wait();
Console.ReadLine();

8. From within Visual Studio, right-click your solution, and select Set StartUp projects.... Select Multiple startup
projects, then select the Start action for ReadDeviceToCloudMessages, SimulatedDevice, and
SendCloudToDevice.
9. Press F5. All three applications should start. Select the SendCloudToDevice windows, and press Enter.
You should see the message being received by the device app.

Receive delivery feedback


It is possible to request delivery (or expiration) acknowledgements from IoT Hub for each cloud-to-device message.
This option enables the solution back end to easily inform retry or compensation logic. For more information about
cloud-to-device feedback, see the IoT Hub developer guide.
In this section, you modify the SendCloudToDevice app to request feedback, and receive it from IoT Hub.
1. In Visual Studio, in the SendCloudToDevice project, add the following method to the Program class.

private async static void ReceiveFeedbackAsync()


{
var feedbackReceiver = serviceClient.GetFeedbackReceiver();

Console.WriteLine("\nReceiving c2d feedback from service");


while (true)
{
var feedbackBatch = await feedbackReceiver.ReceiveAsync();
if (feedbackBatch == null) continue;

Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Received feedback: {0}", string.Join(", ", feedbackBatch.Records.Select(f =>
f.StatusCode)));
Console.ResetColor();

await feedbackReceiver.CompleteAsync(feedbackBatch);
}
}

Note this receive pattern is the same one used to receive cloud-to-device messages from the device app.
2. Add the following method in the Main method, right after the
serviceClient = ServiceClient.CreateFromConnectionString(connectionString) line:
ReceiveFeedbackAsync();

3. To request feedback for the delivery of your cloud-to-device message, you have to specify a property in the
SendCloudToDeviceMessageAsync method. Add the following line, right after the
var commandMessage = new Message(...); line:

commandMessage.Ack = DeliveryAcknowledgement.Full;

4. Run the apps by pressing F5. You should see all three applications start. Select the SendCloudToDevice
windows, and press Enter. You should see the message being received by the device app, and after a few
seconds, the feedback message being received by your SendCloudToDevice application.

NOTE
For simplicity's sake, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Next steps
In this tutorial, you learned how to send and receive cloud-to-device messages.
To see examples of complete end-to-end solutions that use IoT Hub, see Azure IoT Remote Monitoring solution
accelerator.
To learn more about developing solutions with IoT Hub, see the IoT Hub developer guide.
Send cloud-to-device messages with IoT Hub (Java)
6/6/2018 • 5 min to read • Edit Online

Azure IoT Hub is a fully managed service that helps enable reliable and secure bi-directional communications
between millions of devices and a solution back end. The Get started with IoT Hub tutorial shows how to create an
IoT hub, provision a device identity in it, and code a simulated device app that sends device-to-cloud messages.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial builds on Get started with IoT Hub. It shows you how to:
From your solution back end, send cloud-to-device messages to a single device through IoT Hub.
Receive cloud-to-device messages on a device.
From your solution back end, request delivery acknowledgement (feedback) for messages sent to a device from
IoT Hub.
You can find more information on cloud-to-device messages in the IoT Hub developer guide.
At the end of this tutorial, you run two Java console apps:
simulated-device, a modified version of the app created in Get started with IoT Hub, which connects to your
IoT hub and receives cloud-to-device messages.
send-c2d-messages, which sends a cloud-to-device message to the simulated device app through IoT Hub, and
then receives its delivery acknowledgement.

NOTE
IoT Hub has SDK support for many device platforms and languages (including C, Java, and Javascript) through Azure IoT
device SDKs. For step-by-step instructions on how to connect your device to this tutorial's code, and generally to Azure IoT
Hub, see the Azure IoT Developer Center.

To complete this tutorial, you need the following:


A complete working version of the Get started with IoT Hub or Process IoT Hub device-to-cloud messages
tutorial.
The latest Java SE Development Kit 8
Maven 3
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Receive messages in the simulated device app


In this section, you modify the simulated device app you created in Get started with IoT Hub to receive cloud-to-
device messages from the IoT hub.
1. Using a text editor, open the simulated-device\src\main\java\com\mycompany\app\App.java file.
2. Add the following MessageCallback class as a nested class inside the App class. The execute method is
invoked when the device receives a message from IoT Hub. In this example, the device always notifies the
IoT hub that it has completed the message:

private static class AppMessageCallback implements MessageCallback {


public IotHubMessageResult execute(Message msg, Object context) {
System.out.println("Received message from hub: "
+ new String(msg.getBytes(), Message.DEFAULT_IOTHUB_MESSAGE_CHARSET));

return IotHubMessageResult.COMPLETE;
}
}

3. Modify the main method to create an AppMessageCallback instance and call the setMessageCallback
method before it opens the client as follows:

client = new DeviceClient(connString, protocol);

MessageCallback callback = new AppMessageCallback();


client.setMessageCallback(callback, null);
client.open();

NOTE
If you use HTTPS instead of MQTT or AMQP as the transport, the DeviceClient instance checks for messages from
IoT Hub infrequently (less than every 25 minutes). For more information about the differences between MQTT, AMQP
and HTTPS support, and IoT Hub throttling, see the IoT Hub developer guide.

4. To build the simulated-device app using Maven, execute the following command at the command prompt
in the simulated-device folder:

mvn clean package -DskipTests

Send a cloud-to-device message


In this section, you create a Java console app that sends cloud-to-device messages to the simulated device app. You
need the device ID of the device you added in the Get started with IoT Hub tutorial. You also need the IoT Hub
connection string for your hub that you can find in the Azure portal.
1. Create a Maven project called send-c2d-messages using the following command at your command
prompt. Note this command is a single, long command:

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=send-c2d-messages -


DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2. At your command prompt, navigate to the new send-c2d-messages folder.


3. Using a text editor, open the pom.xml file in the send-c2d-messages folder and add the following
dependency to the dependencies node. Adding the dependency enables you to use the iothub-java-
service-client package in your application to communicate with your IoT hub service:
<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-service-client</artifactId>
<version>1.7.23</version>
</dependency>

NOTE
You can check for the latest version of iot-service-client using Maven search.

4. Save and close the pom.xml file.


5. Using a text editor, open the send-c2d-messages\src\main\java\com\mycompany\app\App.java file.
6. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.service.*;
import java.io.IOException;
import java.net.URISyntaxException;

7. Add the following class-level variables to the App class, replacing {yourhubconnectionstring} and
{yourdeviceid} with the values your noted earlier:

private static final String connectionString = "{yourhubconnectionstring}";


private static final String deviceId = "{yourdeviceid}";
private static final IotHubServiceClientProtocol protocol = IotHubServiceClientProtocol.AMQPS;

8. Replace the main method with the following code. This code connects to your IoT hub, sends a message to
your device, and then waits for an acknowledgment that the device received and processed the message:

public static void main(String[] args) throws IOException,


URISyntaxException, Exception {
ServiceClient serviceClient = ServiceClient.createFromConnectionString(
connectionString, protocol);

if (serviceClient != null) {
serviceClient.open();
FeedbackReceiver feedbackReceiver = serviceClient
.getFeedbackReceiver();
if (feedbackReceiver != null) feedbackReceiver.open();

Message messageToSend = new Message("Cloud to device message.");


messageToSend.setDeliveryAcknowledgement(DeliveryAcknowledgement.Full);

serviceClient.send(deviceId, messageToSend);
System.out.println("Message sent to device");

FeedbackBatch feedbackBatch = feedbackReceiver.receive(10000);


if (feedbackBatch != null) {
System.out.println("Message feedback received, feedback time: "
+ feedbackBatch.getEnqueuedTimeUtc().toString());
}

if (feedbackReceiver != null) feedbackReceiver.close();


serviceClient.close();
}
}
NOTE
For simplicity's sake, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

9. To build the simulated-device app using Maven, execute the following command at the command prompt
in the simulated-device folder:

mvn clean package -DskipTests

Run the applications


You are now ready to run the applications.
1. At a command prompt in the simulated-device folder, run the following command to begin sending
telemetry to your IoT hub and to listen for cloud-to-device messages sent from your hub:

mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

2. At a command prompt in the send-c2d-messages folder, run the following command to send a cloud-to-
device message and wait for a feedback acknowledgment:

mvn exec:java -Dexec.mainClass="com.mycompany.app.App"


Next steps
In this tutorial, you learned how to send and receive cloud-to-device messages.
To see examples of complete end-to-end solutions that use IoT Hub, see Azure IoT Remote Monitoring solution
accelerator.
To learn more about developing solutions with IoT Hub, see the IoT Hub developer guide.
Send cloud-to-device messages with IoT Hub (Node)
5/29/2018 • 5 min to read • Edit Online

Introduction
Azure IoT Hub is a fully managed service that helps enable reliable and secure bi-directional communications
between millions of devices and a solution back end. The Get started with IoT Hub tutorial shows how to create an
IoT hub, provision a device identity in it, and code a simulated device app that sends device-to-cloud messages.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial builds on Get started with IoT Hub. It shows you how to:
From your solution back end, send cloud-to-device messages to a single device through IoT Hub.
Receive cloud-to-device messages on a device.
From your solution back end, request delivery acknowledgement (feedback) for messages sent to a device from
IoT Hub.
You can find more information on cloud-to-device messages in the IoT Hub developer guide.
At the end of this tutorial, you run two Node.js console apps:
SimulatedDevice, a modified version of the app created in Get started with IoT Hub, which connects to your
IoT hub and receives cloud-to-device messages.
SendCloudToDeviceMessage, which sends a cloud-to-device message to the simulated device app through
IoT Hub, and then receives its delivery acknowledgement.

NOTE
IoT Hub has SDK support for many device platforms and languages (including C, Java, and Javascript) through Azure IoT
device SDKs. For step-by-step instructions on how to connect your device to this tutorial's code, and generally to Azure IoT
Hub, see the Azure IoT Developer Center.

To complete this tutorial, you need the following:


Node.js version 4.0.x or later.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Receive messages in the simulated device app


In this section, you modify the simulated device app you created in Get started with IoT Hub to receive cloud-to-
device messages from the IoT hub.
1. Using a text editor, open the SimulatedDevice.js file.
2. Modify the connectCallback function to handle messages sent from IoT Hub. In this example, the device
always invokes the complete function to notify IoT Hub that it has processed the message. Your new
version of the connectCallback function looks like the following snippet:
var connectCallback = function (err) {
if (err) {
console.log('Could not connect: ' + err);
} else {
console.log('Client connected');
client.on('message', function (msg) {
console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);
client.complete(msg, printResultFor('completed'));
});
// Create a message and send it to the IoT Hub every second
setInterval(function(){
var temperature = 20 + (Math.random() * 15);
var humidity = 60 + (Math.random() * 20);
var data = JSON.stringify({ deviceId: 'myFirstNodeDevice', temperature: temperature, humidity:
humidity });
var message = new Message(data);
message.properties.add('temperatureAlert', (temperature > 30) ? 'true' : 'false');
console.log("Sending message: " + message.getData());
client.sendEvent(message, printResultFor('send'));
}, 1000);
}
};

NOTE
If you use HTTPS instead of MQTT or AMQP as the transport, the DeviceClient instance checks for messages from
IoT Hub infrequently (less than every 25 minutes). For more information about the differences between MQTT, AMQP
and HTTPS support, and IoT Hub throttling, see the IoT Hub developer guide.

Send a cloud-to-device message


In this section, you create a Node.js console app that sends cloud-to-device messages to the simulated device app.
You need the device ID of the device you added in the Get started with IoT Hub tutorial. You also need the IoT Hub
connection string for your hub that you can find in the Azure portal.
1. Create an empty folder called sendcloudtodevicemessage. In the sendcloudtodevicemessage folder,
create a package.json file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the sendcloudtodevicemessage folder, run the following command to install
the azure-iothub package:

npm install azure-iothub --save

3. Using a text editor, create a SendCloudToDeviceMessage.js file in the sendcloudtodevicemessage folder.


4. Add the following require statements at the start of the SendCloudToDeviceMessage.js file:

'use strict';

var Client = require('azure-iothub').Client;


var Message = require('azure-iot-common').Message;

5. Add the following code to SendCloudToDeviceMessage.js file. Replace the "{iot hub connection string}"
placeholder value with the IoT Hub connection string for the hub you created in the Get started with IoT
Hub tutorial. Replace the "{device id}" placeholder with the device ID of the device you added in the Get
started with IoT Hub tutorial:

var connectionString = '{iot hub connection string}';


var targetDevice = '{device id}';

var serviceClient = Client.fromConnectionString(connectionString);

6. Add the following function to print operation results to the console:

function printResultFor(op) {
return function printResult(err, res) {
if (err) console.log(op + ' error: ' + err.toString());
if (res) console.log(op + ' status: ' + res.constructor.name);
};
}

7. Add the following function to print delivery feedback messages to the console:

function receiveFeedback(err, receiver){


receiver.on('message', function (msg) {
console.log('Feedback message:')
console.log(msg.getData().toString('utf-8'));
});
}

8. Add the following code to send a message to your device and handle the feedback message when the device
acknowledges the cloud-to-device message:

serviceClient.open(function (err) {
if (err) {
console.error('Could not connect: ' + err.message);
} else {
console.log('Service client connected');
serviceClient.getFeedbackReceiver(receiveFeedback);
var message = new Message('Cloud to device message.');
message.ack = 'full';
message.messageId = "My Message ID";
console.log('Sending message: ' + message.getData());
serviceClient.send(targetDevice, message, printResultFor('send'));
}
});

9. Save and close SendCloudToDeviceMessage.js file.

Run the applications


You are now ready to run the applications.
1. At the command prompt in the simulateddevice folder, run the following command to send telemetry to
IoT Hub and to listen for cloud-to-device messages:

node SimulatedDevice.js
2. At a command prompt in the sendcloudtodevicemessage folder, run the following command to send a
cloud-to-device message and wait for the acknowledgment feedback:

node SendCloudToDeviceMessage.js

NOTE
For simplicity's sake, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Next steps
In this tutorial, you learned how to send and receive cloud-to-device messages.
To see examples of complete end-to-end solutions that use IoT Hub, see Azure IoT Remote Monitoring solution
accelerator.
To learn more about developing solutions with IoT Hub, see the IoT Hub developer guide.
Send cloud-to-device messages with IoT Hub
(Python)
5/29/2018 • 6 min to read • Edit Online

Introduction
Azure IoT Hub is a fully managed service that helps enable reliable and secure bi-directional communications
between millions of devices and a solution back end. The Get started with IoT Hub tutorial shows how to create an
IoT hub, provision a device identity in it, and code a simulated device app that sends device-to-cloud messages.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial builds on Get started with IoT Hub. It shows you how to:
From your solution back end, send cloud-to-device messages to a single device through IoT Hub.
Receive cloud-to-device messages on a device.
From your solution back end, request delivery acknowledgement (feedback) for messages sent to a device from
IoT Hub.
You can find more information on cloud-to-device messages in the IoT Hub developer guide.
At the end of this tutorial, you run two Python console apps:
SimulatedDevice.py, a modified version of the app created in Get started with IoT Hub, which connects to
your IoT hub and receives cloud-to-device messages.
SendCloudToDeviceMessage.py, which sends a cloud-to-device message to the simulated device app
through IoT Hub, and then receives its delivery acknowledgement.

NOTE
IoT Hub has SDK support for many device platforms and languages (including C, Java, and Javascript) through Azure IoT
device SDKs. For step-by-step instructions on how to connect your device to this tutorial's code, and generally to Azure IoT
Hub, see the Azure IoT Developer Center.

To complete this tutorial, you need the following:


Python 2.x or 3.x. Make sure to use the 32-bit or 64-bit installation as required by your setup. When prompted
during the installation, make sure to add Python to your platform-specific environment variable. If you are using
Python 2.x, you may need to install or upgrade pip, the Python package management system.
If you are using Windows OS, then Visual C++ redistributable package to allow the use of native DLLs from
Python.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)
NOTE
The pip packages for azure-iothub-service-client and azure-iothub-device-client are currently available only for
Windows OS. For Linux/Mac OS, please refer to the Linux and Mac OS-specific sections on the [Prepare your development
environment for Python][lnk-python-devbox] post.

Receive messages in the simulated device app


In this section, you create a Python console app to simulate the device and receive cloud-to-device messages from
the IoT hub.
1. Using a text editor, create a SimulatedDevice.py file.
2. Add the following import statements and variables at the start of the SimulatedDevice.py file:

import time
import sys
import iothub_client
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult
from iothub_client import IoTHubMessage, IoTHubMessageDispositionResult, IoTHubError

RECEIVE_CONTEXT = 0
WAIT_COUNT = 10
RECEIVED_COUNT = 0
RECEIVE_CALLBACKS = 0

3. Add the following code to SimulatedDevice.py file. Replace the "{deviceConnectionString}" placeholder
value with the device connection string for the device you created in the Get started with IoT Hub tutorial:

# choose AMQP or AMQP_WS as transport protocol


PROTOCOL = IoTHubTransportProvider.AMQP
CONNECTION_STRING = "{deviceConnectionString}"

4. Add the following function to print received messages to the console:


def receive_message_callback(message, counter):
global RECEIVE_CALLBACKS
message_buffer = message.get_bytearray()
size = len(message_buffer)
print ( "Received Message [%d]:" % counter )
print ( " Data: <<<%s>>> & Size=%d" % (message_buffer[:size].decode('utf-8'), size) )
map_properties = message.properties()
key_value_pair = map_properties.get_internals()
print ( " Properties: %s" % key_value_pair )
counter += 1
RECEIVE_CALLBACKS += 1
print ( " Total calls received: %d" % RECEIVE_CALLBACKS )
return IoTHubMessageDispositionResult.ACCEPTED

def iothub_client_init():
client = IoTHubClient(CONNECTION_STRING, PROTOCOL)

client.set_message_callback(receive_message_callback, RECEIVE_CONTEXT)

return client

def print_last_message_time(client):
try:
last_message = client.get_last_message_receive_time()
print ( "Last Message: %s" % time.asctime(time.localtime(last_message)) )
print ( "Actual time : %s" % time.asctime() )
except IoTHubClientError as iothub_client_error:
if iothub_client_error.args[0].result == IoTHubClientResult.INDEFINITE_TIME:
print ( "No message received" )
else:
print ( iothub_client_error )

5. Add the following code to initialize the client and wait to recieve the cloud-to-device message:

def iothub_client_init():
client = IoTHubClient(CONNECTION_STRING, PROTOCOL)

client.set_message_callback(receive_message_callback, RECEIVE_CONTEXT)

return client

def iothub_client_sample_run():
try:
client = iothub_client_init()

while True:
print ( "IoTHubClient waiting for commands, press Ctrl-C to exit" )

status_counter = 0
while status_counter <= WAIT_COUNT:
status = client.get_send_status()
print ( "Send status: %s" % status )
time.sleep(10)
status_counter += 1

except IoTHubError as iothub_error:


print ( "Unexpected error %s from IoTHub" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubClient sample stopped" )

print_last_message_time(client)

6. Add the following main function:


if __name__ == '__main__':
print ( "Starting the IoT Hub Python sample..." )
print ( " Protocol %s" % PROTOCOL )
print ( " Connection string=%s" % CONNECTION_STRING )

iothub_client_sample_run()

7. Save and close SimulatedDevice.py file.

Send a cloud-to-device message


In this section, you create a Python console app that sends cloud-to-device messages to the simulated device app.
You need the device ID of the device you added in the Get started with IoT Hub tutorial. You also need the IoT Hub
connection string for your hub that you can find in the Azure portal.
1. Using a text editor, create a SendCloudToDeviceMessage.py file.
2. Add the following import statements and variables at the start of the SendCloudToDeviceMessage.py
file:

import random
import sys
import iothub_service_client
from iothub_service_client import IoTHubMessaging, IoTHubMessage, IoTHubError

OPEN_CONTEXT = 0
FEEDBACK_CONTEXT = 1
MESSAGE_COUNT = 1
AVG_WIND_SPEED = 10.0
MSG_TXT = "{\"service client sent a message\": %.2f}"

3. Add the following code to SendCloudToDeviceMessage.py file. Replace the "{IoTHubConnectionString}"


placeholder value with the IoT Hub connection string for the hub you created in the Get started with IoT
Hub tutorial. Replace the "{deviceId}" placeholder with the device ID of the device you added in the Get
started with IoT Hub tutorial:

CONNECTION_STRING = "{IoTHubConnectionString}"
DEVICE_ID = "{deviceId}"

4. Add the following function to print feedback messages to the console:

def open_complete_callback(context):
print ( 'open_complete_callback called with context: {0}'.format(context) )

def send_complete_callback(context, messaging_result):


context = 0
print ( 'send_complete_callback called with context : {0}'.format(context) )
print ( 'messagingResult : {0}'.format(messaging_result) )

5. Add the following code to send a message to your device and handle the feedback message when the device
acknowledges the cloud-to-device message:
def iothub_messaging_sample_run():
try:
iothub_messaging = IoTHubMessaging(CONNECTION_STRING)

iothub_messaging.open(open_complete_callback, OPEN_CONTEXT)

for i in range(0, MESSAGE_COUNT):


print ( 'Sending message: {0}'.format(i) )
msg_txt_formatted = MSG_TXT % (AVG_WIND_SPEED + (random.random() * 4 + 2))
message = IoTHubMessage(bytearray(msg_txt_formatted, 'utf8'))

# optional: assign ids


message.message_id = "message_%d" % i
message.correlation_id = "correlation_%d" % i
# optional: assign properties
prop_map = message.properties()
prop_text = "PropMsg_%d" % i
prop_map.add("Property", prop_text)

iothub_messaging.send_async(DEVICE_ID, message, send_complete_callback, i)

try:
# Try Python 2.xx first
raw_input("Press Enter to continue...\n")
except:
pass
# Use Python 3.xx in the case of exception
input("Press Enter to continue...\n")

iothub_messaging.close()

except IoTHubError as iothub_error:


print ( "Unexpected error {0}" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubMessaging sample stopped" )

6. Add the following main function:

if __name__ == '__main__':
print ( "Starting the IoT Hub Service Client Messaging Python sample..." )
print ( " Connection string = {0}".format(CONNECTION_STRING) )
print ( " Device ID = {0}".format(DEVICE_ID) )

iothub_messaging_sample_run()

7. Save and close SendCloudToDeviceMessage.py file.

Run the applications


You are now ready to run the applications.
1. Open a command prompt and install the Azure IoT Hub Device SDK for Python.

pip install azure-iothub-device-client

2. At the command prompt, run the following command to listen for cloud-to-device messages:

python SimulatedDevice.py
3. Open a new command prompt and install the Azure IoT Hub Service SDK for Python.

pip install azure-iothub-service-client

4. At a command prompt, run the following command to send a cloud-to-device message and wait for the
message feedback:

python SendCloudToDeviceMessage.py

5. Note the message recieved by the device.

Next steps
In this tutorial, you learned how to send and receive cloud-to-device messages.
To see examples of complete end-to-end solutions that use IoT Hub, see Azure IoT Remote Monitoring solution
accelerator.
To learn more about developing solutions with IoT Hub, see the IoT Hub developer guide.
Get started with device management (Node)
5/29/2018 • 9 min to read • Edit Online

Back-end apps can use Azure IoT Hub primitives, such as device twin and direct methods, to remotely start and
monitor device management actions on devices. This tutorial shows you how a back-end app and a device app can
work together to initiate and monitor a remote device reboot using IoT Hub.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use a direct method to initiate device management actions (such as reboot, factory reset, and firmware update)
from a back-end app in the cloud. The device is responsible for:
Handling the method request sent from IoT Hub.
Initiating the corresponding device-specific action on the device.
Providing status updates through reported properties to IoT Hub.
You can use a back-end app in the cloud to run device twin queries to report on the progress of your device
management actions.
This tutorial shows you how to:
Use the Azure portal to create an IoT Hub and create a device identity in your IoT hub.
Create a simulated device app that contains a direct method that reboots that device. Direct methods are
invoked from the cloud.
Create a Node.js console app that calls the reboot direct method in the simulated device app through your IoT
hub.
At the end of this tutorial, you have two Node.js console apps:
dmpatterns_getstarted_device.js, which connects to your IoT hub with the device identity created earlier, receives
a reboot direct method, simulates a physical reboot, and reports the time for the last reboot.
dmpatterns_getstarted_service.js, which calls a direct method in the simulated device app, displays the response,
and displays the updated reported properties.
To complete this tutorial, you need the following:
Node.js version 4.0.x or later,
Prepare your development environment describes how to install Node.js for this tutorial on either Windows or
Linux.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device IDs
are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with the IoT
Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the device app
to connect to your IoT Hub as a device.
Refer to Getting started with IoT Hub to programmatically create device identities.

Create a simulated device app


In this section, you will
Create a Node.js console app that responds to a direct method called by the cloud
Trigger a simulated device reboot
Use the reported properties to enable device twin queries to identify devices and when they last rebooted
1. Create an empty folder called manageddevice. In the manageddevice folder, create a package.json file
using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the manageddevice folder, run the following command to install the azure-
iot-device Device SDK package and azure-iot-device-mqtt package:

npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a dmpatterns_getstarted_device.js file in the manageddevice folder.


4. Add the following 'require' statements at the start of the dmpatterns_getstarted_device.js file:

'use strict';

var Client = require('azure-iot-device').Client;


var Protocol = require('azure-iot-device-mqtt').Mqtt;

5. Add a connectionString variable and use it to create a Client instance. Replace the connection string with
your device connection string.

var connectionString = 'HostName={youriothostname};DeviceId=myDeviceId;SharedAccessKey={yourdevicekey}';


var client = Client.fromConnectionString(connectionString, Protocol);

6. Add the following function to implement the direct method on the device
var onReboot = function(request, response) {

// Respond the cloud app for the direct method


response.send(200, 'Reboot started', function(err) {
if (err) {
console.error('An error occured when sending a method response:\n' + err.toString());
} else {
console.log('Response to method \'' + request.methodName + '\' sent successfully.');
}
});

// Report the reboot before the physical restart


var date = new Date();
var patch = {
iothubDM : {
reboot : {
lastReboot : date.toISOString(),
}
}
};

// Get device Twin


client.getTwin(function(err, twin) {
if (err) {
console.error('could not get twin');
} else {
console.log('twin acquired');
twin.properties.reported.update(patch, function(err) {
if (err) throw err;
console.log('Device reboot twin state reported')
});
}
});

// Add your device's reboot API for physical restart.


console.log('Rebooting!');
};

7. Open the connection to your IoT hub and start the direct method listener:

client.open(function(err) {
if (err) {
console.error('Could not open IotHub client');
} else {
console.log('Client opened. Waiting for reboot method.');
client.onDeviceMethod('reboot', onReboot);
}
});

8. Save and close the dmpatterns_getstarted_device.js file.

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Trigger a remote reboot on the device using a direct method


In this section, you create a Node.js console app that initiates a remote reboot on a device using a direct method.
The app uses device twin queries to discover the last reboot time for that device.
1. Create an empty folder called triggerrebootondevice. In the triggerrebootondevice folder, create a
package.json file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the triggerrebootondevice folder, run the following command to install the
azure-iothub Device SDK package and azure-iot-device-mqtt package:

npm install azure-iothub --save

3. Using a text editor, create a dmpatterns_getstarted_service.js file in the triggerrebootondevice folder.


4. Add the following 'require' statements at the start of the dmpatterns_getstarted_service.js file:

'use strict';

var Registry = require('azure-iothub').Registry;


var Client = require('azure-iothub').Client;

5. Add the following variable declarations and replace the placeholder values:

var connectionString = '{iothubconnectionstring}';


var registry = Registry.fromConnectionString(connectionString);
var client = Client.fromConnectionString(connectionString);
var deviceToReboot = 'myDeviceId';

6. Add the following function to invoke the device method to reboot the target device:

var startRebootDevice = function(twin) {

var methodName = "reboot";

var methodParams = {
methodName: methodName,
payload: null,
timeoutInSeconds: 30
};

client.invokeDeviceMethod(deviceToReboot, methodParams, function(err, result) {


if (err) {
console.error("Direct method error: "+err.message);
} else {
console.log("Successfully invoked the device to reboot.");
}
});
};

7. Add the following function to query for the device and get the last reboot time:
var queryTwinLastReboot = function() {

registry.getTwin(deviceToReboot, function(err, twin){

if (twin.properties.reported.iothubDM != null)
{
if (err) {
console.error('Could not query twins: ' + err.constructor.name + ': ' + err.message);
} else {
var lastRebootTime = twin.properties.reported.iothubDM.reboot.lastReboot;
console.log('Last reboot time: ' + JSON.stringify(lastRebootTime, null, 2));
}
} else
console.log('Waiting for device to report last reboot time.');
});
};

8. Add the following code to call the functions that trigger the reboot direct method and query for the last
reboot time:

startRebootDevice();
setInterval(queryTwinLastReboot, 2000);

9. Save and close the dmpatterns_getstarted_service.js file.

Run the apps


You are now ready to run the apps.
1. At the command prompt in the manageddevice folder, run the following command to begin listening for
the reboot direct method.

node dmpatterns_getstarted_device.js

2. At the command prompt in the triggerrebootondevice folder, run the following command to trigger the
remote reboot and query for the device twin to find the last reboot time.

node dmpatterns_getstarted_service.js

3. You see the device response to the direct method in the console.

Customize and extend the device management actions


Your IoT solutions can expand the defined set of device management patterns or enable custom patterns by using
the device twin and cloud-to-device method primitives. Other examples of device management actions include
factory reset, firmware update, software update, power management, network and connectivity management, and
data encryption.

Device maintenance windows


Typically, you configure devices to perform actions at a time that minimizes interruptions and downtime. Device
maintenance windows are a commonly used pattern to define the time when a device should update its
configuration. Your back-end solutions can use the desired properties of the device twin to define and activate a
policy on your device that enables a maintenance window. When a device receives the maintenance window policy,
it can use the reported property of the device twin to report the status of the policy. The back-end app can then use
device twin queries to attest to compliance of devices and each policy.

Next steps
In this tutorial, you used a direct method to trigger a remote reboot on a device. You used the reported properties
to report the last reboot time from the device, and queried the device twin to discover the last reboot time of the
device from the cloud.
To continue getting started with IoT Hub and device management patterns such as remote over the air firmware
update, see:
Tutorial: How to do a firmware update
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
To continue getting started with IoT Hub, see Getting started with IoT Edge.
Get started with device management (.NET/Node)
5/29/2018 • 9 min to read • Edit Online

Back-end apps can use Azure IoT Hub primitives, such as device twin and direct methods, to remotely start and
monitor device management actions on devices. This tutorial shows you how a back-end app and a device app can
work together to initiate and monitor a remote device reboot using IoT Hub.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use a direct method to initiate device management actions (such as reboot, factory reset, and firmware update)
from a back-end app in the cloud. The device is responsible for:
Handling the method request sent from IoT Hub.
Initiating the corresponding device-specific action on the device.
Providing status updates through reported properties to IoT Hub.
You can use a back-end app in the cloud to run device twin queries to report on the progress of your device
management actions.
This tutorial shows you how to:
Use the Azure portal to create an IoT Hub and create a device identity in your IoT hub.
Create a simulated device app that contains a direct method that reboots that device. Direct methods are
invoked from the cloud.
Create a .NET console app that calls the reboot direct method in the simulated device app through your IoT hub.
At the end of this tutorial, you have a Node.js console device app and a .NET (C#) console back-end app:
dmpatterns_getstarted_device.js, which connects to your IoT hub with the device identity created earlier, receives
a reboot direct method, simulates a physical reboot, and reports the time for the last reboot.
TriggerReboot, which calls a direct method in the simulated device app, displays the response, and displays the
updated reported properties.
To complete this tutorial, you need the following:
Visual Studio 2015 or Visual Studio 2017.
Node.js version 4.0.x or later,
Prepare your development environment describes how to install Node.js for this tutorial on either Windows or
Linux.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device IDs
are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with the IoT
Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the device app
to connect to your IoT Hub as a device.
Refer to Getting started with IoT Hub to programmatically create device identities.

Trigger a remote reboot on the device using a direct method


In this section, you create a .NET console app (using C#) that initiates a remote reboot on a device using a direct
method. The app uses device twin queries to discover the last reboot time for that device.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to a new solution by using the Console
App (.NET Framework) project template. Make sure the .NET Framework version is 4.5.1 or later. Name
the project TriggerReboot.

2. In Solution Explorer, right-click the TriggerReboot project, and then click Manage NuGet Packages.
3. In the NuGet Package Manager window, select Browse, search for microsoft.azure.devices, select
Install to install the Microsoft.Azure.Devices package, and accept the terms of use. This procedure
downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package and its dependencies.
4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;

5. Add the following fields to the Program class. Replace the placeholder value with the IoT Hub connection
string for the hub that you created in the section "Create an IoT hub."

static RegistryManager registryManager;


static string connString = "{iot hub connection string}";
static ServiceClient client;
static JobClient jobClient;
static string targetDevice = "myDeviceId";

6. Add the following method to the Program class. This code gets the device twin for the rebooting device and
outputs the reported properties.

public static async Task QueryTwinRebootReported()


{
Twin twin = await registryManager.GetTwinAsync(targetDevice);
Console.WriteLine(twin.Properties.Reported.ToJson());
}

7. Add the following method to the Program class. This code initiates the reboot on the device using a direct
method.

public static async Task StartReboot()


{
client = ServiceClient.CreateFromConnectionString(connString);
CloudToDeviceMethod method = new CloudToDeviceMethod("reboot");
method.ResponseTimeout = TimeSpan.FromSeconds(30);

CloudToDeviceMethodResult result = await client.InvokeDeviceMethodAsync(targetDevice, method);

Console.WriteLine("Invoked firmware update on device.");


}
8. Finally, add the following lines to the Main method:

registryManager = RegistryManager.CreateFromConnectionString(connString);
StartReboot().Wait();
QueryTwinRebootReported().Wait();
Console.WriteLine("Press ENTER to exit.");
Console.ReadLine();

9. Build the solution.

Create a simulated device app


In this section, you will
Create a Node.js console app that responds to a direct method called by the cloud
Trigger a simulated device reboot
Use the reported properties to enable device twin queries to identify devices and when they last rebooted
1. Create a new empty folder called manageddevice. In the manageddevice folder, create a package.json file
using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the manageddevice folder, run the following command to install the azure-
iot-device Device SDK package and azure-iot-device-mqtt package:

npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a new dmpatterns_getstarted_device.js file in the manageddevice folder.
4. Add the following 'require' statements at the start of the dmpatterns_getstarted_device.js file:

'use strict';

var Client = require('azure-iot-device').Client;


var Protocol = require('azure-iot-device-mqtt').Mqtt;

5. Add a connectionString variable and use it to create a Client instance. Replace the connection string with
your device connection string.

var connectionString = 'HostName={youriothostname};DeviceId=myDeviceId;SharedAccessKey={yourdevicekey}';


var client = Client.fromConnectionString(connectionString, Protocol);

6. Add the following function to implement the direct method on the device
var onReboot = function(request, response) {

// Respond the cloud app for the direct method


response.send(200, 'Reboot started', function(err) {
if (!err) {
console.error('An error occured when sending a method response:\n' + err.toString());
} else {
console.log('Response to method \'' + request.methodName + '\' sent successfully.');
}
});

// Report the reboot before the physical restart


var date = new Date();
var patch = {
iothubDM : {
reboot : {
lastReboot : date.toISOString(),
}
}
};

// Get device Twin


client.getTwin(function(err, twin) {
if (err) {
console.error('could not get twin');
} else {
console.log('twin acquired');
twin.properties.reported.update(patch, function(err) {
if (err) throw err;
console.log('Device reboot twin state reported')
});
}
});

// Add your device's reboot API for physical restart.


console.log('Rebooting!');
};

7. Add the following code to open the connection to your IoT hub and start the direct method listener:

client.open(function(err) {
if (err) {
console.error('Could not open IotHub client');
} else {
console.log('Client opened. Waiting for reboot method.');
client.onDeviceMethod('reboot', onReboot);
}
});

8. Save and close the dmpatterns_getstarted_device.js file.

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Run the apps


You are now ready to run the apps.
1. At the command prompt in the manageddevice folder, run the following command to begin listening for
the reboot direct method.

node dmpatterns_getstarted_device.js

2. Run the C# console app TriggerReboot. Right-click the TriggerReboot project, select Debug, and then
select Start new instance.
3. You see the device response to the direct method in the console.

Customize and extend the device management actions


Your IoT solutions can expand the defined set of device management patterns or enable custom patterns by using
the device twin and cloud-to-device method primitives. Other examples of device management actions include
factory reset, firmware update, software update, power management, network and connectivity management, and
data encryption.

Device maintenance windows


Typically, you configure devices to perform actions at a time that minimizes interruptions and downtime. Device
maintenance windows are a commonly used pattern to define the time when a device should update its
configuration. Your back-end solutions can use the desired properties of the device twin to define and activate a
policy on your device that enables a maintenance window. When a device receives the maintenance window policy,
it can use the reported property of the device twin to report the status of the policy. The back-end app can then use
device twin queries to attest to compliance of devices and each policy.

Next steps
In this tutorial, you used a direct method to trigger a remote reboot on a device. You used the reported properties
to report the last reboot time from the device, and queried the device twin to discover the last reboot time of the
device from the cloud.
To continue getting started with IoT Hub and device management patterns such as remote over the air firmware
update, see:
Tutorial: How to do a firmware update
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
To continue getting started with IoT Hub, see Getting started with IoT Edge.
Get started with device management (.NET/.NET)
5/29/2018 • 10 min to read • Edit Online

Back-end apps can use Azure IoT Hub primitives, such as device twin and direct methods, to remotely start and
monitor device management actions on devices. This tutorial shows you how a back-end app and a device app can
work together to initiate and monitor a remote device reboot using IoT Hub.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use a direct method to initiate device management actions (such as reboot, factory reset, and firmware update)
from a back-end app in the cloud. The device is responsible for:
Handling the method request sent from IoT Hub.
Initiating the corresponding device-specific action on the device.
Providing status updates through reported properties to IoT Hub.
You can use a back-end app in the cloud to run device twin queries to report on the progress of your device
management actions.
This tutorial shows you how to:
Use the Azure portal to create an IoT Hub and create a device identity in your IoT hub.
Create a simulated device app that contains a direct method that reboots that device. Direct methods are
invoked from the cloud.
Create a .NET console app that calls the reboot direct method in the simulated device app through your IoT hub.
At the end of this tutorial, you have two .NET console apps:
SimulateManagedDevice, which connects to your IoT hub with the device identity created earlier, receives a
reboot direct method, simulates a physical reboot, and reports the time for the last reboot.
TriggerReboot, which calls a direct method in the simulated device app, displays the response, and displays the
updated reported properties.
To complete this tutorial, you need the following:
Visual Studio 2015 or Visual Studio 2017.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A device
cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the "Identity
registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a unique
device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new device
identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and keys
to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device. If your
application needs to store other device-specific metadata, it should use an application-specific store. For more information,
see IoT Hub developer guide.

Trigger a remote reboot on the device using a direct method


In this section, you create a .NET console app (using C#) that initiates a remote reboot on a device using a direct
method. The app uses device twin queries to discover the last reboot time for that device.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to a new solution by using the Console
App (.NET Framework) project template. Make sure the .NET Framework version is 4.5.1 or later. Name
the project TriggerReboot.

2. In Solution Explorer, right-click the TriggerReboot project, and then click Manage NuGet Packages.
3. In the NuGet Package Manager window, select Browse, search for microsoft.azure.devices, select
Install to install the Microsoft.Azure.Devices package, and accept the terms of use. This procedure
downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package and its dependencies.
4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;

5. Add the following fields to the Program class. Replace the placeholder value with the IoT Hub connection
string for the hub that you created in the section "Create an IoT hub."

static RegistryManager registryManager;


static string connString = "{iot hub connection string}";
static ServiceClient client;
static string targetDevice = "myDeviceId";

6. Add the following method to the Program class. This code gets the device twin for the rebooting device and
outputs the reported properties.

public static async Task QueryTwinRebootReported()


{
Twin twin = await registryManager.GetTwinAsync(targetDevice);
Console.WriteLine(twin.Properties.Reported.ToJson());
}

7. Add the following method to the Program class. This code initiates the reboot on the device using a direct
method.

public static async Task StartReboot()


{
client = ServiceClient.CreateFromConnectionString(connString);
CloudToDeviceMethod method = new CloudToDeviceMethod("reboot");
method.ResponseTimeout = TimeSpan.FromSeconds(30);

CloudToDeviceMethodResult result = await client.InvokeDeviceMethodAsync(targetDevice, method);

Console.WriteLine("Invoked firmware update on device.");


}

8. Finally, add the following lines to the Main method:


registryManager = RegistryManager.CreateFromConnectionString(connString);
StartReboot().Wait();
QueryTwinRebootReported().Wait();
Console.WriteLine("Press ENTER to exit.");
Console.ReadLine();

9. Build the solution.

NOTE
This tutorial performs only a single query for the device's reported properties. In production code, we recommend polling to
detect changes in the reported properties.

Create a simulated device app


In this section, you will
Create a .NET console app that responds to a direct method called by the cloud
Trigger a simulated device reboot
Use the reported properties to enable device twin queries to identify devices and when they last rebooted
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project SimulateManagedDevice.

2. In Solution Explorer, right-click the SimulateManagedDevice project, and then click Manage NuGet
Packages....
3. In the NuGet Package Manager window, select Browse and search for microsoft.azure.devices.client.
Select Install to install the Microsoft.Azure.Devices.Client package, and accept the terms of use. This
procedure downloads, installs, and adds a reference to the Azure IoT device SDK NuGet package and its
dependencies.
4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;

5. Add the following fields to the Program class. Replace the placeholder value with the device connection
string that you noted in the previous section.

static string DeviceConnectionString = "HostName=<yourIotHubName>.azure-devices.net;DeviceId=


<yourIotDeviceName>;SharedAccessKey=<yourIotDeviceAccessKey>";
static DeviceClient Client = null;

6. Add the following to implement the direct method on the device:

static Task<MethodResponse> onReboot(MethodRequest methodRequest, object userContext)


{
// In a production device, you would trigger a reboot scheduled to start after this method returns
// For this sample, we simulate the reboot by writing to the console and updating the reported
properties
try
{
Console.WriteLine("Rebooting!");

// Update device twin with reboot time.


TwinCollection reportedProperties, reboot, lastReboot;
lastReboot = new TwinCollection();
reboot = new TwinCollection();
reportedProperties = new TwinCollection();
lastReboot["lastReboot"] = DateTime.Now;
reboot["reboot"] = lastReboot;
reportedProperties["iothubDM"] = reboot;
Client.UpdateReportedPropertiesAsync(reportedProperties).Wait();
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}

string result = "'Reboot started.'";


return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200));
}

7. Finally, add the following code to the Main method to open the connection to your IoT hub and initialize the
method listener:
try
{
Console.WriteLine("Connecting to hub");
Client = DeviceClient.CreateFromConnectionString(DeviceConnectionString, TransportType.Mqtt);

// setup callback for "reboot" method


Client.SetMethodHandlerAsync("reboot", onReboot, null).Wait();
Console.WriteLine("Waiting for reboot method\n Press enter to exit.");
Console.ReadLine();

Console.WriteLine("Exiting...");

// as a good practice, remove the "reboot" handler


Client.SetMethodHandlerAsync("reboot", null, null).Wait();
Client.CloseAsync().Wait();
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}

8. In the Visual Studio Solution Explorer, right-click your solution, and then click Set StartUp Projects.... Select
Single startup project, and then select the SimulateManagedDevice project in the dropdown menu.
Build the solution.

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Run the apps


You are now ready to run the apps.
1. Run the .NET device app SimulateManagedDevice. Right-click the SimulateManagedDevice project,
select Debug, and then select Start new instance. It should start listening for method calls from your IoT
Hub:
2. Now that the device is connected and waiting for method invocations, run the .NET TriggerReboot app to
invoke the reboot method in the simulated device app. Right-click the TriggerReboot project, select Debug,
and then select Start new instance. You should see "Rebooting!" written in the
SimulatedManagedDevice console and the reported properties of the device, which include the last
reboot time, written in the TriggerReboot console.

Customize and extend the device management actions


Your IoT solutions can expand the defined set of device management patterns or enable custom patterns by using
the device twin and cloud-to-device method primitives. Other examples of device management actions include
factory reset, firmware update, software update, power management, network and connectivity management, and
data encryption.

Device maintenance windows


Typically, you configure devices to perform actions at a time that minimizes interruptions and downtime. Device
maintenance windows are a commonly used pattern to define the time when a device should update its
configuration. Your back-end solutions can use the desired properties of the device twin to define and activate a
policy on your device that enables a maintenance window. When a device receives the maintenance window policy,
it can use the reported property of the device twin to report the status of the policy. The back-end app can then use
device twin queries to attest to compliance of devices and each policy.

Next steps
In this tutorial, you used a direct method to trigger a remote reboot on a device. You used the reported properties
to report the last reboot time from the device, and queried the device twin to discover the last reboot time of the
device from the cloud.
To continue getting started with IoT Hub and device management patterns such as remote over the air firmware
update, see:
Tutorial: How to do a firmware update
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
To continue getting started with IoT Hub, see Getting started with IoT Edge.
Get started with device management (Java)
5/29/2018 • 12 min to read • Edit Online

Back-end apps can use Azure IoT Hub primitives, such as device twin and direct methods, to remotely start and
monitor device management actions on devices. This tutorial shows you how a back-end app and a device app can
work together to initiate and monitor a remote device reboot using IoT Hub.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use a direct method to initiate device management actions (such as reboot, factory reset, and firmware update)
from a back-end app in the cloud. The device is responsible for:
Handling the method request sent from IoT Hub.
Initiating the corresponding device-specific action on the device.
Providing status updates through reported properties to IoT Hub.
You can use a back-end app in the cloud to run device twin queries to report on the progress of your device
management actions.
This tutorial shows you how to:
Use the Azure portal to create an IoT Hub and create a device identity in your IoT hub.
Create a simulated device app that implements a direct method to reboot the device. Direct methods are
invoked from the cloud.
Create an app that invokes the reboot direct method in the simulated device app through your IoT hub. This app
then monitors the reported properties from the device to see when the reboot operation is complete.
At the end of this tutorial, you have two Java console apps:
simulated-device. This app:
Connects to your IoT hub with the device identity created earlier.
Receives a reboot direct method call.
Simulates a physical reboot.
Reports the time of the last reboot through a reported property.
trigger-reboot. This app:
Calls a direct method in the simulated device app.
Displays the response to the direct method call sent by the simulated device
Displays the updated reported properties.

NOTE
For information about the SDKs that you can use to build applications to run on devices and your solution back end, see
Azure IoT SDKs.

To complete this tutorial, you need:


Java SE 8.
Prepare your development environment describes how to install Java for this tutorial on either Windows or
Linux.
Maven 3.
Prepare your development environment describes how to install Maven for this tutorial on either Windows or
Linux.
Node.js version 0.10.0 or later.

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device IDs
are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with the IoT
Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the device app
to connect to your IoT Hub as a device.
Refer to Getting started with IoT Hub to programmatically create device identities.

Trigger a remote reboot on the device using a direct method


In this section, you create a Java console app that:
1. Invokes the reboot direct method in the simulated device app.
2. Displays the response.
3. Polls the reported properties sent from the device to determine when the reboot is complete.
This console app connects to your IoT Hub to invoke the direct method and read the reported properties.
1. Create an empty folder called dm-get-started.
2. In the dm-get-started folder, create a Maven project called trigger-reboot using the following command at
your command prompt. The following shows a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=trigger-reboot -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

3. At your command prompt, navigate to the trigger-reboot folder.


4. Using a text editor, open the pom.xml file in the trigger-reboot folder and add the following dependency to
the dependencies node. This dependency enables you to use the iot-service-client package in your app to
communicate with your IoT hub:

<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-service-client</artifactId>
<version>1.7.23</version>
<type>jar</type>
</dependency>

NOTE
You can check for the latest version of iot-service-client using Maven search.

5. Add the following build node after the dependencies node. This configuration instructs Maven to use Java
1.8 to build the app:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

6. Save and close the pom.xml file.


7. Using a text editor, open the trigger-reboot\src\main\java\com\mycompany\app\App.java source file.
8. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceMethod;
import com.microsoft.azure.sdk.iot.service.devicetwin.MethodResult;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;
import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwin;
import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwinDevice;

import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;

9. Add the following class-level variables to the App class. Replace {youriothubconnectionstring} with your IoT
hub connection string you noted in the Create an IoT Hub section:

public static final String iotHubConnectionString = "{youriothubconnectionstring}";


public static final String deviceId = "myDeviceId";

private static final String methodName = "reboot";


private static final Long responseTimeout = TimeUnit.SECONDS.toSeconds(30);
private static final Long connectTimeout = TimeUnit.SECONDS.toSeconds(5);

10. To implement a thread that reads the reported properties from the device twin every 10 seconds, add the
following nested class to the App class:

private static class ShowReportedProperties implements Runnable {


public void run() {
try {
DeviceTwin deviceTwins = DeviceTwin.createFromConnectionString(iotHubConnectionString);
DeviceTwinDevice twinDevice = new DeviceTwinDevice(deviceId);
while (true) {
System.out.println("Get reported properties from device twin");
deviceTwins.getTwin(twinDevice);
System.out.println(twinDevice.reportedPropertiesToString());
Thread.sleep(10000);
}
} catch (Exception ex) {
System.out.println("Exception reading reported properties: " + ex.getMessage());
}
}
}
11. Modify the signature of the main method to throw the following exception:

public static void main(String[] args) throws IOException

12. To invoke the reboot direct method on the simulated device, add the following code to the main method:

System.out.println("Starting sample...");
DeviceMethod methodClient = DeviceMethod.createFromConnectionString(iotHubConnectionString);

try
{
System.out.println("Invoke reboot direct method");
MethodResult result = methodClient.invoke(deviceId, methodName, responseTimeout, connectTimeout,
null);

if(result == null)
{
throw new IOException("Invoke direct method reboot returns null");
}
System.out.println("Invoked reboot on device");
System.out.println("Status for device: " + result.getStatus());
System.out.println("Message from device: " + result.getPayload());
}
catch (IotHubException e)
{
System.out.println(e.getMessage());
}

13. To start the thread to poll the reported properties from the simulated device, add the following code to the
main method:

ShowReportedProperties showReportedProperties = new ShowReportedProperties();


ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(showReportedProperties);

14. To enable you to stop the app, add the following code to the main method:

System.out.println("Press ENTER to exit.");


System.in.read();
executor.shutdownNow();
System.out.println("Shutting down sample...");

15. Save and close the trigger-reboot\src\main\java\com\mycompany\app\App.java file.


16. Build the trigger-reboot back-end app and correct any errors. At your command prompt, navigate to the
trigger-reboot folder and run the following command:
mvn clean package -DskipTests

Create a simulated device app


In this section, you create a Java console app that simulates a device. The app listens for the reboot direct method
call from your IoT hub and immediately responds to that call. The app then sleeps for a while to simulate the reboot
process before it uses a reported property to notify the trigger-reboot back-end app that the reboot is complete.
1. In the dm-get-started folder, create a Maven project called simulated-device using the following command
at your command prompt. The following is a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=simulated-device -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2. At your command prompt, navigate to the simulated-device folder.


3. Using a text editor, open the pom.xml file in the simulated-device folder and add the following dependency
to the dependencies node. This dependency enables you to use the iot-service-client package in your app
to communicate with your IoT hub:

<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-device-client</artifactId>
<version>1.3.32</version>
</dependency>

NOTE
You can check for the latest version of iot-device-client using Maven search.

4. Add the following build node after the dependencies node. This configuration instructs Maven to use Java
1.8 to build the app:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

5. Save and close the pom.xml file.


6. Using a text editor, open the simulated-device\src\main\java\com\mycompany\app\App.java source file.
7. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.device.*;
import com.microsoft.azure.sdk.iot.device.DeviceTwin.*;

import java.io.IOException;
import java.net.URISyntaxException;
import java.time.LocalDateTime;
import java.util.Scanner;
import java.util.Set;
import java.util.HashSet;

8. Add the following class-level variables to the App class. Replace {yourdeviceconnectionstring} with the
device connection string you noted in the Create a device identity section:
private static final int METHOD_SUCCESS = 200;
private static final int METHOD_NOT_DEFINED = 404;

private static IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;


private static String connString = "{yourdeviceconnectionstring}";
private static DeviceClient client;

9. To implement a callback handler for direct method status events, add the following nested class to the App
class:

protected static class DirectMethodStatusCallback implements IotHubEventCallback


{
public void execute(IotHubStatusCode status, Object context)
{
System.out.println("IoT Hub responded to device method operation with status " + status.name());
}
}

10. To implement a callback handler for device twin status events, add the following nested class to the App
class:

protected static class DeviceTwinStatusCallback implements IotHubEventCallback


{
public void execute(IotHubStatusCode status, Object context)
{
System.out.println("IoT Hub responded to device twin operation with status " + status.name());
}
}

11. To implement a callback handler for property events, add the following nested class to the App class:

protected static class PropertyCallback implements PropertyCallBack<String, String>


{
public void PropertyCall(String propertyKey, String propertyValue, Object context)
{
System.out.println("PropertyKey: " + propertyKey);
System.out.println("PropertyKvalue: " + propertyKey);
}
}

12. To implement a thread to simulate the device reboot, add the following nested class to the App class. The
thread sleeps for five seconds and then sets the lastReboot reported property:
protected static class RebootDeviceThread implements Runnable {
public void run() {
try {
System.out.println("Rebooting...");
Thread.sleep(5000);
Property property = new Property("lastReboot", LocalDateTime.now());
Set<Property> properties = new HashSet<Property>();
properties.add(property);
client.sendReportedProperties(properties);
System.out.println("Rebooted");
}
catch (Exception ex) {
System.out.println("Exception in reboot thread: " + ex.getMessage());
}
}
}

13. To implement the direct method on the device, add the following nested class to the App class. When the
simulated app receives a call to the reboot direct method, it returns an acknowledgement to the caller and
then starts a thread to process the reboot:

protected static class DirectMethodCallback implements


com.microsoft.azure.sdk.iot.device.DeviceTwin.DeviceMethodCallback
{
@Override
public DeviceMethodData call(String methodName, Object methodData, Object context)
{
DeviceMethodData deviceMethodData;
switch (methodName)
{
case "reboot" :
{
int status = METHOD_SUCCESS;
System.out.println("Received reboot request");
deviceMethodData = new DeviceMethodData(status, "Started reboot");
RebootDeviceThread rebootThread = new RebootDeviceThread();
Thread t = new Thread(rebootThread);
t.start();
break;
}
default:
{
int status = METHOD_NOT_DEFINED;
deviceMethodData = new DeviceMethodData(status, "Not defined direct method " + methodName);
}
}
return deviceMethodData;
}
}

14. Modify the signature of the main method to throw the following exceptions:

public static void main(String[] args) throws IOException, URISyntaxException

15. To instantiate a DeviceClient, add the following code to the main method:

System.out.println("Starting device client sample...");


client = new DeviceClient(connString, protocol);

16. To start listening for direct method calls, add the following code to the main method:
try
{
client.open();
client.subscribeToDeviceMethod(new DirectMethodCallback(), null, new DirectMethodStatusCallback(),
null);
client.startDeviceTwin(new DeviceTwinStatusCallback(), null, new PropertyCallback(), null);
System.out.println("Subscribed to direct methods and polling for reported properties. Waiting...");
}
catch (Exception e)
{
System.out.println("On exception, shutting down \n" + " Cause: " + e.getCause() + " \n" +
e.getMessage());
client.close();
System.out.println("Shutting down...");
}

17. To shut down the device simulator, add the following code to the main method:

System.out.println("Press any key to exit...");


Scanner scanner = new Scanner(System.in);
scanner.nextLine();
scanner.close();
client.close();
System.out.println("Shutting down...");

18. Save and close the simulated-device\src\main\java\com\mycompany\app\App.java file.


19. Build the simulated-device back-end app and correct any errors. At your command prompt, navigate to the
simulated-device folder and run the following command:
mvn clean package -DskipTests

Run the apps


You are now ready to run the apps.
1. At a command prompt in the simulated-device folder, run the following command to begin listening for
reboot method calls from your IoT hub:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
2. At a command prompt in the trigger-reboot folder, run the following command to call the reboot method on
your simulated device from your IoT hub:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

3. The simulated device responds to the reboot direct method call:

Customize and extend the device management actions


Your IoT solutions can expand the defined set of device management patterns or enable custom patterns by using
the device twin and cloud-to-device method primitives. Other examples of device management actions include
factory reset, firmware update, software update, power management, network and connectivity management, and
data encryption.

Device maintenance windows


Typically, you configure devices to perform actions at a time that minimizes interruptions and downtime. Device
maintenance windows are a commonly used pattern to define the time when a device should update its
configuration. Your back-end solutions can use the desired properties of the device twin to define and activate a
policy on your device that enables a maintenance window. When a device receives the maintenance window policy,
it can use the reported property of the device twin to report the status of the policy. The back-end app can then use
device twin queries to attest to compliance of devices and each policy.

Next steps
In this tutorial, you used a direct method to trigger a remote reboot on a device. You used the reported properties
to report the last reboot time from the device, and queried the device twin to discover the last reboot time of the
device from the cloud.
To continue getting started with IoT Hub and device management patterns such as remote over the air firmware
update, see:
Tutorial: How to do a firmware update
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
To continue getting started with IoT Hub, see Getting started with IoT Edge.
Get started with device management (Python)
5/29/2018 • 9 min to read • Edit Online

Back-end apps can use Azure IoT Hub primitives, such as device twin and direct methods, to remotely start and
monitor device management actions on devices. This tutorial shows you how a back-end app and a device app can
work together to initiate and monitor a remote device reboot using IoT Hub.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use a direct method to initiate device management actions (such as reboot, factory reset, and firmware update)
from a back-end app in the cloud. The device is responsible for:
Handling the method request sent from IoT Hub.
Initiating the corresponding device-specific action on the device.
Providing status updates through reported properties to IoT Hub.
You can use a back-end app in the cloud to run device twin queries to report on the progress of your device
management actions.
This tutorial shows you how to:
Use the Azure portal to create an IoT Hub and create a device identity in your IoT hub.
Create a simulated device app that contains a direct method that reboots that device. Direct methods are
invoked from the cloud.
Create a Python console app that calls the reboot direct method in the simulated device app through your IoT
hub.
At the end of this tutorial, you have two Python console apps:
dmpatterns_getstarted_device.py, which connects to your IoT hub with the device identity created earlier,
receives a reboot direct method, simulates a physical reboot, and reports the time for the last reboot.
dmpatterns_getstarted_service.py, which calls a direct method in the simulated device app, displays the
response, and displays the updated reported properties.
To complete this tutorial, you need the following:
Python 2.x or 3.x. Make sure to use the 32-bit or 64-bit installation as required by your setup. When prompted
during the installation, make sure to add Python to your platform-specific environment variable. If you are using
Python 2.x, you may need to install or upgrade pip, the Python package management system.
Install the azure-iothub-device-client package, using the command
pip install azure-iothub-device-client
Install the azure-iothub-service-client package, using the command
pip install azure-iothub-service-client
If you are using Windows OS, then Visual C++ redistributable package to allow the use of native DLLs from
Python.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)
Create an IoT hub
Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A device
cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the "Identity
registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a unique
device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new device
identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and keys
to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device. If your
application needs to store other device-specific metadata, it should use an application-specific store. For more information,
see IoT Hub developer guide.

Create a simulated device app


In this section, you will:
Create a Python console app that responds to a direct method called by the cloud
Simulate a device reboot
Use the reported properties to enable device twin queries to identify devices and when they last rebooted
1. Using a text editor, create a dmpatterns_getstarted_device.py file.
2. Add the following import statements at the start of the dmpatterns_getstarted_device.py file.

import random
import time, datetime
import sys

import iothub_client
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult,
IoTHubError, DeviceMethodReturnValue

3. Add variables including a CONNECTION_STRING variable and the client intialization. Replace the
connection string with your device connection string.

CONNECTION_STRING = "{deviceConnectionString}"
PROTOCOL = IoTHubTransportProvider.MQTT

CLIENT = IoTHubClient(CONNECTION_STRING, PROTOCOL)

WAIT_COUNT = 5

SEND_REPORTED_STATE_CONTEXT = 0
METHOD_CONTEXT = 0

SEND_REPORTED_STATE_CALLBACKS = 0
METHOD_CALLBACKS = 0
4. Add the following function callbacks to implement the direct method on the device.

def send_reported_state_callback(status_code, user_context):


global SEND_REPORTED_STATE_CALLBACKS

print ( "Device twins updated." )

def device_method_callback(method_name, payload, user_context):


global METHOD_CALLBACKS

if method_name == "rebootDevice":
print ( "Rebooting device..." )

time.sleep(20)

print ( "Device rebooted." )

current_time = str(datetime.datetime.now())
reported_state = "{\"rebootTime\":\"" + current_time + "\"}"
CLIENT.send_reported_state(reported_state, len(reported_state), send_reported_state_callback,
SEND_REPORTED_STATE_CONTEXT)

print ( "Updating device twins: rebootTime" )

device_method_return_value = DeviceMethodReturnValue()
device_method_return_value.response = "{ \"Response\": \"This is the response from the device\" }"
device_method_return_value.status = 200

return device_method_return_value

5. Start the direct method listener and wait.

def iothub_client_init():
if CLIENT.protocol == IoTHubTransportProvider.MQTT or client.protocol ==
IoTHubTransportProvider.MQTT_WS:
CLIENT.set_device_method_callback(device_method_callback, METHOD_CONTEXT)

def iothub_client_sample_run():
try:
iothub_client_init()

while True:
print ( "IoTHubClient waiting for commands, press Ctrl-C to exit" )

status_counter = 0
while status_counter <= WAIT_COUNT:
time.sleep(10)
status_counter += 1

except IoTHubError as iothub_error:


print ( "Unexpected error %s from IoTHub" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubClient sample stopped" )

if __name__ == '__main__':
print ( "Starting the IoT Hub Python sample..." )
print ( " Protocol %s" % PROTOCOL )
print ( " Connection string=%s" % CONNECTION_STRING )

iothub_client_sample_run()

6. Save and close the dmpatterns_getstarted_device.py file.


NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Trigger a remote reboot on the device using a direct method


In this section, you create a Python console app that initiates a remote reboot on a device using a direct method.
The app uses device twin queries to discover the last reboot time for that device.
1. Using a text editor, create a dmpatterns_getstarted_service.py file.
2. Add the following import statements at the start of the dmpatterns_getstarted_service.py file.

import sys, time


import iothub_service_client

from iothub_service_client import IoTHubDeviceMethod, IoTHubError, IoTHubDeviceTwin

3. Add the following variable declarations. Only replace placeholder values for IoTHubConnectionString and
deviceId.

CONNECTION_STRING = "{IoTHubConnectionString}"
DEVICE_ID = "{deviceId}"

METHOD_NAME = "rebootDevice"
METHOD_PAYLOAD = "{\"method_number\":\"42\"}"
TIMEOUT = 60
WAIT_COUNT = 10

4. Add the following function to invoke the device method to reboot the target device, then query for the
device twins and get the last reboot time.
def iothub_devicemethod_sample_run():
try:
iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)
iothub_device_method = IoTHubDeviceMethod(CONNECTION_STRING)

print ( "" )
print ( "Invoking device to reboot..." )

response = iothub_device_method.invoke(DEVICE_ID, METHOD_NAME, METHOD_PAYLOAD, TIMEOUT)

print ( "" )
print ( "Successfully invoked the device to reboot." )

print ( "" )
print ( response.payload )

while True:
print ( "" )
print ( "IoTHubClient waiting for commands, press Ctrl-C to exit" )

status_counter = 0
while status_counter <= WAIT_COUNT:
twin_info = iothub_twin_method.get_twin(DEVICE_ID)

if twin_info.find("rebootTime") != -1:
print ( "Last reboot time: " +
twin_info[twin_info.find("rebootTime")+11:twin_info.find("rebootTime")+37])
else:
print ("Waiting for device to report last reboot time...")

time.sleep(5)
status_counter += 1

except IoTHubError as iothub_error:


print ( "" )
print ( "Unexpected error {0}".format(iothub_error) )
return
except KeyboardInterrupt:
print ( "" )
print ( "IoTHubDeviceMethod sample stopped" )

if __name__ == '__main__':
print ( "Starting the IoT Hub Service Client DeviceManagement Python sample..." )
print ( " Connection string = {0}".format(CONNECTION_STRING) )
print ( " Device ID = {0}".format(DEVICE_ID) )

iothub_devicemethod_sample_run()

5. Save and close the dmpatterns_getstarted_service.py file.

Run the apps


You are now ready to run the apps.
1. At the command prompt, run the following command to begin listening for the reboot direct method.

python dmpatterns_getstarted_device.py

2. At another command prompt, run the following command to trigger the remote reboot and query for the
device twin to find the last reboot time.
python dmpatterns_getstarted_service.py

3. You see the device response to the direct method in the console.

Customize and extend the device management actions


Your IoT solutions can expand the defined set of device management patterns or enable custom patterns by using
the device twin and cloud-to-device method primitives. Other examples of device management actions include
factory reset, firmware update, software update, power management, network and connectivity management, and
data encryption.

Device maintenance windows


Typically, you configure devices to perform actions at a time that minimizes interruptions and downtime. Device
maintenance windows are a commonly used pattern to define the time when a device should update its
configuration. Your back-end solutions can use the desired properties of the device twin to define and activate a
policy on your device that enables a maintenance window. When a device receives the maintenance window policy,
it can use the reported property of the device twin to report the status of the policy. The back-end app can then use
device twin queries to attest to compliance of devices and each policy.

Next steps
In this tutorial, you used a direct method to trigger a remote reboot on a device. You used the reported properties
to report the last reboot time from the device, and queried the device twin to discover the last reboot time of the
device from the cloud.
To continue getting started with IoT Hub and device management patterns such as remote over the air firmware
update, see:
Tutorial: How to do a firmware update
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
To continue getting started with IoT Hub, see Getting started with IoT Edge.
Use device management to initiate a device firmware
update (Node/Node)
5/29/2018 • 10 min to read • Edit Online

In the Get started with device management tutorial, you saw how to use the device twin and direct methods
primitives to remotely reboot a device. This tutorial uses the same IoT Hub primitives and provides guidance and
shows you how to do an end-to-end simulated firmware update. This pattern is used in the firmware update
implementation for the Intel Edison device sample.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a Node.js console app that calls the firmwareUpdate direct method in the simulated device app through
your IoT hub.
Create a simulated device app that implements a firmwareUpdate direct method. This method initiates a
multi-stage process that waits to download the firmware image, downloads the firmware image, and finally
applies the firmware image. During each stage of the update, the device uses the reported properties to report
on progress.
At the end of this tutorial, you have two Node.js console apps:
dmpatterns_fwupdate_service.js, which calls a direct method in the simulated device app, displays the response,
and periodically (every 500ms) displays the updated reported properties.
dmpatterns_fwupdate_device.js, which connects to your IoT hub with the device identity created earlier, receives
a firmwareUpdate direct method, runs through a multi-state process to simulate a firmware update including:
waiting for the image download, downloading the new image, and finally applying the image.
To complete this tutorial, you need the following:
Node.js version 4.0.x or later,
Prepare your development environment describes how to install Node.js for this tutorial on either Windows or
Linux.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)
Follow the Get started with device management article to create your IoT hub and get your IoT Hub connection
string.

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device IDs
are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with the IoT
Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the device app
to connect to your IoT Hub as a device.
Refer to Getting started with IoT Hub to programmatically create device identities.

Trigger a remote firmware update on the device using a direct method


In this section, you create a Node.js console app that initiates a remote firmware update on a device. The app uses a
direct method to initiate the update and uses device twin queries to periodically get the status of the active
firmware update.
1. Create an empty folder called triggerfwupdateondevice. In the triggerfwupdateondevice folder, create
a package.json file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the triggerfwupdateondevice folder, run the following command to install
the azure-iot-hub package:

npm install azure-iothub --save

3. Using a text editor, create a dmpatterns_getstarted_service.js file in the triggerfwupdateondevice folder.


4. Add the following 'require' statements at the start of the dmpatterns_getstarted_service.js file:

'use strict';

var Registry = require('azure-iothub').Registry;


var Client = require('azure-iothub').Client;

5. Add the following variable declarations and replace the placeholder values:

var connectionString = '{device_connectionstring}';


var registry = Registry.fromConnectionString(connectionString);
var client = Client.fromConnectionString(connectionString);
var deviceToUpdate = 'myDeviceId';

6. Add the following function to find and display the value of the firmwareUpdate reported property.
var queryTwinFWUpdateReported = function() {
registry.getTwin(deviceToUpdate, function(err, twin){
if (err) {
console.error('Could not query twins: ' + err.constructor.name + ': ' + err.message);
} else {
console.log((JSON.stringify(twin.properties.reported.iothubDM.firmwareUpdate)) + "\n");
}
});
};

7. Add the following function to invoke the firmwareUpdate method to reboot the target device:

var startFirmwareUpdateDevice = function() {


var params = {
fwPackageUri: 'https://secureurl'
};

var methodName = "firmwareUpdate";


var payloadData = JSON.stringify(params);

var methodParams = {
methodName: methodName,
payload: payloadData,
timeoutInSeconds: 30
};

client.invokeDeviceMethod(deviceToUpdate, methodParams, function(err, result) {


if (err) {
console.error('Could not start the firmware update on the device: ' + err.message)
}
});
};

8. Finally, Add the following function to code to start the firmware update sequence and start periodically
showing the reported properties:

startFirmwareUpdateDevice();
setInterval(queryTwinFWUpdateReported, 500);

9. Save and close the dmpatterns_fwupdate_service.js file.

Create a simulated device app


In this section, you:
Create a Node.js console app that responds to a direct method called by the cloud
Trigger a simulated firmware update
Use the reported properties to enable device twin queries to identify devices and when they last completed a
firmware update
1. Create an empty folder called manageddevice. In the manageddevice folder, create a package.json file
using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the manageddevice folder, run the following command to install the azure-
iot-device and azure-iot-device-mqtt Device SDK packages:
npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a dmpatterns_fwupdate_device.js file in the manageddevice folder.


4. Add the following 'require' statements at the start of the dmpatterns_fwupdate_device.js file:

'use strict';

var Client = require('azure-iot-device').Client;


var Protocol = require('azure-iot-device-mqtt').Mqtt;

5. Add a connectionString variable and use it to create a Client instance. Replace the
{yourdeviceconnectionstring} placeholder with the connection string you previously made a note of in the
"Create a device identity" section previously:

var connectionString = '{yourdeviceconnectionstring}';


var client = Client.fromConnectionString(connectionString, Protocol);

6. Add the following function that is used to update reported properties:

var reportFWUpdateThroughTwin = function(twin, firmwareUpdateValue) {


var patch = {
iothubDM : {
firmwareUpdate : firmwareUpdateValue
}
};

twin.properties.reported.update(patch, function(err) {
if (err) throw err;
console.log('twin state reported: ' + firmwareUpdateValue.status);
});
};

7. Add the following functions that simulate downloading and applying the firmware image:

var simulateDownloadImage = function(imageUrl, callback) {


var error = null;
var image = "[fake image data]";

console.log("Downloading image from " + imageUrl);

callback(error, image);
}

var simulateApplyImage = function(imageData, callback) {


var error = null;

if (!imageData) {
error = {message: 'Apply image failed because of missing image data.'};
}

callback(error);
}

8. Add the following function that updates the firmware update status through the reported properties to
waiting. Typically, devices are informed of an available update and an administrator defined policy causes
the device to start downloading and applying the update. This function is where the logic to enable that
policy should run. For simplicity, the sample waits for four seconds before proceeding to download the
firmware image:

var waitToDownload = function(twin, fwPackageUriVal, callback) {


var now = new Date();

reportFWUpdateThroughTwin(twin, {
fwPackageUri: fwPackageUriVal,
status: 'waiting',
error : null,
startedWaitingTime : now.toISOString()
});
setTimeout(callback, 4000);
};

9. Add the following function that updates the firmware update status through the reported properties to
downloading. The function then simulates a firmware download and finally updates the firmware update
status to either downloadFailed or downloadComplete:

var downloadImage = function(twin, fwPackageUriVal, callback) {


var now = new Date();

reportFWUpdateThroughTwin(twin, {
status: 'downloading',
});

setTimeout(function() {
// Simulate download
simulateDownloadImage(fwPackageUriVal, function(err, image) {

if (err)
{
reportFWUpdateThroughTwin(twin, {
status: 'downloadfailed',
error: {
code: error_code,
message: error_message,
}
});
}
else {
reportFWUpdateThroughTwin(twin, {
status: 'downloadComplete',
downloadCompleteTime: now.toISOString(),
});

setTimeout(function() { callback(image); }, 4000);


}
});

}, 4000);
}

10. Add the following function that updates the firmware update status through the reported properties to
applying. The function then simulates applying the firmware image and finally updates the firmware update
status to either applyFailed or applyComplete:
var applyImage = function(twin, imageData, callback) {
var now = new Date();

reportFWUpdateThroughTwin(twin, {
status: 'applying',
startedApplyingImage : now.toISOString()
});

setTimeout(function() {

// Simulate apply firmware image


simulateApplyImage(imageData, function(err) {
if (err) {
reportFWUpdateThroughTwin(twin, {
status: 'applyFailed',
error: {
code: err.error_code,
message: err.error_message,
}
});
} else {
reportFWUpdateThroughTwin(twin, {
status: 'applyComplete',
lastFirmwareUpdate: now.toISOString()
});

}
});

setTimeout(callback, 4000);

}, 4000);
}

11. Add the following function that handles the firmwareUpdate direct method and initiates the multi-stage
firmware update process:
var onFirmwareUpdate = function(request, response) {

// Respond the cloud app for the direct method


response.send(200, 'FirmwareUpdate started', function(err) {
if (!err) {
console.error('An error occured when sending a method response:\n' + err.toString());
} else {
console.log('Response to method \'' + request.methodName + '\' sent successfully.');
}
});

// Get the parameter from the body of the method request


var fwPackageUri = request.payload.fwPackageUri;

// Obtain the device twin


client.getTwin(function(err, twin) {
if (err) {
console.error('Could not get device twin.');
} else {
console.log('Device twin acquired.');

// Start the multi-stage firmware update


waitToDownload(twin, fwPackageUri, function() {
downloadImage(twin, fwPackageUri, function(imageData) {
applyImage(twin, imageData, function() {});
});
});

}
});
}

12. Finally, add the following code that connects to your IoT hub:

client.open(function(err) {
if (err) {
console.error('Could not connect to IotHub client');
} else {
console.log('Client connected to IoT Hub. Waiting for firmwareUpdate direct method.');
}

client.onDeviceMethod('firmwareUpdate', onFirmwareUpdate);
});

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Run the apps


You are now ready to run the apps.
1. At the command prompt in the manageddevice folder, run the following command to begin listening for
the reboot direct method.

node dmpatterns_fwupdate_device.js

2. At the command prompt in the triggerfwupdateondevice folder, run the following command to trigger the
remote reboot and query for the device twin to find the last reboot time.

node dmpatterns_fwupdate_service.js

3. You see the device response to the direct method in the console.

Next steps
In this tutorial, you used a direct method to trigger a remote firmware update on a device and used the reported
properties to follow the progress of the firmware update.
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
Use device management to initiate a device firmware
update (.NET/Node)
5/29/2018 • 10 min to read • Edit Online

In the Get started with device management tutorial, you saw how to use the device twin and direct methods
primitives to remotely reboot a device. This tutorial uses the same IoT Hub primitives and shows you how to do an
end-to-end simulated firmware update. This pattern is used in the firmware update implementation for the
Raspberry Pi device implementation sample.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a .NET console app that calls the firmwareUpdate direct method in the simulated device app through
your IoT hub.
Create a simulated device app that implements a firmwareUpdate direct method. This method initiates a
multi-stage process that waits to download the firmware image, downloads the firmware image, and finally
applies the firmware image. During each stage of the update, the device uses the reported properties to report
on progress.
At the end of this tutorial, you have a Node.js console device app and a .NET (C#) console back-end app:
dmpatterns_fwupdate_service.js, which calls a direct method in the simulated device app, displays the response,
and periodically (every 500ms) displays the updated reported properties.
TriggerFWUpdate, which connects to your IoT hub with the device identity created earlier, receives a
firmwareUpdate direct method, runs through a multi-state process to simulate a firmware update including: waiting
for the image download, downloading the new image, and finally applying the image.
To complete this tutorial, you need the following:
Visual Studio 2015 or Visual Studio 2017.
Node.js version 4.0.x or later,
Prepare your development environment describes how to install Node.js for this tutorial on either Windows or
Linux.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)
Follow the Get started with device management article to create your IoT hub and get your IoT Hub connection
string.

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device IDs
are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with the IoT
Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the device app
to connect to your IoT Hub as a device.
Refer to Getting started with IoT Hub to programmatically create device identities.

Trigger a remote firmware update on the device using a direct method


In this section, you create a .NET console app (using C#) that initiates a remote firmware update on a device. The
app uses a direct method to initiate the update and uses device twin queries to periodically get the status of the
active firmware update.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project TriggerFWUpdate.

2. In Solution Explorer, right-click the TriggerFWUpdate project, and then click Manage NuGet Packages....
3. In the NuGet Package Manager window, select Browse, search for microsoft.azure.devices, select
Install to install the Microsoft.Azure.Devices package, and accept the terms of use. This procedure
downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package and its dependencies.
4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;

5. Add the following fields to the Program class. Replace the multiple placeholder values with the IoT Hub
connection string for the hub that you created in the previous section and the Id of your device.

static RegistryManager registryManager;


static string connString = "{iot hub connection string}";
static ServiceClient client;
static string targetDevice = "{deviceIdForTargetDevice}";

6. Add the following method to the Program class:

public static async Task QueryTwinFWUpdateReported()


{
Twin twin = await registryManager.GetTwinAsync(targetDevice);
Console.WriteLine(twin.Properties.Reported.ToJson());
}

7. Add the following method to the Program class:


public static async Task StartFirmwareUpdate()
{
client = ServiceClient.CreateFromConnectionString(connString);
CloudToDeviceMethod method = new CloudToDeviceMethod("firmwareUpdate");
method.ResponseTimeout = TimeSpan.FromSeconds(30);
method.SetPayloadJson(
@"{
fwPackageUri : 'https://someurl'
}");

CloudToDeviceMethodResult result = await client.InvokeDeviceMethodAsync(targetDevice, method);

Console.WriteLine("Invoked firmware update on device.");


}

8. Finally, add the following lines to the Main method:

registryManager = RegistryManager.CreateFromConnectionString(connString);
StartFirmwareUpdate().Wait();
QueryTwinFWUpdateReported().Wait();
Console.WriteLine("Press ENTER to exit.");
Console.ReadLine();

9. In the Solution Explorer, open the Set StartUp projects... and make sure the Action for TriggerFWUpdate
project is Start.
10. Build the solution.

Create a simulated device app


In this section, you:
Create a Node.js console app that responds to a direct method called by the cloud
Trigger a simulated firmware update
Use the reported properties to enable device twin queries to identify devices and when they last completed a
firmware update
1. Create an empty folder called manageddevice. In the manageddevice folder, create a package.json file
using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the manageddevice folder, run the following command to install the azure-
iot-device and azure-iot-device-mqtt Device SDK packages:

npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a dmpatterns_fwupdate_device.js file in the manageddevice folder.


4. Add the following 'require' statements at the start of the dmpatterns_fwupdate_device.js file:

'use strict';

var Client = require('azure-iot-device').Client;


var Protocol = require('azure-iot-device-mqtt').Mqtt;
5. Add a connectionString variable and use it to create a Client instance. Replace the
{yourdeviceconnectionstring} placeholder with the connection string you previously made a note of in the
"Create a device identity" section previously:

var connectionString = '{yourdeviceconnectionstring}';


var client = Client.fromConnectionString(connectionString, Protocol);

6. Add the following function that is used to update reported properties:

var reportFWUpdateThroughTwin = function(twin, firmwareUpdateValue) {


var patch = {
iothubDM : {
firmwareUpdate : firmwareUpdateValue
}
};

twin.properties.reported.update(patch, function(err) {
if (err) throw err;
console.log('twin state reported: ' + firmwareUpdateValue.status);
});
};

7. Add the following functions that simulate downloading and applying the firmware image:

var simulateDownloadImage = function(imageUrl, callback) {


var error = null;
var image = "[fake image data]";

console.log("Downloading image from " + imageUrl);

callback(error, image);
}

var simulateApplyImage = function(imageData, callback) {


var error = null;

if (!imageData) {
error = {message: 'Apply image failed because of missing image data.'};
}

callback(error);
}

8. Add the following function that updates the firmware update status through the reported properties to
waiting. Typically, devices are informed of an available update and an administrator defined policy causes
the device to start downloading and applying the update. This function is where the logic to enable that
policy should run. For simplicity, the sample waits for four seconds before proceeding to download the
firmware image:
var waitToDownload = function(twin, fwPackageUriVal, callback) {
var now = new Date();

reportFWUpdateThroughTwin(twin, {
fwPackageUri: fwPackageUriVal,
status: 'waiting',
error : null,
startedWaitingTime : now.toISOString()
});
setTimeout(callback, 4000);
};

9. Add the following function that updates the firmware update status through the reported properties to
downloading. The function then simulates a firmware download and finally updates the firmware update
status to either downloadFailed or downloadComplete:

var downloadImage = function(twin, fwPackageUriVal, callback) {


var now = new Date();

reportFWUpdateThroughTwin(twin, {
status: 'downloading',
});

setTimeout(function() {
// Simulate download
simulateDownloadImage(fwPackageUriVal, function(err, image) {

if (err)
{
reportFWUpdateThroughTwin(twin, {
status: 'downloadfailed',
error: {
code: error_code,
message: error_message,
}
});
}
else {
reportFWUpdateThroughTwin(twin, {
status: 'downloadComplete',
downloadCompleteTime: now.toISOString(),
});

setTimeout(function() { callback(image); }, 4000);


}
});

}, 4000);
}

10. Add the following function that updates the firmware update status through the reported properties to
applying. The function then simulates applying the firmware image and finally updates the firmware update
status to either applyFailed or applyComplete:
var applyImage = function(twin, imageData, callback) {
var now = new Date();

reportFWUpdateThroughTwin(twin, {
status: 'applying',
startedApplyingImage : now.toISOString()
});

setTimeout(function() {

// Simulate apply firmware image


simulateApplyImage(imageData, function(err) {
if (err) {
reportFWUpdateThroughTwin(twin, {
status: 'applyFailed',
error: {
code: err.error_code,
message: err.error_message,
}
});
} else {
reportFWUpdateThroughTwin(twin, {
status: 'applyComplete',
lastFirmwareUpdate: now.toISOString()
});

}
});

setTimeout(callback, 4000);

}, 4000);
}

11. Add the following function that handles the firmwareUpdate direct method and initiates the multi-stage
firmware update process:
var onFirmwareUpdate = function(request, response) {

// Respond the cloud app for the direct method


response.send(200, 'FirmwareUpdate started', function(err) {
if (!err) {
console.error('An error occured when sending a method response:\n' + err.toString());
} else {
console.log('Response to method \'' + request.methodName + '\' sent successfully.');
}
});

// Get the parameter from the body of the method request


var fwPackageUri = request.payload.fwPackageUri;

// Obtain the device twin


client.getTwin(function(err, twin) {
if (err) {
console.error('Could not get device twin.');
} else {
console.log('Device twin acquired.');

// Start the multi-stage firmware update


waitToDownload(twin, fwPackageUri, function() {
downloadImage(twin, fwPackageUri, function(imageData) {
applyImage(twin, imageData, function() {});
});
});

}
});
}

12. Finally, add the following code that connects to your IoT hub:

client.open(function(err) {
if (err) {
console.error('Could not connect to IotHub client');
} else {
console.log('Client connected to IoT Hub. Waiting for firmwareUpdate direct method.');
}

client.onDeviceMethod('firmwareUpdate', onFirmwareUpdate);
});

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Run the apps


You are now ready to run the apps.
1. At the command prompt in the manageddevice folder, run the following command to begin listening for
the reboot direct method.

node dmpatterns_fwupdate_device.js

2. In Visual Studio, right-click on the TriggerFWUpdate project, select Debug and Start new instance.
3. You see the device response to the direct method in the console.

Next steps
In this tutorial, you used a direct method to trigger a remote firmware update on a device and used the reported
properties to follow the progress of the firmware update.
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
Use device management to initiate a device firmware
update (.NET/.NET)
6/4/2018 • 12 min to read • Edit Online

Introduction
In the Get started with device management tutorial, you saw how to use the device twin and direct methods
primitives to remotely reboot a device. This tutorial uses the same IoT Hub primitives and shows you how to do an
end-to-end simulated firmware update. This pattern is used in the firmware update implementation for the
Raspberry Pi device implementation sample.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a .NET console app that calls the firmwareUpdate direct method in the simulated device app through
your IoT hub.
Create a simulated device app that implements a firmwareUpdate direct method. This method initiates a
multi-stage process that waits to download the firmware image, downloads the firmware image, and finally
applies the firmware image. During each stage of the update, the device uses the reported properties to report
on progress.
At the end of this tutorial, you have a .NET (C#) console device app and a .NET (C#) console back-end app:
SimulatedDeviceFwUpdate, which connects to your IoT hub with the device identity created earlier,
receives the firmwareUpdate direct method, runs through a multi-state process to simulate a firmware
update including: waiting for the image download, downloading the new image, and finally applying the
image.
TriggerFWUpdate, which uses the service SDK to remotely invoke the firmwareUpdate direct method on
the simulated device, displays the response, and periodically (every 500ms) displays the updated reported
properties.
To complete this tutorial, you need the following:
Visual Studio 2015 or Visual Studio 2017.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)
Follow the Get started with device management article to create your IoT hub and get your IoT Hub connection
string.

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A device
cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the "Identity
registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a unique
device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new device
identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and keys
to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device. If your
application needs to store other device-specific metadata, it should use an application-specific store. For more information,
see IoT Hub developer guide.

Trigger a remote firmware update on the device using a direct method


In this section, you create a .NET console app (using C#) that initiates a remote firmware update on a device. The
app uses a direct method to initiate the update and uses device twin queries to periodically get the status of the
active firmware update.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project TriggerFWUpdate.

2. In Solution Explorer, right-click the TriggerFWUpdate project, and then click Manage NuGet Packages.
3. In the NuGet Package Manager window, select Browse, search for microsoft.azure.devices, select
Install to install the Microsoft.Azure.Devices package, and accept the terms of use. This procedure
downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package and its dependencies.
4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;

5. Add the following fields to the Program class. Replace the multiple placeholder values with the IoT Hub
connection string for the hub that you created in the previous section and the ID of your device.

static RegistryManager registryManager;


static string connString = "{iot hub connection string}";
static ServiceClient client;
static string targetDevice = "{deviceIdForTargetDevice}";

6. Add the following method to the Program class. This method polls the device twin for updated status every
500 milliseconds. It writes to the console only when status has actually changed. For this sample, to prevent
consuming extra IoT Hub messages in your subscription, polling stops when the device reports a status of
applyComplete or an error.
public static async Task QueryTwinFWUpdateReported(DateTime startTime)
{
DateTime lastUpdated = startTime;

while (true)
{
Twin twin = await registryManager.GetTwinAsync(targetDevice);

if (twin.Properties.Reported.GetLastUpdated().ToUniversalTime() > lastUpdated.ToUniversalTime())


{
lastUpdated = twin.Properties.Reported.GetLastUpdated().ToUniversalTime();
Console.WriteLine("\n" + twin.Properties.Reported["iothubDM"].ToJson());

var status = twin.Properties.Reported["iothubDM"]["firmwareUpdate"]["status"].Value;


if ((status == "downloadFailed") || (status == "applyFailed") || (status ==
"applyComplete"))
{
Console.WriteLine("\nStop polling.");
return;
}
}
await Task.Delay(500);
}
}

7. Add the following method to the Program class:

public static async Task StartFirmwareUpdate()


{
client = ServiceClient.CreateFromConnectionString(connString);
CloudToDeviceMethod method = new CloudToDeviceMethod("firmwareUpdate");
method.ResponseTimeout = TimeSpan.FromSeconds(30);
method.SetPayloadJson(
@"{
fwPackageUri : 'https://someurl'
}");

CloudToDeviceMethodResult result = await client.InvokeDeviceMethodAsync(targetDevice, method);

Console.WriteLine("Invoked firmware update on device.");


}

8. Finally, add the following lines to the Main method. This creates a registry manager to read the device twin
with, starts the polling task on a worker thread, and then triggers the firmware update.

registryManager = RegistryManager.CreateFromConnectionString(connString);

Task queryTask = Task.Run(() => (QueryTwinFWUpdateReported(DateTime.Now)));

StartFirmwareUpdate().Wait();
Console.WriteLine("Press ENTER to exit.");
Console.ReadLine();

9. Build the solution.

Create a simulated device app


In this section, you:
Create a .NET console app that responds to a direct method called by the cloud
Simulate a firmware update triggered by a backend service through a direct method
Use the reported properties to enable device twin queries to identify devices and when they last completed a
firmware update
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project SimulateDeviceFWUpdate.

2. In Solution Explorer, right-click the SimulateDeviceFWUpdate project, and then click Manage NuGet
Packages.
3. In the NuGet Package Manager window, select Browse and search for microsoft.azure.devices.client.
Select Install to install the Microsoft.Azure.Devices.Client package, and accept the terms of use. This
procedure downloads, installs, and adds a reference to the Azure IoT device SDK NuGet package and its
dependencies.

4. Add the following using statements at the top of the Program.cs file:

using Newtonsoft.Json.Linq;
using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;

5. Add the following fields to the Program class. Replace the placeholder value with the device connection
string that you noted in the Create a device identity section.
static string DeviceConnectionString = "HostName=<yourIotHubName>.azure-devices.net;DeviceId=
<yourIotDeviceName>;SharedAccessKey=<yourIotDeviceAccessKey>";
static DeviceClient Client = null;

6. Add the following method to report status back to the cloud through the device twin:

static async Task reportFwUpdateThroughTwin(Twin twin, TwinCollection fwUpdateValue)


{
try
{
TwinCollection patch = new TwinCollection();
TwinCollection iothubDM = new TwinCollection();

iothubDM["firmwareUpdate"] = fwUpdateValue;
patch["iothubDM"] = iothubDM;

await Client.UpdateReportedPropertiesAsync(patch);
Console.WriteLine("Twin state reported: {0}", fwUpdateValue["status"]);
}
catch
{
Console.WriteLine("Error updating device twin");
throw;
}
}

7. Add the following method to simulate downloading the firmware image:

static async Task<byte[]> simulateDownloadImage(string imageUrl)


{
var image = "[fake image data]";

Console.WriteLine("Downloading image from " + imageUrl);

await Task.Delay(4000);

return Encoding.ASCII.GetBytes(image);

8. Add the following method to simulate applying the firmware image to the device:

static async Task simulateApplyImage(byte[] imageData)


{
if (imageData == null)
{
throw new ArgumentNullException();
}

await Task.Delay(4000);

9. Add the following method to simulate waiting to download the firmware image. Update status to waiting
and clear other firmware update properties on the twin. These properties are cleared to remove any existing
values from prior firmware updates. This is necessary because reported properties are sent as a PATCH
operation (a delta) and not a PUT operation (a complete set of properties that replaces all of the previous
values). Typically, devices are informed of an available update and an administrator defined policy causes the
device to start downloading and applying the update. This function is where the logic to enable that policy
should run.

static async Task waitToDownload(Twin twin, string fwUpdateUri)


{
var now = DateTime.Now;
TwinCollection status = new TwinCollection();
status["fwPackageUri"] = fwUpdateUri;
status["status"] = "waiting";
status["error"] = null;
status["startedWaitingTime"] = DateTime.Now;
status["downloadCompleteTime"] = null;
status["startedApplyingImage"] = null;
status["lastFirmwareUpdate"] = null;

await reportFwUpdateThroughTwin(twin, status);

await Task.Delay(2000);
}

10. Add the following method to perform the download. It updates the status to downloading through the
device twin, calls the simulate download method, and reports a status of downloadComplete or
downloadFailed through the twin depending on the results of the download operation.

static async Task<byte[]> downloadImage(Twin twin, string fwUpdateUri)


{
try
{
TwinCollection statusUpdate = new TwinCollection();
statusUpdate["status"] = "downloading";
await reportFwUpdateThroughTwin(twin, statusUpdate);

byte[] imageData = await simulateDownloadImage(fwUpdateUri);

statusUpdate = new TwinCollection();


statusUpdate["status"] = "downloadComplete";
statusUpdate["downloadCompleteTime"] = DateTime.Now;
await reportFwUpdateThroughTwin(twin, statusUpdate);
return imageData;
}
catch (Exception ex)
{
TwinCollection statusUpdate = new TwinCollection();
statusUpdate["status"] = "downloadFailed";
statusUpdate["error"] = new TwinCollection();
statusUpdate["error"]["code"] = ex.GetType().ToString();
statusUpdate["error"]["message"] = ex.Message;
await reportFwUpdateThroughTwin(twin, statusUpdate);
throw;
}
}

11. Add the following method to apply the image. It updates the status to applying through the device twin,
calls the simulate apply image method, and updates status to applyComplete or applyFailed through the
twin depending on the results of the apply operation.
static async Task applyImage(Twin twin, byte[] imageData)
{
try
{
TwinCollection statusUpdate = new TwinCollection();
statusUpdate["status"] = "applying";
statusUpdate["startedApplyingImage"] = DateTime.Now;
await reportFwUpdateThroughTwin(twin, statusUpdate);

await simulateApplyImage(imageData);

statusUpdate = new TwinCollection();


statusUpdate["status"] = "applyComplete";
statusUpdate["lastFirmwareUpdate"] = DateTime.Now;
await reportFwUpdateThroughTwin(twin, statusUpdate);
}
catch (Exception ex)
{
TwinCollection statusUpdate = new TwinCollection();
statusUpdate["status"] = "applyFailed";
statusUpdate["error"] = new TwinCollection();
statusUpdate["error"]["code"] = ex.GetType().ToString();
statusUpdate["error"]["message"] = ex.Message;
await reportFwUpdateThroughTwin(twin, statusUpdate);
throw;
}
}

12. Add the following method to sequence the firmware update operation from waiting to download the image
through applying the image to the device:

static async Task doUpdate(string fwUpdateUrl)


{
try
{
Twin twin = await Client.GetTwinAsync();
await waitToDownload(twin, fwUpdateUrl);
byte[] imageData = await downloadImage(twin, fwUpdateUrl);
await applyImage(twin, imageData);
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error during update: {0}", ex.Message);
}
}

13. Add the following method to handle the updateFirmware direct method from the cloud. It extracts the URL
to the firmware update from the message payload and passes it to the doUpdate task, which it starts on
another threadpool thread. It then immediately returns the method response to the cloud.

static Task<MethodResponse> onFirmwareUpdate(MethodRequest methodRequest, object userContext)


{
string fwUpdateUrl = (string)JObject.Parse(methodRequest.DataAsJson)["fwPackageUri"];
Console.WriteLine("\nMethod: {0} triggered by service, URI is: {1}", methodRequest.Name,
fwUpdateUrl);

Task updateTask = Task.Run(() => (doUpdate(fwUpdateUrl)));

string result = "'FirmwareUpdate started.'";


return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200));
}
NOTE
This method triggers the simulated update to run as a Task and then immediately responds to the method call,
informing the service that the firmware update has been started. Update status and completion will be sent to the
service through the reported properties of the device twin. We respond to the method call when starting the update,
rather than after its completion, because:
A real update process is very likely to take longer than the method call timeout.
A real update process is very likely to require a reboot, which would re-launch this app making the
MethodRequest object unavailable. (Updating reported properties, however, is possible even after a reboot.)

14. Finally, add the following code to the Main method to open the connection to your IoT hub and initialize the
method listener:

try
{
Console.WriteLine("Connecting to hub");
Client = DeviceClient.CreateFromConnectionString(DeviceConnectionString, TransportType.Mqtt);

// setup callback for "firmware update" method


Client.SetMethodHandlerAsync("firmwareUpdate", onFirmwareUpdate, null).Wait();
Console.WriteLine("Waiting for firmware update direct method call\n Press enter to exit.");
Console.ReadLine();

Console.WriteLine("Exiting...");

// as a good practice, remove the firmware update handler


Client.SetMethodHandlerAsync("firmwareUpdate", null, null).Wait();
Client.CloseAsync().Wait();
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}

15. Build the solution.

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Run the apps


You are now ready to run the apps.
1. Run the .NET device app SimulatedDeviceFWUpdate. Right-click the SimulatedDeviceFWUpdate
project, select Debug, and then select Start new instance. It should start listening for method calls from
your IoT Hub:
2. Once the device is connected and waiting for method invocations, run the .NET TriggerFWUpdate app to
invoke the firmware update method in the simulated device app. Right-click the TriggerFWUpdate project,
select Debug, and then select Start new instance. You should see update sequence written in the
SimulatedDeviceFWUpdate console and also the sequence reported through the reported properties of
the device in the TriggerFWUpdate console. Note that the process takes several seconds to complete.
Next steps
In this tutorial, you used a direct method to trigger a remote firmware update on a device and used the reported
properties to follow the progress of the firmware update.
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
Use device management to initiate a device firmware
update (Java/Java)
5/29/2018 • 11 min to read • Edit Online

In the Get started with device management tutorial, you saw how to use the device twin and direct methods
primitives to remotely reboot a device. This tutorial uses the same IoT Hub primitives and shows you how to do an
end-to-end simulated firmware update. This pattern is used in the firmware update implementation for the
Raspberry Pi device implementation sample.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a Java console app that calls the firmwareUpdate direct method on the simulated device app through
your IoT hub.
Create a Java console app that simulates the device and implements the firmwareUpdate direct method. This
method initiates a multi-stage process that waits to download the firmware image, downloads the firmware
image, and finally applies the firmware image. During each stage of the update, the device uses the reported
properties to report on progress.
At the end of this tutorial, you have two Java console apps:
firmware-update, calls a direct method on the simulated device, displays the response, and periodically displays
reported property updates
simulated-device, connects to your IoT hub with the previously created device identity, receives the
firmwareUpdate direct method call, and runs through a firmware update simulation
To complete this tutorial, you need the following:
The latest Java SE Development Kit 8
Maven 3
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A device
cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the "Identity
registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a unique
device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new device
identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and keys
to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device. If your
application needs to store other device-specific metadata, it should use an application-specific store. For more information,
see IoT Hub developer guide.

Trigger a remote firmware update on the device using a direct method


In this section, you create a Java console app that initiates a remote firmware update on a device. The app uses a
direct method to initiate the update and uses device twin queries to periodically get the status of the active
firmware update.
1. Create an empty folder called fw -get-started.
2. In the fw -get-started folder, create a Maven project called firmware-update using the following command
at your command prompt. Note this is a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=firmware-update -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

3. At your command prompt, navigate to the firmware-update folder.


4. Using a text editor, open the pom.xml file in the firmware-update folder and add the following dependency to
the dependencies node. This dependency enables you to use the iot-service-client package in your app to
communicate with your IoT hub:

<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-service-client</artifactId>
<version>1.5.22</version>
<type>jar</type>
</dependency>

NOTE
You can check for the latest version of iot-service-client using Maven search.

5. Add the following build node after the dependencies node. This configuration instructs Maven to use Java
1.8 to build the app:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

6. Save and close the pom.xml file.


7. Using a text editor, open the firmware-update\src\main\java\com\mycompany\app\App.java source file.
8. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceMethod;
import com.microsoft.azure.sdk.iot.service.devicetwin.MethodResult;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;
import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwin;
import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwinDevice;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

9. Add the following class-level variables to the App class. Replace {youriothubconnectionstring} with your
IoT hub connection string you noted in the Create an IoT Hub section:

public static final String iotHubConnectionString = "{youriothubconnectionstring}";


public static final String deviceId = "myDeviceId";

private static final String methodName = "firmwareUpdate";


private static final Long responseTimeout = TimeUnit.SECONDS.toSeconds(30);
private static final Long connectTimeout = TimeUnit.SECONDS.toSeconds(5);

10. To implement a method that reads the reported properties from the device twin, add the following to the
App class:
public static void ShowReportedProperties()
{
try
{
DeviceTwin deviceTwins = DeviceTwin.createFromConnectionString(iotHubConnectionString);
DeviceTwinDevice twinDevice = new DeviceTwinDevice(deviceId);

Boolean firmwareUpdated = false;


Integer timeoutCycle = 0;

while (!firmwareUpdated)
{
if (timeoutCycle > 5)
{
System.out.println("Operation timed out");
break;
}

Thread.sleep(1000);

deviceTwins.getTwin(twinDevice);

String reportedProperties = twinDevice.reportedPropertiesToString();

if(reportedProperties.contains("status=waiting"))
{
System.out.println("Waiting on device...");
}
else if(reportedProperties.contains("status=downloadComplete"))
{
System.out.println("Download complete, applying firmware...");
}
else if (reportedProperties.contains("status=applyComplete"))
{
System.out.println("Firmware applied");
System.out.println("Get reported properties from device twin");
System.out.println(twinDevice.reportedPropertiesToString());
firmwareUpdated = true;
}
else
{
timeoutCycle++;
}
}
} catch (Exception ex) {
System.out.println("Exception reading reported properties: " + ex.getMessage());
}
}

11. Modify the signature of the main method to throw the following exceptions:

public static void main( String[] args ) throws IOException

12. To invoke the firmwareUpdate direct method on the simulated device, add the following code to the main
method:
DeviceMethod methodClient = DeviceMethod.createFromConnectionString(iotHubConnectionString);

try
{
String payload = "https://someurl";

System.out.println("Invoked firmware update on device.");


System.out.println("Sent URL: " + payload);

MethodResult result = methodClient.invoke(deviceId, methodName, responseTimeout, connectTimeout,


payload);

if(result == null)
{
throw new IOException("Invoke direct method reboot returns null");
}

System.out.println("Status for device: " + result.getStatus());


System.out.println("Message from device: " + result.getPayload());
}
catch (IotHubException e)
{
System.out.println(e.getMessage());
}

13. To poll the reported properties from the simulated device, add the following code to the main method:

ShowReportedProperties();

14. To enable you to stop the app, add the following code to the main method:

System.out.println("Press ENTER to exit.");


System.in.read();
System.out.println("Shutting down sample...");

15. Save and close the firmware-update\src\main\java\com\mycompany\app\App.java file.


16. Build the firmware-update back-end app and correct any errors. At your command prompt, navigate to the
firmware-update folder and run the following command:
mvn clean package -DskipTests

Simulate a device to handle direct method calls


In this section, you create a Java console simulated device app that can receive the firmwareUpdate direct method.
The app then runs through a multi-state process to simulate the firmware update using reportedProperties to
communicate status.
1. In the fw -get-started folder, create a Maven project called simulated-device using the following command
at your command prompt. Note this is a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=simulated-device -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2. At your command prompt, navigate to the simulated-device folder.


3. Using a text editor, open the pom.xml file in the firmware-update folder and add the following dependency to
the dependencies node. This dependency enables you to use the iot-service-client package in your app to
communicate with your IoT hub:
<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-device-client</artifactId>
<version>1.3.32</version>
<type>jar</type>
</dependency>

NOTE
You can check for the latest version of iot-device-client using Maven search.

4. Add the following build node after the dependencies node. This configuration instructs Maven to use Java
1.8 to build the app:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

5. Save and close the pom.xml file.


6. Using a text editor, open the simulated-device\src\main\java\com\mycompany\app\App.java source file.
7. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.device.*;
import com.microsoft.azure.sdk.iot.device.DeviceTwin.*;

import java.io.IOException;
import java.net.URISyntaxException;
import java.time.LocalDateTime;
import java.util.Scanner;
import java.util.Set;
import java.util.HashSet;
import java.util.HashMap;

8. Add the following class-level variables to the App class. Replace {yourdeviceconnectionstring} with your
device connection string you noted in the Create a Device Identity section:

private static final int METHOD_SUCCESS = 200;


private static final int METHOD_NOT_DEFINED = 404;

private static IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;


private static String connString = "{yourdeviceconnectionstring";
private static DeviceClient client;

private static String downloadURL = "unknown";

9. To implement direct method functionality, provide callbacks by adding the following nested classes to the
App class:

protected static class DirectMethodStatusCallback implements IotHubEventCallback


{
public void execute(IotHubStatusCode status, Object context)
{
System.out.println("IoT Hub responded to device method operation with status " + status.name());
}
}
protected static class DirectMethodCallback implements
com.microsoft.azure.sdk.iot.device.DeviceTwin.DeviceMethodCallback
{
@Override
public DeviceMethodData call(String methodName, Object methodData, Object context)
{
DeviceMethodData deviceMethodData;
switch (methodName)
{
case "firmwareUpdate" :
{
System.out.println("Response to method '" + methodName + "' sent successfully");

downloadURL = new String((byte[])methodData);

int status = METHOD_SUCCESS;


System.out.println("Starting firmware update");
deviceMethodData = new DeviceMethodData(status, "Started firmware update");
FirmwareUpdateThread firmwareUpdateThread = new FirmwareUpdateThread();
Thread t = new Thread(firmwareUpdateThread);
t.start();
break;
}
default:
{
int status = METHOD_NOT_DEFINED;
deviceMethodData = new DeviceMethodData(status, "Not defined direct method " + methodName);
}
}
return deviceMethodData;
}
}

10. To implement device twin functionality, provide callbacks by adding the following nested classes to the App
class:

protected static class DeviceTwinStatusCallback implements IotHubEventCallback


{
public void execute(IotHubStatusCode status, Object context)
{
System.out.println("IoT Hub responded to device twin operation with status " + status.name());
}
}
protected static class PropertyCallback implements PropertyCallBack<String, String>
{
public void PropertyCall(String propertyKey, String propertyValue, Object context)
{
System.out.println("PropertyKey: " + propertyKey);
System.out.println("PropertyKvalue: " + propertyKey);
}
}

11. To implement the firmware update, add the following nested class to the App class:
protected static class FirmwareUpdateThread implements Runnable {
public void run() {
try {
HashMap initialUpdate = new HashMap();
Property sentProperty = new Property("firmwareUpdate", initialUpdate);
Set<Property> sentPackage = new HashSet<Property>();

System.out.println("Downloading from " + downloadURL);

initialUpdate.put("status", "waiting");
initialUpdate.put("fwPackageUri", downloadURL);
initialUpdate.put("startedWaitingTime", LocalDateTime.now().toString());
sentPackage.add(sentProperty);

client.sendReportedProperties(sentPackage);

Thread.sleep(5000);

System.out.println("Download complete");

HashMap downloadUpdate = new HashMap();


downloadUpdate.put("status","downloadComplete");
downloadUpdate.put("downloadCompleteTime", LocalDateTime.now().toString());
downloadUpdate.put("startedApplyingImage", LocalDateTime.now().toString());
sentProperty.setValue(downloadUpdate);

client.sendReportedProperties(sentPackage);

Thread.sleep(5000);

System.out.println("Apply complete");

HashMap applyUpdate = new HashMap();


applyUpdate.put("status","applyComplete");
applyUpdate.put("lastFirmwareUpdate", LocalDateTime.now().toString());
sentProperty.setValue(applyUpdate);

client.sendReportedProperties(sentPackage);

Thread.sleep(5000);

HashMap resetUpdate = new HashMap();


applyUpdate.put("status","reset");
sentProperty.setValue(resetUpdate);

client.sendReportedProperties(sentPackage);
}
catch (Exception ex) {
System.out.println("Exception in reboot thread: " + ex.getMessage());
}
}
}

12. Modify the signature of the main method to throw the following exceptions:

public static void main(String[] args) throws IOException, URISyntaxException

13. To initiate the direct methods and device twins routine, add the following code to the main method:
client = new DeviceClient(connString, protocol);

try
{
client.open();
client.subscribeToDeviceMethod(new DirectMethodCallback(), null, new DirectMethodStatusCallback(),
null);
client.startDeviceTwin(new DeviceTwinStatusCallback(), null, new PropertyCallback(), null);
System.out.println("Client connected to IoT Hub. Waiting for firmwareUpdate direct method.");
}
catch (Exception e)
{
System.out.println("On exception, shutting down \n" + " Cause: " + e.getCause() + " \n" +
e.getMessage());
client.close();
System.out.println("Shutting down...");
}

14. To enable you to stop the app, add the following code to the end of the main method:

System.out.println("Press any key to exit...");


Scanner scanner = new Scanner(System.in);
scanner.nextLine();
scanner.close();
client.close();
System.out.println("Shutting down...");

15. Save and close the simulated-device\src\main\java\com\mycompany\app\App.java file.


16. Build the simulated-device app and correct any errors. At your command prompt, navigate to the
simulated-device folder and run the following command:
mvn clean package -DskipTests

Run the apps


You are now ready to run the apps.
1. At a command prompt in the simulated-device folder, run the following command to begin listening for
the firmware update direct method.
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

2. At a command prompt in the firmware-update folder, run the following command to invoke the firmware
update and query the device twins on your simulated device from your IoT hub:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

3. You can see the simulated device responding to the direct method in the console.
Next steps
In this tutorial, you used a direct method to trigger a remote firmware update on a device and used the reported
properties to follow the progress of the firmware update.
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
Use device management to initiate a device firmware
update (Python/Python)
5/29/2018 • 9 min to read • Edit Online

In the Get started with device management tutorial, you saw how to use the device twin and direct methods
primitives to remotely reboot a device. This tutorial uses the same IoT Hub primitives and provides guidance and
shows you how to do an end-to-end simulated firmware update. This pattern is used in the firmware update
implementation for the Intel Edison device sample.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a Python console app that calls the firmwareUpdate direct method in the simulated device app through
your IoT hub.
Create a simulated device app that implements a firmwareUpdate direct method. This method initiates a
multi-stage process that waits to download the firmware image, downloads the firmware image, and finally
applies the firmware image. During each stage of the update, the device uses the reported properties to report
on progress.
At the end of this tutorial, you have two Python console apps:
dmpatterns_fwupdate_service.py, which calls a direct method in the simulated device app, displays the response,
and periodically (every 500ms) displays the updated reported properties.
dmpatterns_fwupdate_device.py, which connects to your IoT hub with the device identity created earlier,
receives a firmwareUpdate direct method, runs through a multi-state process to simulate a firmware update
including: waiting for the image download, downloading the new image, and finally applying the image.
To complete this tutorial, you need the following:
Python 2.x or 3.x. Make sure to use the 32-bit or 64-bit installation as required by your setup. When prompted
during the installation, make sure to add Python to your platform-specific environment variable. If you are using
Python 2.x, you may need to install or upgrade pip, the Python package management system.
If you are using Windows OS, then Visual C++ redistributable package to allow the use of native DLLs from
Python.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A device
cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the "Identity
registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a unique
device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new device
identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and keys
to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device. If your
application needs to store other device-specific metadata, it should use an application-specific store. For more information,
see IoT Hub developer guide.

Trigger a remote firmware update on the device using a direct method


In this section, you create a Python console app that initiates a remote firmware update on a device. The app uses a
direct method to initiate the update and uses device twin queries to periodically get the status of the active
firmware update.
1. At your command prompt, run the following command to install the azure-iothub-service-client package:

pip install azure-iothub-service-client

2. Using a text editor, in your working directory, create a dmpatterns_getstarted_service.py file.


3. Add the following 'import' statements and variables at the start of the dmpatterns_getstarted_service.py
file. Replace IoTHubConnectionString and deviceId with your values noted previously:

import sys
import time

import iothub_service_client
from iothub_service_client import IoTHubDeviceTwin, IoTHubDeviceMethod, IoTHubError

CONNECTION_STRING = "{IoTHubConnectionString}"
DEVICE_ID = "{deviceId}"

METHOD_NAME = "firmwareUpdate"
METHOD_PAYLOAD = "{\"fwPackageUri\":\"test.com\"}"
TIMEOUT = 60
MESSAGE_COUNT = 5

4. Add the following function to call the direct method and display the value of the firmwareUpdate reported
property. Also add the main routine:
def iothub_firmware_sample_run():
try:
iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)

print ( "" )
print ( "Direct Method called." )
iothub_device_method = IoTHubDeviceMethod(CONNECTION_STRING)

response = iothub_device_method.invoke(DEVICE_ID, METHOD_NAME, METHOD_PAYLOAD, TIMEOUT)


print ( response.payload )

print ( "" )
print ( "Device Twin queried, press Ctrl-C to exit" )
while True:
twin_info = iothub_twin_method.get_twin(DEVICE_ID)

if "\"firmwareStatus\":\"standBy\"" in twin_info:
print ( "Waiting on device..." )
elif "\"firmwareStatus\":\"downloading\"" in twin_info:
print ( "Downloading firmware..." )
elif "\"firmwareStatus\":\"applying\"" in twin_info:
print ( "Download complete, applying firmware..." )
elif "\"firmwareStatus\":\"completed\"" in twin_info:
print ( "Firmware applied" )
print ( "" )
print ( "Get reported properties from device twin:" )
print ( twin_info )
break
else:
print ( "Unknown status" )

status_counter = 0
while status_counter <= MESSAGE_COUNT:
time.sleep(1)
status_counter += 1

except IoTHubError as iothub_error:


print ( "" )
print ( "Unexpected error {0}" % iothub_error )
return
except KeyboardInterrupt:
print ( "" )
print ( "IoTHubService sample stopped" )

if __name__ == '__main__':
print ( "Starting the IoT Hub firmware update Python sample..." )
print ( " Connection string = {0}".format(CONNECTION_STRING) )
print ( " Device ID = {0}".format(DEVICE_ID) )

iothub_firmware_sample_run()

5. Save and close the dmpatterns_fwupdate_service.py file.

Create a simulated device app


In this section, you:
Create a Python console app that responds to a direct method called by the cloud
Trigger a simulated firmware update
Use the reported properties to enable device twin queries to identify devices and when they last completed a
firmware update
1. At your command prompt, run the following command to install the azure-iothub-device-client package:
pip install azure-iothub-device-client

2. Using a text editor, create a dmpatterns_fwupdate_device.py file.


3. Add the following 'import' statements and variables at the start of the dmpatterns_fwupdate_device.py
file. Replace deviceConnectionString with the device connection string from your IoT hub:

import time, datetime


import sys
import threading

import iothub_client
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult
from iothub_client import IoTHubError, DeviceMethodReturnValue

SEND_REPORTED_STATE_CONTEXT = 0
METHOD_CONTEXT = 0

MESSAGE_COUNT = 10

PROTOCOL = IoTHubTransportProvider.MQTT
CONNECTION_STRING = "{deviceConnectionString}"
CLIENT = IoTHubClient(CONNECTION_STRING, PROTOCOL)

4. Add the following functions that are used to provide reported properties updates and implement the direct
method:

def send_reported_state_callback(status_code, user_context):


print ( "Reported state updated." )

def device_method_callback(method_name, payload, user_context):


if method_name == "firmwareUpdate":
print ( "Starting firmware update." )
image_url = payload
thr = threading.Thread(target=simulate_download_image, args=([payload]), kwargs={})
thr.start()

device_method_return_value = DeviceMethodReturnValue()
device_method_return_value.response = "{ \"Response\": \"Firmware update started\" }"
device_method_return_value.status = 200
return device_method_return_value

5. Add the following functions that simulate downloading and applying the firmware image:
def simulate_download_image(image_url):
time.sleep(15)
print ( "Downloading image from: " + image_url )

reported_state = "{\"firmwareStatus\":\"downloading\", \"downloadComplete\":\"" +


str(datetime.datetime.now()) + "\"}"
CLIENT.send_reported_state(reported_state, len(reported_state), send_reported_state_callback,
SEND_REPORTED_STATE_CONTEXT)
time.sleep(15)

simulate_apply_image(image_url)

def simulate_apply_image(image_url):
print ( "Applying image from: " + image_url )

reported_state = "{\"firmwareStatus\":\"applying\", \"startedApplyingImage\":\"" +


str(datetime.datetime.now()) + "\"}"
CLIENT.send_reported_state(reported_state, len(reported_state), send_reported_state_callback,
SEND_REPORTED_STATE_CONTEXT)
time.sleep(15)

simulate_complete_image()

def simulate_complete_image():
print ( "Image applied." )

reported_state = "{\"firmwareStatus\":\"completed\", \"lastFirmwareUpdate\":\"" +


str(datetime.datetime.now()) + "\"}"
CLIENT.send_reported_state(reported_state, len(reported_state), send_reported_state_callback,
SEND_REPORTED_STATE_CONTEXT)

6. Add the following function that initializes the device twin's reported properties and wait for the direct
method to be called. Also add the main routine:

def iothub_firmware_sample_run():
try:
CLIENT.set_device_method_callback(device_method_callback, METHOD_CONTEXT)

reported_state = "{\"firmwareStatus\":\"standBy\", \"logTime\":\"" +


str(datetime.datetime.now()) + "\"}"
CLIENT.send_reported_state(reported_state, len(reported_state), send_reported_state_callback,
SEND_REPORTED_STATE_CONTEXT)
print ( "Device twins initialized." )
print ( "IoTHubClient waiting for commands, press Ctrl-C to exit" )

while True:
status_counter = 0
while status_counter <= MESSAGE_COUNT:
time.sleep(10)
status_counter += 1

except IoTHubError as iothub_error:


print ( "Unexpected error %s from IoTHub" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubClient sample stopped" )

if __name__ == '__main__':
print ( "Starting the IoT Hub Python firmware update sample..." )
print ( " Protocol %s" % PROTOCOL )
print ( " Connection string=%s" % CONNECTION_STRING )

iothub_firmware_sample_run()
NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Run the apps


You are now ready to run the apps.
1. At the command prompt, run the following command to begin listening for the reboot direct method.

python dmpatterns_fwupdate_device.py

2. At another command prompt, run the following command to trigger the remote reboot and query for the
device twin to find the last reboot time.

python dmpatterns_fwupdate_service.py

3. You see the device response to the direct method in the console. Then note the change in reported
properties throughout the firmware update.

Next steps
In this tutorial, you used a direct method to trigger a remote firmware update on a device and used the reported
properties to follow the progress of the firmware update.
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
Manage your IoT Hub device identities in bulk
5/29/2018 • 11 min to read • Edit Online

Each IoT hub has an identity registry you can use to create per-device resources in the service. The identity
registry also enables you to control access to the device-facing endpoints. This article describes how to import
and export device identities in bulk to and from an identity registry.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Import and export operations take place in the context of Jobs that enable you to execute bulk service operations
against an IoT hub.
The RegistryManager class includes the ExportDevicesAsync and ImportDevicesAsync methods that use the
Job framework. These methods enable you to export, import, and synchronize the entirety of an IoT hub identity
registry.
This topic discusses using the RegistryManager class and Job system to perform bulk imports and exports of
devices to and from an IoT hub’s identity registry. You can also use the Azure IoT Hub Device Provisioning
Service to enable zero-touch, just-in-time provisioning to one or more IoT hubs without requiring human
intervention. To learn more, see the provisioning service documentation.

What are jobs?


Identity registry operations use the Job system when the operation:
Has a potentially long execution time compared to standard run-time operations.
Returns a large amount of data to the user.
Instead of a single API call waiting or blocking on the result of the operation, the operation asynchronously
creates a Job for that IoT hub. The operation then immediately returns a JobProperties object.
The following C# code snippet shows how to create an export job:

// Call an export job on the IoT Hub to retrieve all devices


JobProperties exportJob = await registryManager.ExportDevicesAsync(containerSasUri, false);

NOTE
To use the RegistryManager class in your C# code, add the Microsoft.Azure.Devices NuGet package to your project. The
RegistryManager class is in the Microsoft.Azure.Devices namespace.

You can use the RegistryManager class to query the state of the Job using the returned JobProperties
metadata. To create an instance of the RegistryManager class, use the CreateFromConnectionString method:

RegistryManager registryManager = RegistryManager.CreateFromConnectionString("{your IoT Hub connection


string}");
To find the connection string for your IoT hub, in the Azure portal:
Navigate to your IoT hub.
Select Shared access policies.
Select a policy, taking into account the permissions you need.
Copy the connectionstring from the panel on the right-hand side of the screen.
The following C# code snippet shows how to poll every five seconds to see if the job has finished executing:

// Wait until job is finished


while(true)
{
exportJob = await registryManager.GetJobAsync(exportJob.JobId);
if (exportJob.Status == JobStatus.Completed ||
exportJob.Status == JobStatus.Failed ||
exportJob.Status == JobStatus.Cancelled)
{
// Job has finished executing
break;
}

await Task.Delay(TimeSpan.FromSeconds(5));
}

Export devices
Use the ExportDevicesAsync method to export the entirety of an IoT hub identity registry to an Azure Storage
blob container using a Shared Access Signature.
This method enables you to create reliable backups of your device information in a blob container that you
control.
The ExportDevicesAsync method requires two parameters:
A string that contains a URI of a blob container. This URI must contain a SAS token that grants write access
to the container. The job creates a block blob in this container to store the serialized export device data. The
SAS token must include these permissions:

SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Read |
SharedAccessBlobPermissions.Delete

A boolean that indicates if you want to exclude authentication keys from your export data. If false,
authentication keys are included in export output. Otherwise, keys are exported as null.
The following C# code snippet shows how to initiate an export job that includes device authentication keys in the
export data and then poll for completion:
// Call an export job on the IoT Hub to retrieve all devices
JobProperties exportJob = await registryManager.ExportDevicesAsync(containerSasUri, false);

// Wait until job is finished


while(true)
{
exportJob = await registryManager.GetJobAsync(exportJob.JobId);
if (exportJob.Status == JobStatus.Completed ||
exportJob.Status == JobStatus.Failed ||
exportJob.Status == JobStatus.Cancelled)
{
// Job has finished executing
break;
}

await Task.Delay(TimeSpan.FromSeconds(5));
}

The job stores its output in the provided blob container as a block blob with the name devices.txt. The output
data consists of JSON serialized device data, with one device per line.
The following example shows the output data:

{"id":"Device1","eTag":"MA==","status":"enabled","authentication":{"symmetricKey":
{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device2","eTag":"MA==","status":"enabled","authentication":{"symmetricKey":
{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device3","eTag":"MA==","status":"disabled","authentication":{"symmetricKey":
{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device4","eTag":"MA==","status":"disabled","authentication":{"symmetricKey":
{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device5","eTag":"MA==","status":"enabled","authentication":{"symmetricKey":
{"primaryKey":"abc=","secondaryKey":"def="}}}

If a device has twin data, then the twin data are also exported together with the device data. The following
example shows this format. All data from the "twinETag" line until the end are twin data.
{
"id":"export-6d84f075-0",
"eTag":"MQ==",
"status":"enabled",
"statusReason":"firstUpdate",
"authentication":null,
"twinETag":"AAAAAAAAAAI=",
"tags":{
"Location":"LivingRoom"
},
"properties":{
"desired":{
"Thermostat":{
"Temperature":75.1,
"Unit":"F"
},
"$metadata":{
"$lastUpdated":"2017-03-09T18:30:52.3167248Z",
"$lastUpdatedVersion":2,
"Thermostat":{
"$lastUpdated":"2017-03-09T18:30:52.3167248Z",
"$lastUpdatedVersion":2,
"Temperature":{
"$lastUpdated":"2017-03-09T18:30:52.3167248Z",
"$lastUpdatedVersion":2
},
"Unit":{
"$lastUpdated":"2017-03-09T18:30:52.3167248Z",
"$lastUpdatedVersion":2
}
}
},
"$version":2
},
"reported":{
"$metadata":{
"$lastUpdated":"2017-03-09T18:30:51.1309437Z"
},
"$version":1
}
}
}

If you need access to this data in code, you can easily deserialize this data using the ExportImportDevice class.
The following C# code snippet shows how to read device information that was previously exported to a block
blob:

var exportedDevices = new List<ExportImportDevice>();

using (var streamReader = new StreamReader(await


blob.OpenReadAsync(AccessCondition.GenerateIfExistsCondition(), null, null), Encoding.UTF8))
{
while (streamReader.Peek() != -1)
{
string line = await streamReader.ReadLineAsync();
var device = JsonConvert.DeserializeObject<ExportImportDevice>(line);
exportedDevices.Add(device);
}
}

Import devices
The ImportDevicesAsync method in the RegistryManager class enables you to perform bulk import and
synchronization operations in an IoT hub identity registry. Like the ExportDevicesAsync method, the
ImportDevicesAsync method uses the Job framework.
Take care using the ImportDevicesAsync method because in addition to provisioning new devices in your
identity registry, it can also update and delete existing devices.

WARNING
An import operation cannot be undone. Always back up your existing data using the ExportDevicesAsync method to
another blob container before you make bulk changes to your identity registry.

The ImportDevicesAsync method takes two parameters:


A string that contains a URI of an Azure Storage blob container to use as input to the job. This URI must
contain a SAS token that grants read access to the container. This container must contain a blob with the
name devices.txt that contains the serialized device data to import into your identity registry. The import
data must contain device information in the same JSON format that the ExportImportDevice job uses
when it creates a devices.txt blob. The SAS token must include these permissions:

SharedAccessBlobPermissions.Read

A string that contains a URI of an Azure Storage blob container to use as output from the job. The job
creates a block blob in this container to store any error information from the completed import Job. The
SAS token must include these permissions:

SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Read |
SharedAccessBlobPermissions.Delete

NOTE
The two parameters can point to the same blob container. The separate parameters simply enable more control over your
data as the output container requires additional permissions.

The following C# code snippet shows how to initiate an import job:

JobProperties importJob = await registryManager.ImportDevicesAsync(containerSasUri, containerSasUri);

This method can also be used to import the data for the device twin. The format for the data input is the same as
the format shown in the ExportDevicesAsync section. In this way, you can reimport the exported data. The
$metadata is optional.

Import behavior
You can use the ImportDevicesAsync method to perform the following bulk operations in your identity registry:
Bulk registration of new devices
Bulk deletions of existing devices
Bulk status changes (enable or disable devices)
Bulk assignment of new device authentication keys
Bulk auto-regeneration of device authentication keys
Bulk update of twin data
You can perform any combination of the preceding operations within a single ImportDevicesAsync call. For
example, you can register new devices and delete or update existing devices at the same time. When used along
with the ExportDevicesAsync method, you can completely migrate all your devices from one IoT hub to another.
If the import file includes twin metadata, then this metadata overwrites the existing twin metadata. If the import
file does not include twin metadata, then only the lastUpdateTime metadata is updated using the current time.
Use the optional importMode property in the import serialization data for each device to control the import
process per-device. The importMode property has the following options:

IMPORTMODE DESCRIPTION

createOrUpdate If a device does not exist with the specified id, it is newly
registered.
If the device already exists, existing information is overwritten
with the provided input data without regard to the ETag
value.
The user can optionally specify twin data along with the
device data. The twin’s etag, if specified, is processed
independently from the device’s etag. If there is a mismatch
with the existing twin’s etag, an error is written to the log file.

create If a device does not exist with the specified id, it is newly
registered.
If the device already exists, an error is written to the log file.
The user can optionally specify twin data along with the
device data. The twin’s etag, if specified, is processed
independently from the device’s etag. If there is a mismatch
with the existing twin’s etag, an error is written to the log file.

update If a device already exists with the specified id, existing


information is overwritten with the provided input data
without regard to the ETag value.
If the device does not exist, an error is written to the log file.

updateIfMatchETag If a device already exists with the specified id, existing


information is overwritten with the provided input data only if
there is an ETag match.
If the device does not exist, an error is written to the log file.
If there is an ETag mismatch, an error is written to the log file.

createOrUpdateIfMatchETag If a device does not exist with the specified id, it is newly
registered.
If the device already exists, existing information is overwritten
with the provided input data only if there is an ETag match.
If there is an ETag mismatch, an error is written to the log file.
The user can optionally specify twin data along with the
device data. The twin’s etag, if specified, is processed
independently from the device’s etag. If there is a mismatch
with the existing twin’s etag, an error is written to the log file.

delete If a device already exists with the specified id, it is deleted


without regard to the ETag value.
If the device does not exist, an error is written to the log file.

deleteIfMatchETag If a device already exists with the specified id, it is deleted only
if there is an ETag match. If the device does not exist, an error
is written to the log file.
If there is an ETag mismatch, an error is written to the log file.
NOTE
If the serialization data does not explicitly define an importMode flag for a device, it defaults to createOrUpdate during
the import operation.

Import devices example – bulk device provisioning


The following C# code sample illustrates how to generate multiple device identities that:
Include authentication keys.
Write that device information to a block blob.
Import the devices into the identity registry.
// Provision 1,000 more devices
var serializedDevices = new List<string>();

for (var i = 0; i < 1000; i++)


{
// Create a new ExportImportDevice
// CryptoKeyGenerator is in the Microsoft.Azure.Devices.Common namespace
var deviceToAdd = new ExportImportDevice()
{
Id = Guid.NewGuid().ToString(),
Status = DeviceStatus.Enabled,
Authentication = new AuthenticationMechanism()
{
SymmetricKey = new SymmetricKey()
{
PrimaryKey = CryptoKeyGenerator.GenerateKey(32),
SecondaryKey = CryptoKeyGenerator.GenerateKey(32)
}
},
ImportMode = ImportMode.Create
};

// Add device to the list


serializedDevices.Add(JsonConvert.SerializeObject(deviceToAdd));
}

// Write the list to the blob


var sb = new StringBuilder();
serializedDevices.ForEach(serializedDevice => sb.AppendLine(serializedDevice));
await blob.DeleteIfExistsAsync();

using (CloudBlobStream stream = await blob.OpenWriteAsync())


{
byte[] bytes = Encoding.UTF8.GetBytes(sb.ToString());
for (var i = 0; i < bytes.Length; i += 500)
{
int length = Math.Min(bytes.Length - i, 500);
await stream.WriteAsync(bytes, i, length);
}
}

// Call import using the blob to add new devices


// Log information related to the job is written to the same container
// This normally takes 1 minute per 100 devices
JobProperties importJob = await registryManager.ImportDevicesAsync(containerSasUri, containerSasUri);

// Wait until job is finished


while(true)
{
importJob = await registryManager.GetJobAsync(importJob.JobId);
if (importJob.Status == JobStatus.Completed ||
importJob.Status == JobStatus.Failed ||
importJob.Status == JobStatus.Cancelled)
{
// Job has finished executing
break;
}

await Task.Delay(TimeSpan.FromSeconds(5));
}

Import devices example – bulk deletion


The following code sample shows you how to delete the devices you added using the previous code sample:
// Step 1: Update each device's ImportMode to be Delete
sb = new StringBuilder();
serializedDevices.ForEach(serializedDevice =>
{
// Deserialize back to an ExportImportDevice
var device = JsonConvert.DeserializeObject<ExportImportDevice>(serializedDevice);

// Update property
device.ImportMode = ImportMode.Delete;

// Re-serialize
sb.AppendLine(JsonConvert.SerializeObject(device));
});

// Step 2: Write the new import data back to the block blob
await blob.DeleteIfExistsAsync();
using (CloudBlobStream stream = await blob.OpenWriteAsync())
{
byte[] bytes = Encoding.UTF8.GetBytes(sb.ToString());
for (var i = 0; i < bytes.Length; i += 500)
{
int length = Math.Min(bytes.Length - i, 500);
await stream.WriteAsync(bytes, i, length);
}
}

// Step 3: Call import using the same blob to delete all devices
importJob = await registryManager.ImportDevicesAsync(containerSasUri, containerSasUri);

// Wait until job is finished


while(true)
{
importJob = await registryManager.GetJobAsync(importJob.JobId);
if (importJob.Status == JobStatus.Completed ||
importJob.Status == JobStatus.Failed ||
importJob.Status == JobStatus.Cancelled)
{
// Job has finished executing
break;
}

await Task.Delay(TimeSpan.FromSeconds(5));
}

Get the container SAS URI


The following code sample shows you how to generate a SAS URI with read, write, and delete permissions for a
blob container:
static string GetContainerSasUri(CloudBlobContainer container)
{
// Set the expiry time and permissions for the container.
// In this case no start time is specified, so the
// shared access signature becomes valid immediately.
var sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24);
sasConstraints.Permissions =
SharedAccessBlobPermissions.Write |
SharedAccessBlobPermissions.Read |
SharedAccessBlobPermissions.Delete;

// Generate the shared access signature on the container,


// setting the constraints directly on the signature.
string sasContainerToken = container.GetSharedAccessSignature(sasConstraints);

// Return the URI string for the container,


// including the SAS token.
return container.Uri + sasContainerToken;
}

Next steps
In this article, you learned how to perform bulk operations against the identity registry in an IoT hub. Follow these
links to learn more about managing Azure IoT Hub:
IoT Hub metrics
Operations monitoring
To further explore the capabilities of IoT Hub, see:
IoT Hub developer guide
Deploying AI to edge devices with Azure IoT Edge
To explore using the IoT Hub Device Provisioning Service to enable zero-touch, just-in-time provisioning, see:
Azure IoT Hub Device Provisioning Service
Overview of device management with IoT Hub
5/29/2018 • 5 min to read • Edit Online

Azure IoT Hub provides the features and an extensibility model that enable device and back-end developers to
build robust device management solutions. Devices range from constrained sensors and single purpose
microcontrollers, to powerful gateways that route communications for groups of devices. In addition, the use cases
and requirements for IoT operators vary significantly across industries. Despite this variation, device management
with IoT Hub provides the capabilities, patterns, and code libraries to cater to a diverse set of devices and end
users.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are
only available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to
choose the right IoT Hub tier.

A crucial part of creating a successful enterprise IoT solution is to provide a strategy for how operators handle the
ongoing management of their collection of devices. IoT operators require simple and reliable tools and
applications that enable them to focus on the more strategic aspects of their jobs. This article provides:
A brief overview of Azure IoT Hub approach to device management.
A description of common device management principles.
A description of the device lifecycle.
An overview of common device management patterns.

Device management principles


IoT brings with it a unique set of device management challenges and every enterprise-class solution must address
the following principles:

Scale and automation: IoT solutions require simple tools that can automate routine tasks and enable a
relatively small operations staff to manage millions of devices. Day-to-day, operators expect to handle device
operations remotely, in bulk, and to only be alerted when issues arise that require their direct attention.
Openness and compatibility: The device ecosystem is extraordinarily diverse. Management tools must be
tailored to accommodate a multitude of device classes, platforms, and protocols. Operators must be able to
support many types of devices, from the most constrained embedded single-process chips, to powerful and
fully functional computers.
Context awareness: IoT environments are dynamic and ever-changing. Service reliability is paramount. Device
management operations must take into account the following factors to ensure that maintenance downtime
doesn't affect critical business operations or create dangerous conditions:
SL A maintenance windows
Network and power states
In-use conditions
Device geolocation
Service many roles: Support for the unique workflows and processes of IoT operations roles is crucial. The
operations staff must work harmoniously with the given constraints of internal IT departments. They must also
find sustainable ways to surface realtime device operations information to supervisors and other business
managerial roles.

Device lifecycle
There is a set of general device management stages that are common to all enterprise IoT projects. In Azure IoT,
there are five stages within the device lifecycle:

Within each of these five stages, there are several device operator requirements that should be fulfilled to provide
a complete solution:
Plan: Enable operators to create a device metadata scheme that enables them to easily and accurately query
for, and target a group of devices for bulk management operations. You can use the device twin to store this
device metadata in the form of tags and properties.
Further reading: Get started with device twins, Understand device twins, How to use device twin properties.
Provision: Securely provision new devices to IoT Hub and enable operators to immediately discover device
capabilities. Use the IoT Hub identity registry to create flexible device identities and credentials, and perform
this operation in bulk by using a job. Build devices to report their capabilities and conditions through device
properties in the device twin.
Further reading: Manage device identities, Bulk management of device identities, How to use device twin
properties, Azure IoT Hub Device Provisioning Service.
Configure: Facilitate bulk configuration changes and firmware updates to devices while maintaining both
health and security. Perform these device management operations in bulk by using desired properties or
with direct methods and broadcast jobs.
Further reading: Use direct methods, Invoke a direct method on a device, How to use device twin properties,
Schedule and broadcast jobs, Schedule jobs on multiple devices.
Monitor: Monitor overall device collection health, the status of ongoing operations, and alert operators to
issues that might require their attention. Apply the device twin to allow devices to report realtime operating
conditions and status of update operations. Build powerful dashboard reports that surface the most
immediate issues by using device twin queries.
Further reading: How to use device twin properties, IoT Hub query language for device twins, jobs, and
message routing.
Retire: Replace or decommission devices after a failure, upgrade cycle, or at the end of the service lifetime.
Use the device twin to maintain device info if the physical device is being replaced, or archived if being
retired. Use the IoT Hub identity registry for securely revoking device identities and credentials.
Further reading: How to use device twin properties, Manage device identities.

Device management patterns


IoT Hub enables the following set of device management patterns. The device management tutorials show you in
more detail how to extend these patterns to fit your exact scenario and how to design new patterns based on these
core templates.
Reboot - The back-end app informs the device through a direct method that it has initiated a reboot. The
device uses the reported properties to update the reboot status of the device.

Factory Reset - The back-end app informs the device through a direct method that it has initiated a factory
reset. The device uses the reported properties to update the factory reset status of the device.
Configuration - The back-end app uses the desired properties to configure software running on the device.
The device uses the reported properties to update configuration status of the device.

Firmware Update - The back-end app informs the device through a direct method that it has initiated a
firmware update. The device initiates a multistep process to download the firmware image, apply the
firmware image, and finally reconnect to the IoT Hub service. Throughout the multistep process, the device
uses the reported properties to update the progress and status of the device.

Reporting progress and status - The solution back end runs device twin queries, across a set of devices, to
report on the status and progress of actions running on the devices.
Next Steps
The capabilities, patterns, and code libraries that IoT Hub provides for device management, enable you to create
IoT applications that fulfill enterprise IoT operator requirements within each device lifecycle stage.
To continue learning about the device management features in IoT Hub, see the Get started with device
management tutorial.
Connecting IoT Devices to Azure: IoT Hub and Event
Hubs
5/29/2018 • 2 min to read • Edit Online

Azure provides services specifically developed for diverse types of connectivity and communication to help you
connect your data to the power of the cloud. Both Azure IoT Hub and Azure Event Hubs are cloud services that can
ingest large amounts of data and process or store that data for business insights. The two services are similar in
that they both support ingestion of data with low latency and high reliability, but they are designed for different
purposes. IoT Hub was developed specifically to address the unique requirements of connecting IoT devices, at-
scale, to the Azure Cloud while Event Hubs was designed for big data streaming. This is why Microsoft
recommends using Azure IoT Hub to connect IoT devices to Azure
Azure IoT Hub is the cloud gateway that connects IoT devices to gather data to drive business insights and
automation. In addition, IoT Hub includes features that enrich the relationship between your devices and your
backend systems. Bi-directional communication capabilities mean that while you receive data from devices you can
also send commands and policies back to devices, for example, to update properties or invoke device management
actions. This cloud-to-device connectivity also powers the important capability of delivering cloud intelligence to
your edge devices with Azure IoT Edge. The unique device-level identity provided by IoT Hub helps better secure
your IoT solution from potential attacks.
Azure Event Hubs is the big data streaming service of Azure. It is designed for high throughput data streaming
scenarios where customers may send billions of requests per day. Event Hubs uses a partitioned consumer model
to scale out your stream and is integrated into the big data and analytics services of Azure including Databricks,
Stream Analytics, ADLS, and HDInsight. With features like Event Hubs Capture and Auto-Inflate, this service is
designed to support your big data apps and solutions. Additionally, IoT Hub leverages Event Hubs for its telemetry
flow path, so your IoT solution also benefits from the tremendous power of Event Hubs.
To summarize, while both solutions are designed for data ingestion at a massive scale, only IoT Hub provides the
rich IoT-specific capabilities that are designed for you to maximize the business value of connecting your IoT
devices to the Azure cloud. If your IoT journey is just beginning, starting with IoT Hub to support your data
ingestion scenarios will assure that you have instant access to the full-featured IoT capabilities once your business
and technical needs require them.
The following table provides details about how the two tiers of IoT Hub compare to Event Hubs when you're
evaluating them for IoT capabilities. For more information about the standard and basic tiers of IoT Hub, see How
to choose the right IoT Hub tier.

IOT CAPABILITY IOT HUB STANDARD TIER IOT HUB BASIC TIER EVENT HUBS

Device-to-cloud messaging

Protocols: HTTPS, AMQP,


AMQP over webSockets

Protocols: MQTT, MQTT over


webSockets

Per-device identity
IOT CAPABILITY IOT HUB STANDARD TIER IOT HUB BASIC TIER EVENT HUBS

File upload from devices

Device Provisioning Service

Cloud-to-device messaging

Device twin and device


management

IoT Edge

Even if the only use case is device-to-cloud data ingestion, we highly recommend using IoT Hub as it provides a
service that is designed for IoT device connectivity.
Next steps
To further explore the capabilities of IoT Hub, see the IoT Hub developer guide
Choose the right IoT Hub tier for your solution
5/29/2018 • 4 min to read • Edit Online

Every IoT solution is different, so Azure IoT Hub offers several options based on pricing and scale. This article is
meant to help you evaluate your IoT Hub needs. For pricing information about IoT Hub tiers refer to IoT Hub
pricing.
To decide which IoT Hub tier is right for your solution, ask yourself two questions:
What features do I plan to use? Azure IoT Hub offers two tiers, basic and standard, that differ in the number of
features they support. If your IoT solution is based around collecting data from devices and analyzing it centrally
then the basic tier is probably right for you. If you want to use more advanced configurations to control IoT devices
remotely or distribute some of your workloads onto the devices themselves then you should consider the standard
tier. For a detailed breakdown of which features are included in each tier continue to Basic and standard tiers.
How much data do I plan to move daily? Each IoT Hub tier is available in three sizes, based around how much
data throughput they can handle in any given day. These sizes are numerically identified as 1, 2, and 3. For example,
each unit of a level 1 IoT hub can handle 400 thousand messages a day, while a level 3 unit can handle 300 million.
For more details about the data guidelines, continue to Message throughput.

Basic and standard tiers


The standard tier of IoT Hub enables all features, and is required for any IoT solutions that want to make use of the
bi-directional communication capabilities. The basic tier enables a subset of the features and is intended for IoT
solutions that only need uni-directional communication from devices to the cloud. Both tiers offer the same security
and authentication features.
Once you create your IoT hub you can upgrade from the basic tier to the standard tier without interrupting your
existing operations. For more information, see How to upgrade your IoT hub.

CAPABILITY BASIC TIER STANDARD TIER

Device-to-cloud telemetry Yes Yes

Per-device identity Yes Yes

Message routing and Event Grid Yes Yes


integration

HTTP, AMQP, and MQTT protocols Yes Yes

Device Provisioning Service Yes Yes

Monitoring and diagnostics Yes Yes

Cloud-to-device messaging Yes

Device twins, Module twins and Device Yes


management

Azure IoT Edge Yes


IoT Hub also offers a free tier that is meant for testing and evaluation. It has all the capabilities of the standard tier,
but limited messaging allowances. You cannot upgrade from the free tier to either basic or standard.
IoT Hub REST APIs
The difference in supported capabilities between the basic and standard tiers of IoT Hub means that some API calls
do not work with basic tier hubs. The following table shows which APIs are available:

API BASIC TIER STANDARD TIER

Delete device Yes Yes

Get device Yes Yes

Delete module Yes Yes

Get module Yes Yes

Get registry statistics Yes Yes

Get services statistics Yes Yes

Put device Yes Yes

Put module Yes Yes

Query devices Yes Yes

Query modules Yes Yes

Create file upload SAS URI Yes Yes

Receive device bound notification Yes Yes

Send device event Yes Yes

Send module event Yes Yes

Update file upload status Yes Yes

Bulk device operation Yes, except for IoT Edge capabilites Yes

Purge command queue Yes

Get device twin Yes

Get module twin Yes

Invoke device method Yes

Update device twin Yes

Update module twin Yes


API BASIC TIER STANDARD TIER

Abandon device bound notification Yes

Complete device bound notification Yes

Cancel job Yes

Create job Yes

Get job Yes

Query jobs Yes

Message throughput
The best way to size an IoT Hub solution is to evaluate the traffic on a per-unit basis. In particular, consider the
required peak throughput for the following categories of operations:
Device-to-cloud messages
Cloud-to-device messages
Identity registry operations
Traffic is measured on a per-unit basis, not per hub. A level 1 or 2 IoT Hub instance can have as many as 200 units
associated with it. A level 3 IoT Hub instance can have up to 10 units. Once you create your IoT hub you can change
the number of units or move between the 1, 2, and 3 sizes within a specific tier without interrupting your existing
operations. For more information, see How to upgrade your IoT Hub.
As an example of each tier's traffic capabilities, device-to-cloud messages follow these sustained throughput
guidelines:

TIER SUSTAINED THROUGHPUT SUSTAINED SEND RATE

B1, S1 Up to 1111 KB/minute per unit Average of 278 messages/minute per


(1.5 GB/day/unit) unit
(400,000 messages/day per unit)

B2, S2 Up to 16 MB/minute per unit Average of 4,167 messages/minute per


(22.8 GB/day/unit) unit
(6 million messages/day per unit)

B3, S3 Up to 814 MB/minute per unit Average of 208,333 messages/minute


(1144.4 GB/day/unit) per unit
(300 million messages/day per unit)

In addition to this throughput information, see IoT Hub quotas and throttles and design your solution accordingly.
Identity registry operation throughput
IoT Hub identity registry operations are not supposed to be run-time operations, as they are mostly related to
device provisioning.
For specific burst performance numbers, see IoT Hub quotas and throttles.

Sharding
While a single IoT hub can scale to millions of devices, sometimes your solution requires specific performance
characteristics that a single IoT hub cannot guarantee. In that case you can partition your devices across multiple
IoT hubs. Multiple IoT hubs smooth traffic bursts and obtain the required throughput or operation rates that are
required.

Next steps
For additional information about IoT Hub capabilities and performance details, see [IoT Hub pricing][link-
pricing] or IoT Hub quotas and throttles.
To change your IoT Hub tier, follow the steps in Upgrade your IoT hub.
IoT Hub high availability and disaster recovery
5/29/2018 • 3 min to read • Edit Online

As an Azure service, IoT Hub provides high availability (HA) using redundancies at the Azure region level, without
any additional work required by the solution. The Microsoft Azure platform also includes features to help you build
solutions with disaster recovery (DR ) capabilities or cross-region availability. If you want to provide global, cross-
region high availability for devices or users, take advantage of these Azure DR features. The article Azure Business
Continuity Technical Guidance describes the built-in features in Azure for business continuity and DR. The Disaster
recovery and high availability for Azure applications paper provides architecture guidance on strategies for Azure
applications to achieve HA and DR.

Azure IoT Hub DR


In addition to intra-region HA, IoT Hub implements failover mechanisms for disaster recovery that require no
intervention from the user. IoT Hub DR is self-initiated and has a recovery time objective (RTO ) of 2-26 hours, and
the following recovery point objectives (RPOs):

FUNCTIONALITY RPO

Service availability for registry and communication operations Possible CName loss

Identity data in identity registry 0-5 mins data loss

Device-to-cloud messages All unread messages are lost

Operations monitoring messages All unread messages are lost

Cloud-to-device messages 0-5 mins data loss

Cloud-to-device feedback queue All unread messages are lost

Device twin data 0-5 mins data loss

Parent and device jobs 0-5 mins data loss

Regional failover with IoT Hub


A complete treatment of deployment topologies in IoT solutions is outside the scope of this article. The article
discusses the regional failover deployment model for the purpose of high availability and disaster recovery.
In a regional failover model, the solution back end runs primarily in one datacenter location. A secondary IoT hub
and back end are deployed in another datacenter location. If the IoT hub in the primary datacenter suffers an
outage or the network connectivity from the device to the primary datacenter is interrupted, devices use a
secondary service endpoint. You can improve the solution availability by implementing a cross-region failover
model instead of staying within a single region.
At a high level, to implement a regional failover model with IoT Hub, you need the following:
A secondary IoT hub and device routing logic: If service in your primary region is disrupted, devices must
start connecting to your secondary region. Given the state-aware nature of most services involved, it is common
for solution administrators to trigger the inter-region failover process. The best way to communicate the new
endpoint to devices, while maintaining control of the process, is to have them regularly check a concierge
service for the current active endpoint. The concierge service can be a web application that is replicated and kept
reachable using DNS -redirection techniques (for example, using Azure Traffic Manager).
Identity registry replication: To be usable, the secondary IoT hub must contain all device identities that can
connect to the solution. The solution should keep geo-replicated backups of device identities, and upload them
to the secondary IoT hub before switching the active endpoint for the devices. The device identity export
functionality of IoT Hub is useful in this context. For more information, see IoT Hub developer guide - identity
registry.
Merging logic: When the primary region becomes available again, all the state and data that have been created
in the secondary site must be migrated back to the primary region. This state and data mostly relate to device
identities and application metadata, which must be merged with the primary IoT hub and any other application-
specific stores in the primary region. To simplify this step, you should use idempotent operations. Idempotent
operations minimize the side-effects from the eventual consistent distribution of events, and from duplicates or
out-of-order delivery of events. In addition, the application logic should be designed to tolerate potential
inconsistencies or "slightly" out-of-date state. This situation can occur due to the additional time it takes for the
system to "heal" based on recovery point objectives (RPO ).

Next steps
Follow these links to learn more about Azure IoT Hub:
Get started with IoT Hubs (Tutorial)
What is Azure IoT Hub?
Support additional protocols for IoT Hub
5/29/2018 • 1 min to read • Edit Online

Azure IoT Hub natively supports communication over the MQTT, AMQP, and HTTPS protocols. In some cases,
devices or field gateways might not be able to use one of these standard protocols and require protocol adaptation.
In such cases, you can use a custom gateway. A custom gateway enables protocol adaptation for IoT Hub endpoints
by bridging the traffic to and from IoT Hub. You can use the Azure IoT protocol gateway as a custom gateway to
enable protocol adaptation for IoT Hub.

Azure IoT protocol gateway


The Azure IoT protocol gateway is a framework for protocol adaptation that is designed for high-scale, bidirectional
device communication with IoT Hub. The protocol gateway is a pass-through component that accepts device
connections over a specific protocol. It bridges the traffic to IoT Hub over AMQP 1.0.
You can deploy the protocol gateway in Azure in a highly scalable way by using Azure Service Fabric, Azure Cloud
Services worker roles, or Windows Virtual Machines. In addition, the protocol gateway can be deployed in on-
premises environments, such as field gateways.
The Azure IoT protocol gateway includes an MQTT protocol adapter that enables you to customize the MQTT
protocol behavior if necessary. Since IoT Hub provides built-in support for the MQTT v3.1.1 protocol, you should
only consider using the MQTT protocol adapter if protocol customizations or specific requirements for additional
functionality are required.
The MQTT adapter also demonstrates the programming model for building protocol adapters for other protocols.
In addition, the Azure IoT protocol gateway programming model allows you to plug in custom components for
specialized processing such as custom authentication, message transformations, compression/decompression, or
encryption/decryption of traffic between the devices and IoT Hub.
For flexibility, the Azure IoT protocol gateway and MQTT implementation are provided in an open-source software
project. You can use the open-source project to add support for various protocols and protocol versions, or
customize the implementation for your scenario.

Next steps
To learn more about the Azure IoT protocol gateway and how to use and deploy it as part of your IoT solution, see:
Azure IoT protocol gateway repository on GitHub
Azure IoT protocol gateway developer guide
To learn more about planning your IoT Hub deployment, see:
Compare with Event Hubs
Scaling, high availability, and disaster recovery
IoT Hub developer guide
Compare message routing and Event Grid for IoT
Hub
5/29/2018 • 4 min to read • Edit Online

Azure IoT Hub provides the capability to stream data from your connected devices, and integrate that data into
your business applications. IoT Hub offers two methods for integrating IoT events into other Azure services or
business applications. This article discusses the two features that provide this capability, so that you can choose
which option is best for your scenario.
IoT Hub message routing: This IoT Hub feature enables users to route device-to-cloud messages to service
endpoints like Azure Storage containers, Event Hubs, Service Bus queues, and Service Bus topics. Routing rules
provide the flexibility to perform query-based routes. They also enable critical alerts that trigger actions through
queries, and can be based on the message headers and body.
IoT Hub integration with Event Grid: Azure Event Grid is a fully managed event routing service that uses a
publish-subscribe model. IoT Hub and Event Grid work together to integrate IoT Hub events into Azure and
non-Azure services, in near-real time.

Similarities and differences


While both message routing and Event Grid enable alert configuration, there are some key differences between the
two. Refer to the following table for details:

FEATURE IOT HUB MESSAGE ROUTING IOT HUB INTEGRATION WITH EVENT GRID

Device messages Yes, message routing can be used for No, Event Grid can only be used for
telemetry data. non-telemetry IoT Hub events.

Event type Yes, message routing can report twin Yes, Event Grid can report when devices
changes and device lifecycle events. are registered to an IoT Hub, and when
devices are deleted.

Ordering Yes, ordering of events is maintained. No, order of events is not guaranteed.

Maximum message size 256 KB, device-to-cloud 64 KB

Filtering Rich filtering through SQL-like language Filtering based on suffix/prefix of device
supports filtering on message headers IDs, which works well for hierarchical
and bodies. For examples, see IoT Hub services like storage.
query language.
FEATURE IOT HUB MESSAGE ROUTING IOT HUB INTEGRATION WITH EVENT GRID

Endpoints Event Hub Azure Functions


Storage blob Azure Automation
Service Bus queue Event Hub
Service Bus topics Logic Apps
Microsoft Flow
Third-party services through
Paid IoT Hub SKUs (S1, S2, and S3) are
WebHooks
limited to 10 custom endpoints. 100
routes can be created per IoT Hub.
For the most up-to-date list of
endpoints, see Event Grid event
handlers.

Cost There is no separate charge for message There is no charge from IoT Hub. Event
routing. Only ingress of telemetry into Grid offers the first 100,000 operations
IoT Hub is charged. For example, if you per month for free, and then $0.60 per
have a message routed to three million operations after that.
different endpoints, you are billed for
only one message.

IoT Hub message routing and Event Grid have similarities too, some of which are detailed in the following table:

FEATURE IOT HUB MESSAGE ROUTING IOT HUB INTEGRATION WITH EVENT GRID

Reliability High: Delivers each message to the High: Delivers each message to the
endpoint at least once for each route. webhook at least once for each
Expires all messages that are not subscription. Expires all events that are
delivered within one hour. not delivered within 24 hours.

Scalability High: Optimized to support millions of High: Capable of routing 10,000,000


simultaneously connected devices events per second per region.
sending billions of messages.

Latency Low: Near-real time. Low: Near-real time.

Send to multiple endpoints Yes, send a single message to multiple Yes, send a single message to multiple
endpoints. endpoints.

Security Iot Hub provides per-device identity and Event Grid provides validation at three
revocable access control. For more points: event subscriptions, event
information, see the IoT Hub access publishing, and webhook event delivery.
control. For more information, see Event Grid
security and authentication.

How to choose
IoT Hub message routing and the IoT Hub integration with Event Grid perform different actions to achieve similar
results. They both take information from your IoT Hub solution and pass it on so that other services can react. So
how do you decide which one to use? In addition to the data from the previous section, use the following questions
to help guide your decision:
What kind of data are you sending to the endpoints?
Use IoT Hub message routing when you have to send telemetry data to other services. Message routing also
enables querying message headers and message bodies.
The IoT Hub integration with Event Grid works with events that occur in the IoT Hub service. These IoT Hub
events include device creation and deletion.
What endpoints need to receive this information?
IoT Hub message routing supports limited endpoints, but you can build connectors to reroute the data and
events to additional endpoints. For a complete list of supported endpoints, see the table in the previous
section.
The IoT Hub integration with Event Grid supports more endpoints. It also works with webhooks to extend
routing outside of the Azure service ecosystem and into third-party business applications.
Does it matter if your data arrives in order?
IoT Hub message routing maintains the order in which messages are sent, so that they arrive in the same
way.
Event Grid does not guarantee that endpoints will receive events in the same order that they occurred.
However, the event schema does include a timestamp that can be used to identify the order after the events
arrive at the endpoint.

Next steps
Learn more about IoT Hub message routing and the IoT Hub endpoints.
Learn more about Azure Event Grid
Try out the Event Grid integration by Sending email notifications about Azure IoT Hub events using Logic
Apps
Azure IoT Hub developer guide
5/29/2018 • 3 min to read • Edit Online

Azure IoT Hub is a fully managed service that helps enable reliable and secure bi-directional communications
between millions of devices and a solution back end.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are only
available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to choose
the right IoT Hub tier.

Azure IoT Hub provides you with:


Secure communications by using per-device security credentials and access control.
Multiple device-to-cloud and cloud-to-device hyper-scale communication options.
Queryable storage of per-device state information and meta-data.
Easy device connectivity with device libraries for the most popular languages and platforms.
This IoT Hub developer guide includes the following articles:
Device-to-cloud communication guidance helps you choose between device-to-cloud messages, device twin's
reported properties, and file upload.
Cloud-to-device communication guidance helps you choose between direct methods, device twin's desired
properties, and cloud-to-device messages.
Device-to-cloud and cloud-to-device messaging with IoT Hub describes the messaging features (device-to-
cloud and cloud-to-device) that IoT Hub exposes.
Send device-to-cloud messages to IoT Hub.
Read device-to-cloud messages from the built-in endpoint.
Use custom endpoints and routing rules for device-to-cloud messages.
Send cloud-to-device messages from IoT Hub.
Create and read IoT Hub messages.
Upload files from a device describes how you can upload files from a device. The article also includes
information about topics such as the notifications the upload process can send.
Manage device identities in IoT Hub describes what information each IoT hub's identity registry stores. The
article also describes how you can access and modify it.
Control access to IoT Hub describes the security model used to grant access to IoT Hub functionality for both
devices and cloud components. The article includes information about using tokens and X.509 certificates, and
details of the permissions you can grant.
Use device twins to synchronize state and configurations describes the device twin concept. The article also
descibes the functionality device twins expose, such as synchronizing a device with its device twin. The article
includes information about the data stored in a device twin.
Invoke a direct method on a device describes the lifecycle of a direct method. The article describes how to
invoke methods on a device from your back-end app and handle the direct method on your device.
Schedule jobs on multiple devices describes how you can schedule jobs on multiple devices. The article
describes how to submit jobs that perform tasks as executing a direct method, updating a device using a device
twin. It also describes how to query the status of a job.
Reference - choose a communication protocol describes the communication protocols that IoT Hub supports for
device communication and lists the ports that should be open.
Reference - IoT Hub endpoints describes the various endpoints that each IoT hub exposes for runtime and
management operations. The article also describes how you can create additional endpoints in your IoT hub,
and how to use a field gateway to enable connectivity to your IoT Hub endpoints in non-standard scenarios.
Reference - IoT Hub query language for device twins, jobs, and message routing describes that IoT Hub query
language that enables you to retrieve information from your hub about your device twins and jobs.
Reference - quotas and throttling summarizes the quotas set in the IoT Hub service and the throttling that
occurs when you exceed a quota.
Reference - pricing provides general information on different SKUs and pricing for IoT Hub and details on how
the various IoT Hub functionalities are metered as messages by IoT Hub.
Reference - Device and service SDKs lists the Azure IoT SDKs for developing device and service apps that
interact with your IoT hub. The article includes links to online API documentation.
Reference - IoT Hub MQTT support provides detailed information about how IoT Hub supports the MQTT
protocol. The article describes the support for the MQTT protocol built-in to the Azure IoT SDKs and provides
information about using the MQTT protocol directly.
Glossary a list of common IoT Hub-related terms.
Device-to-cloud communications guidance
5/29/2018 • 1 min to read • Edit Online

When sending information from the device app to the solution back end, IoT Hub exposes three options:
Device-to-cloud messages for time series telemetry and alerts.
Device twin's reported properties for reporting device state information such as available capabilities,
conditions, or the state of long-running workflows. For example, configuration and software updates.
File uploads for media files and large telemetry batches uploaded by intermittently connected devices or
compressed to save bandwidth.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are only
available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to choose
the right IoT Hub tier.

Here is a detailed comparison of the various device-to-cloud communication options.

DEVICE TWIN'S REPORTED


DEVICE-TO-CLOUD MESSAGES PROPERTIES FILE UPLOADS

Scenario Telemetry time series and Available capabilities and Media files. Large (typically
alerts. For example, 256-KB conditions. For example, the compressed) telemetry
sensor data batches sent current device connectivity batches.
every 5 minutes. mode such as cellular or
WiFi. Synchronizing long-
running workflows, such as
configuration and software
updates.

Storage and retrieval Temporarily stored by IoT Stored by IoT Hub in the Stored in user-provided
Hub, up to 7 days. Only device twin. Retrievable using Azure Storage account.
sequential reading. the IoT Hub query language.

Size Up to 256-KB messages. Maximum reported Maximum file size supported


properties size is 8 KB. by Azure Blob Storage.

Frequency High. For more information, Medium. For more Low. For more information,
see IoT Hub limits. information, see IoT Hub see IoT Hub limits.
limits.

Protocol Available on all protocols. Available using MQTT or Available when using any
AMQP. protocol, but requires HTTPS
on the device.

An application may need to send information both as a telemetry time series or alert and make it available in the
device twin. In this scenario, you can choose one of the following options:
The device app sends a device-to-cloud message and reports a property change.
The solution back end can store the information in the device twin's tags when it receives the message.
Since device-to-cloud messages enable a much higher throughput than device twin updates, it is sometimes
desirable to avoid updating the device twin for every device-to-cloud message.
Cloud-to-device communications guidance
5/29/2018 • 1 min to read • Edit Online

IoT Hub provides three options for device apps to expose functionality to a back-end app:
Direct methods for communications that require immediate confirmation of the result. Direct methods are often
used for interactive control of devices such as turning on a fan.
Twin's desired properties for long-running commands intended to put the device into a certain desired state. For
example, set the telemetry send interval to 30 minutes.
Cloud-to-device messages for one-way notifications to the device app.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Here is a detailed comparison of the various cloud-to-device communication options.

DIRECT METHODS TWIN'S DESIRED PROPERTIES CLOUD-TO-DEVICE MESSAGES

Scenario Commands that require Long-running commands One-way notifications to the


immediate confirmation, intended to put the device device app.
such as turning on a fan. into a certain desired state.
For example, set the
telemetry send interval to
30 minutes.

Data flow Two-way. The device app can One-way. The device app One-way. The device app
respond to the method right receives a notification with receives the message
away. The solution back end the property change.
receives the outcome
contextually to the request.

Durability Disconnected devices are not Property values are Messages can be retained by
contacted. The solution back preserved in the device twin. IoT Hub for up to 48 hours.
end is notified that the Device will read it at next
device is not connected. reconnection. Property
values are retrievable with
the IoT Hub query language.

Targets Single device using Single device using Single device by deviceId.
deviceId, or multiple devices deviceId, or multiple devices
using jobs. using jobs.

Size Maximum direct method Maximum desired properties Up to 64 KB messages.


payload size is 128 KB. size is 8 KB.

Frequency High. For more information, Medium. For more Low. For more information,
see IoT Hub limits. information, see IoT Hub see IoT Hub limits.
limits.
DIRECT METHODS TWIN'S DESIRED PROPERTIES CLOUD-TO-DEVICE MESSAGES

Protocol Available using MQTT or Available using MQTT or Available on all protocols.
AMQP. AMQP. Device must poll when using
HTTPS.

Learn how to use direct methods, desired properties, and cloud-to-device messages in the following tutorials:
Use direct methods, for direct methods;
Use desired properties to configure devices, for device twin's desired properties;
Send cloud-to-device messages, for cloud-to-device messages.
Device-to-cloud and cloud-to-device messaging with
IoT Hub
5/29/2018 • 1 min to read • Edit Online

Use IoT Hub messaging to communicate with your devices by:


Sending device-to-cloud messages from your devices to your solution back end.
Sending cloud-to-device messages from the solution back end to your devices.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are only
available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to choose
the right IoT Hub tier.

Core properties of IoT Hub messaging functionality are the reliability and durability of messages. These properties
enable resilience to intermittent connectivity on the device side, and to load spikes in event processing on the cloud
side. IoT Hub implements at least once delivery guarantees for both device-to-cloud and cloud-to-device
messaging.
For an introduction to the capabilities of IoT Hub, see the Overview of the Azure IoT Hub service.

When to use IoT Hub messaging


Use device-to-cloud messages for sending time series telemetry and alerts from your device app, and cloud-to-
device messages for one-way notifications to your device app.
Refer to Device-to-cloud communication guidance if in doubt between using device-to-cloud messages,
reported properties, or file upload.
Refer to Cloud-to-device communication guidance if in doubt between using cloud-to-device messages, desired
properties, or direct methods.

Next steps
Learn about IoT Hub device-to-cloud messaging.
Learn about IoT Hub cloud-to-device messaging.
Send device-to-cloud messages to IoT Hub
6/6/2018 • 3 min to read • Edit Online

To send time-series telemetry and alerts from your devices to your solution back end, send device-to-cloud
messages from your device to your IoT hub. For a discussion of other device-to-cloud options supported by IoT
Hub, see Device-to-cloud communications guidance.
You send device-to-cloud messages through a device-facing endpoint (/devices/{deviceId}/messages/events).
Routing rules then route your messages to one of the service-facing endpoints on your IoT hub. Routing rules use
the headers and body of the device-to-cloud messages to determine where to route them. By default, messages are
routed to the built-in service-facing endpoint (messages/events), that is compatible with Event Hubs. Therefore,
you can use standard Event Hubs integration and SDKs to receive device-to-cloud messages in your solution back
end.
IoT Hub implements device-to-cloud messaging using a streaming messaging pattern. IoT Hub's device-to-cloud
messages are more like Event Hubs events than Service Bus messages in that there is a high volume of events
passing through the service that can be read by multiple readers.
Device-to-cloud messaging with IoT Hub has the following characteristics:
Device-to-cloud messages are durable and retained in an IoT hub's default messages/events endpoint for up
to seven days.
Device-to-cloud messages can be at most 256 KB, and can be grouped in batches to optimize sends. Batches can
be at most 256 KB.
As explained in the Control access to IoT Hub section, IoT Hub enables per-device authentication and access
control.
IoT Hub allows you to create up to 10 custom endpoints. Messages are delivered to the endpoints based on
routes configured on your IoT hub. For more information, see Routing rules.
IoT Hub enables millions of simultaneously connected devices (see Quotas and throttling).
IoT Hub does not allow arbitrary partitioning. Device-to-cloud messages are partitioned based on their
originating deviceId.
For more information about the differences between IoT Hub and Event Hubs, see Comparison of Azure IoT Hub
and Azure Event Hubs.

Send non-telemetry traffic


Often, in addition to telemetry, devices send messages and requests that require separate execution and handling in
the solution back end. For example, critical alerts that must trigger a specific action in the back end. You can write a
routing rule to send these types of messages to an endpoint dedicated to their processing based on either a header
on the message or a value in the message body.
For more information about the best way to process this kind of message, see the Tutorial: How to process IoT Hub
device-to-cloud messages tutorial.

Route device-to-cloud messages


You have two options for routing device-to-cloud messages to your back-end apps:
Use the built-in Event Hub-compatible endpoint to enable back-end apps to read the device-to-cloud messages
received by the hub. To learn about the built-in Event Hub-compatible endpoint, see Read device-to-cloud
messages from the built-in endpoint.
Use routing rules to send messages to custom endpoints in your IoT hub. Custom endpoints enable your back-
end apps to read device-to-cloud messages using Event Hubs, Service Bus queues, or Service Bus topics. To
learn about routing and custom endpoints, see Use custom endpoints and routing rules for device-to-cloud
messages.

Anti-spoofing properties
To avoid device spoofing in device-to-cloud messages, IoT Hub stamps all messages with the following properties:
ConnectionDeviceId
ConnectionDeviceGenerationId
ConnectionAuthMethod
The first two contain the deviceId and generationId of the originating device, as per Device identity properties.
The ConnectionAuthMethod property contains a JSON serialized object, with the following properties:

{
"scope": "{ hub | device }",
"type": "{ symkey | sas | x509 }",
"issuer": "iothub"
}

Next steps
For information about the SDKs you can use to send device-to-cloud messages, see Azure IoT SDKs.
The Get Started tutorials show you how to send device-to-cloud messages from both simulated and physical
devices. For more detail, see the Process IoT Hub device-to-cloud messages using routes tutorial.
Read device-to-cloud messages from the built-in
endpoint
6/6/2018 • 2 min to read • Edit Online

By default, messages are routed to the built-in service-facing endpoint (messages/events) that is compatible with
Event Hubs. This endpoint is currently only exposed using the AMQP protocol on port 5671. An IoT hub exposes
the following properties to enable you to control the built-in Event Hub-compatible messaging endpoint
messages/events.

PROPERTY DESCRIPTION

Partition count Set this property at creation to define the number of


partitions for device-to-cloud event ingestion.

Retention time This property specifies how long in days messages are retained
by IoT Hub. The default is one day, but it can be increased to
seven days.

IoT Hub also enables you to manage consumer groups on the built-in device-to-cloud receive endpoint.
By default, all messages that do not explicitly match a message routing rule are written to the built-in endpoint. If
you disable this fallback route, messages that do not explicitly match any message routing rules are dropped.
You can modify the retention time, either programmatically using the IoT Hub resource provider REST APIs, or
with the Azure portal.
IoT Hub exposes the messages/events built-in endpoint for your back-end services to read the device-to-cloud
messages received by your hub. This endpoint is Event Hub-compatible, which enables you to use any of the
mechanisms the Event Hubs service supports for reading messages.

Read from the built-in endpoint


When you use the Azure Service Bus SDK for .NET or the Event Hubs - Event Processor Host, you can use any IoT
Hub connection strings with the correct permissions. Then use messages/events as the Event Hub name.
When you use SDKs (or product integrations) that are unaware of IoT Hub, you must retrieve an Event Hub-
compatible endpoint and Event Hub-compatible name:
1. Sign in to the Azure portal and navigate to your IoT hub.
2. Click Endpoints.
3. In the Built-in endpoints section, click Events.
4. A properties page opens, which contains the following values: Event Hub-compatible endpoint, Event
Hub-compatible name, Partitions, Retention time, and Consumer groups.
The IoT Hub SDK requires the IoT Hub endpoint name, which is messages/events as shown under Endpoints.
If the SDK you are using requires a Hostname or Namespace value, remove the scheme from the Event Hub-
compatible endpoint. For example, if your Event Hub-compatible endpoint is sb://iothub-ns-myiothub-
1234.servicebus.windows.net/, the Hostname would be iothub-ns-myiothub-1234.servicebus.windows.net.
The Namespace would be iothub-ns-myiothub-1234.
You can then use any shared access policy that has the ServiceConnect permissions to connect to the specified
Event Hub.
If you need to build an Event Hub connection string by using the previous information, use the following pattern:
Endpoint={Event Hub-compatible endpoint};SharedAccessKeyName={iot hub policy name};SharedAccessKey={iot hub
policy key}

The SDKs and integrations that you can use with Event Hub-compatible endpoints that IoT Hub exposes includes
the items in the following list:
Java Event Hubs client.
Apache Storm spout. You can view the spout source on GitHub.
Apache Spark integration.

Next steps
For more information about IoT Hub endpoints, see IoT Hub endpoints.
The Get Started tutorials show you how to send device-to-cloud messages from simulated devices and read the
messages from the built-in endpoint. For more detail, see the Process IoT Hub device-to-cloud messages using
routes tutorial.
If you want to route your device-to-cloud messages to custom endpoints, see Use message routes and custom
endpoints for device-to-cloud messages.
React to IoT Hub events by using Event Grid to
trigger actions - Preview
5/29/2018 • 2 min to read • Edit Online

Azure IoT Hub integrates with Azure Event Grid so that you can send event notifications to other services and
trigger downstream processes. Configure your business applications to listen for IoT Hub events so that you can
react to critical events in a reliable, scalable, and secure manner. For example, build an application to perform
multiple actions like updating a database, creating a ticket, and delivering an email notification every time a new IoT
device is registered to your IoT hub.
Azure Event Grid is a fully managed event routing service that uses a publish-subscribe model. Event Grid has
built-in support for Azure services like Azure Functions and Azure Logic Apps, and can deliver event alerts to non-
Azure services using webhooks. For a complete list of the event handlers that Event Grid supports, see An
introduction to Azure Event Grid.

Regional availability
The Event Grid integration is available for IoT hubs located in the regions where Event Grid is supported. For the
latest list of regions, see An introduction to Azure Event Grid.

Event types
IoT Hub publishes the following event types:

EVENT TYPE DESCRIPTION

Microsoft.Devices.DeviceCreated Published when a device is registered to an IoT hub.

Microsoft.Devices.DeviceDeleted Published when a device is deleted from an IoT hub.


Use either the Azure portal or Azure CLI to configure which events to publish from each IoT hub. For an example,
try the tutorial Send email notifications about Azure IoT Hub events using Logic Apps.

Event schema
IoT Hub events contain all the information you need to respond to changes in your device lifecycle. You can identify
an IoT Hub event by checking that the eventType property starts with Microsoft.Devices. For more information
about how to use Event Grid event properties, see the Event Grid event schema.
Device created schema
The following example shows the schema of a device created event:

[{
"id": "56afc886-767b-d359-d59e-0da7877166b2",
"topic": "/SUBSCRIPTIONS/<subscription ID>/RESOURCEGROUPS/<resource group
name>/PROVIDERS/MICROSOFT.DEVICES/IOTHUBS/<hub name>",
"subject": "devices/LogicAppTestDevice",
"eventType": "Microsoft.Devices.DeviceCreated",
"eventTime": "2018-01-02T19:17:44.4383997Z",
"data": {
"twin": {
"deviceId": "LogicAppTestDevice",
"etag": "AAAAAAAAAAE=",
"status": "enabled",
"statusUpdateTime": "0001-01-01T00:00:00",
"connectionState": "Disconnected",
"lastActivityTime": "0001-01-01T00:00:00",
"cloudToDeviceMessageCount": 0,
"authenticationType": "sas",
"x509Thumbprint": {
"primaryThumbprint": null,
"secondaryThumbprint": null
},
"version": 2,
"properties": {
"desired": {
"$metadata": {
"$lastUpdated": "2018-01-02T19:17:44.4383997Z"
},
"$version": 1
},
"reported": {
"$metadata": {
"$lastUpdated": "2018-01-02T19:17:44.4383997Z"
},
"$version": 1
}
}
},
"hubName": "egtesthub1",
"deviceId": "LogicAppTestDevice",
"operationTimestamp": "2018-01-02T19:17:44.4383997Z",
"opType": "DeviceCreated"
},
"dataVersion": "",
"metadataVersion": "1"
}]

For a detailed description of each property, see Azure Event Grid event schema for IoT Hub

Filter events
IoT Hub event subscriptions can filter events based on event type and device name. Subject filters in Event Grid
work based on prefix and suffix matches. The filter uses an AND operator, so events with a subject that match both
the prefix and suffix are delivered to the subscriber.
The subject of IoT Events uses the format:

devices/{deviceId}

Tips for consuming events


Applications that handle IoT Hub events should follow these suggested practices:
Multiple subscriptions can be configured to route events to the same event handler, so it's important not to
assume that events are from a particular source. Always check the message topic to ensure that it comes from
the IoT hub that you expect.
Don't assume that all events you receive are the types that you expect. Always check the eventType before
processing the message.
Messages can arrive out of order or after a delay. Use the etag field to understand if your information about
objects is up-to-date.

Next steps
Try the IoT Hub events tutorial
Learn more about Event Grid
Compare the differences between routing IoT Hub events and messages
Use message routes and custom endpoints for
device-to-cloud messages
6/6/2018 • 2 min to read • Edit Online

IoT Hub enables you to route device-to-cloud messages to IoT Hub service-facing endpoints based on message
properties. Routing rules give you the flexibility to send messages where they need to go without the need for
additional services or custom code. Each routing rule you configure has the following properties:

PROPERTY DESCRIPTION

Name The unique name that identifies the rule.

Source The origin of the data stream to be acted upon. For example,
device telemetry.

Condition The query expression for the routing rule that is run against
the message's headers and body and determines if it is a
match for the endpoint. For more information about
constructing a route condition, see the Reference - query
language for device twins and jobs.

Endpoint The name of the endpoint where IoT Hub sends messages that
match the condition. Endpoints should be in the same region
as the IoT hub, otherwise you may be charged for cross-
region writes.

A single message may match the condition on multiple routing rules, in which case IoT Hub delivers the message
to the endpoint associated with each matched rule. IoT Hub also automatically deduplicates message delivery, so if
a message matches multiple rules that have the same destination, it is only written once to that destination.

Endpoints and routing


An IoT hub has a default built-in endpoint. You can create custom endpoints to route messages to by linking other
services in your subscription to the hub. IoT Hub currently supports Azure Storage containers, Event Hubs, Service
Bus queues, and Service Bus topics as custom endpoints.
When you use routing and custom endpoints, messages are only delivered to the built-in endpoint if they don't
match any rules. To deliver messages to the built-in endpoint as well as to a custom endpoint, add a route that
sends messages to the events endpoint.

NOTE
IoT Hub only supports writing data to Azure Storage containers as blobs.

WARNING
Service Bus queues and topics with Sessions or Duplicate Detection enabled are not supported as custom endpoints.

For more information about creating custom endpoints in IoT Hub, see IoT Hub endpoints.
For more information about reading from custom endpoints, see:
Reading from Azure Storage containers.
Reading from Event Hubs.
Reading from Service Bus queues.
Reading from Service Bus topics.

Latency
When you route device-to-cloud telemetry messages using built-in endpoints, there is a slight increase in the end-
to-end latency after the creation of the first route.
In most cases, the average increase in latency is less than one second. You can monitor the latency using
d2c.endpoints.latency.builtIn.events IoT Hub metric. Creating or deleting any route after the first one does not
impact the end-to-end latency.
Next steps
For more information about IoT Hub endpoints, see IoT Hub endpoints.
For more information about the query language you use to define routing rules, see IoT Hub query language for
device twins, jobs, and message routing.
The Process IoT Hub device-to-cloud messages using routes tutorial shows you how to use routing rules and
custom endpoints.
Send cloud-to-device messages from IoT Hub
5/29/2018 • 5 min to read • Edit Online

To send one-way notifications to the device app from your solution back end, send cloud-to-devices messages from
your IoT hub to your device. For a discussion of other cloud-to-devices options supported by IoT Hub, see Cloud-
to-device communications guidance.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

You send cloud-to-device messages through a service-facing endpoint (/messages/devicebound). A device then
receives the messages through a device-specific endpoint (/devices/{deviceId}/messages/devicebound).
To target each cloud-to-device message at a single device, IoT Hub sets the to property to
/devices/{deviceId}/messages/devicebound.
Each device queue holds at most 50 cloud-to-device messages. Trying to send more messages to the same device
results in an error.

The cloud-to-device message lifecycle


To guarantee at-least-once message delivery, IoT Hub persists cloud-to-device messages in per-device queues.
Devices must explicitly acknowledge completion for IoT Hub to remove them from the queue. This approach
guarantees resiliency against connectivity and device failures.
The following diagram shows the lifecycle state graph for a cloud-to-device message in IoT Hub.

When the IoT Hub service sends a message to a device, the service sets the message state to Enqueued. When a
device wants to receive a message, IoT Hub locks the message (by setting the state to Invisible), which allows
other threads on the device to start receiving other messages. When a device thread completes the processing of a
message, it notifies IoT Hub by completing the message. IoT Hub then sets the state to Completed.
A device can also choose to:
Reject the message, which causes IoT Hub to set it to the Dead lettered state. Devices that connect over the
MQTT protocol cannot reject cloud-to-device messages.
Abandon the message, which causes IoT Hub to put the message back in the queue, with the state set to
Enqueued. Devices that connect over the MQTT protocol cannot abandon cloud-to-device messages.
A thread could fail to process a message without notifying IoT Hub. In this case, messages automatically transition
from the Invisible state back to the Enqueued state after a visibility (or lock) timeout. The default value of this
timeout is one minute.
The max delivery count property on IoT Hub determines the maximum number of times a message can
transition between the Enqueued and Invisible states. After that number of transitions, IoT Hub sets the state of
the message to Dead lettered. Similarly, IoT Hub sets the state of a message to Dead lettered after its expiration
time (see Time to live).
The How to send cloud-to-device messages with IoT Hub shows you how to send cloud-to-device messages from
the cloud and receive them on a device.
Typically, a device completes a cloud-to-device message when the loss of the message does not affect the
application logic. For example, when the device has persisted the message content locally or has successfully
executed an operation. The message could also carry transient information, whose loss would not impact the
functionality of the application. Sometimes, for long-running tasks, you can:
Complete the cloud-to-device message after persisting the task description in local storage.
Notify the solution back end with one or more device-to-cloud messages at various stages of progress of the
task.

Message expiration (time to live)


Every cloud-to-device message has an expiration time. This time is set by one of:
The ExpiryTimeUtc property in the service.
IoT Hub using the default time to live specified as an IoT Hub property.
See Cloud-to-device configuration options.
A common way to take advantage of message expiration and avoid sending messages to disconnected devices, is to
set short time to live values. This approach achieves the same result as maintaining the device connection state,
while being more efficient. When you request message acknowledgements, IoT Hub notifies you which devices are:
Able to receive messages.
Are not online or have failed.

Message feedback
When you send a cloud-to-device message, the service can request the delivery of per-message feedback regarding
the final state of that message.

ACK PROPERTY BEHAVIOR

positive If the cloud-to-device message reaches the Completed state,


IoT Hub generates a feedback message.

negative If the cloud-to-device message reaches the Dead lettered


state, IoT Hub generates a feedback message.

full IoT Hub generates a feedback message in either case.


If Ack is full, and you don't receive a feedback message, it means that the feedback message expired. The service
can't know what happened to the original message. In practice, a service should ensure that it can process the
feedback before it expires. The maximum expiry time is two days, which leaves time to get the service running
again if a failure occurs.
As explained in Endpoints, IoT Hub delivers feedback through a service-facing endpoint
(/messages/servicebound/feedback) as messages. The semantics for receiving feedback are the same as for
cloud-to-device messages. Whenever possible, message feedback is batched in a single message, with the following
format:

PROPERTY DESCRIPTION

EnqueuedTime Timestamp indicating when the feedback message was


received by the hub.

UserId {iot hub name}

ContentType application/vnd.microsoft.iothub.feedback.json

The body is a JSON -serialized array of records, each with the following properties:

PROPERTY DESCRIPTION

EnqueuedTimeUtc Timestamp indicating when the outcome of the message


happened. For example, the hub received the feedback
message or the original message expired.

OriginalMessageId MessageId of the cloud-to-device message to which this


feedback information relates.

StatusCode Required string. Used in feedback messages generated by IoT


Hub.
'Success'
'Expired'
'DeliveryCountExceeded'
'Rejected'
'Purged'

Description String values for StatusCode.

DeviceId DeviceId of the target device of the cloud-to-device message


to which this piece of feedback relates.

DeviceGenerationId DeviceGenerationId of the target device of the cloud-to-


device message to which this piece of feedback relates.

The service must specify a MessageId for the cloud-to-device message to be able to correlate its feedback with the
original message.
The following example shows the body of a feedback message.
[
{
"OriginalMessageId": "0987654321",
"EnqueuedTimeUtc": "2015-07-28T16:24:48.789Z",
"StatusCode": 0,
"Description": "Success",
"DeviceId": "123",
"DeviceGenerationId": "abcdefghijklmnopqrstuvwxyz"
},
{
...
},
...
]

Cloud-to-device configuration options


Each IoT hub exposes the following configuration options for cloud-to-device messaging:

PROPERTY DESCRIPTION RANGE AND DEFAULT

defaultTtlAsIso8601 Default TTL for cloud-to-device ISO_8601 interval up to 2D (minimum 1


messages. minute). Default: 1 hour.

maxDeliveryCount Maximum delivery count for cloud-to- 1 to 100. Default: 10.


device per-device queues.

feedback.ttlAsIso8601 Retention for service-bound feedback ISO_8601 interval up to 2D (minimum 1


messages. minute). Default: 1 hour.

feedback.maxDeliveryCount Maximum delivery count for feedback 1 to 100. Default: 100.


queue.

For more information about how to set these configuration options, see Create IoT hubs.

Next steps
For information about the SDKs you can use to receive cloud-to-device messages, see Azure IoT SDKs.
To try out receiving cloud-to-device messages, see the Send cloud-to-device tutorial.
Create and read IoT Hub messages
5/29/2018 • 3 min to read • Edit Online

To support seamless interoperability across protocols, IoT Hub defines a common message format for all device-
facing protocols. This message format is used for both device-to-cloud and cloud-to-device messages.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are only
available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to choose
the right IoT Hub tier.

An IoT Hub message consists of:


A set of system properties. Properties that IoT Hub interprets or sets. This set is predetermined.
A set of application properties. A dictionary of string properties that the application can define and access,
without needing to deserialize the message body. IoT Hub never modifies these properties.
An opaque binary body.
Property names and values can only contain ASCII alphanumeric characters, plus
{'!', '#', '$', '%, '&', "'", '*', '+', '-', '.', '^', '_', '`', '|', '~'} when you:

Send device-to-cloud messages using the HTTPS protocol.


Send cloud-to-device messages.
For more information about how to encode and decode messages sent using different protocols, see Azure IoT
SDKs.
The following table lists the set of system properties in IoT Hub messages.

PROPERTY DESCRIPTION

MessageId A user-settable identifier for the message used for request-


reply patterns. Format: A case-sensitive string (up to 128
characters long) of ASCII 7-bit alphanumeric characters +
{'-', ':',’.', '+', '%', '_', '#', '*', '?', '!',
'(', ')', ',', '=', '@', ';', '$', '''}
.

Sequence number A number (unique per device-queue) assigned by IoT Hub to


each cloud-to-device message.

To A destination specified in Cloud-to-Device messages.

ExpiryTimeUtc Date and time of message expiration.

EnqueuedTime Date and time the Cloud-to-Device message was received by


IoT Hub.

CorrelationId A string property in a response message that typically


contains the MessageId of the request, in request-reply
patterns.
PROPERTY DESCRIPTION

UserId An ID used to specify the origin of messages. When messages


are generated by IoT Hub, it is set to {iot hub name} .

Ack A feedback message generator. This property is used in cloud-


to-device messages to request IoT Hub to generate feedback
messages as a result of the consumption of the message by
the device. Possible values: none (default): no feedback
message is generated, positive: receive a feedback message if
the message was completed, negative: receive a feedback
message if the message expired (or maximum delivery count
was reached) without being completed by the device, or full:
both positive and negative. For more information, see
Message feedback.

ConnectionDeviceId An ID set by IoT Hub on device-to-cloud messages. It contains


the deviceId of the device that sent the message.

ConnectionDeviceGenerationId An ID set by IoT Hub on device-to-cloud messages. It contains


the generationId (as per Device identity properties) of the
device that sent the message.

ConnectionAuthMethod An authentication method set by IoT Hub on device-to-cloud


messages. This property contains information about the
authentication method used to authenticate the device
sending the message. For more information, see Device to
cloud anti-spoofing.

CreationTimeUtc Date and time the message was created on a device. A device
must set this value explicitly.

Message size
IoT Hub measures message size in a protocol-agnostic way, considering only the actual payload. The size in bytes is
calculated as the sum of the following:
The body size in bytes.
The size in bytes of all the values of the message system properties.
The size in bytes of all user property names and values.
Property names and values are limited to ASCII characters, so the length of the strings equals the size in bytes.

Next steps
For information about message size limits in IoT Hub, see IoT Hub quotas and throttling.
To learn how to create and read IoT Hub messages in various programming languages, see the Get started
tutorials.
Reference - choose a communication protocol
5/29/2018 • 2 min to read • Edit Online

IoT Hub allows devices to use the following protocols for device-side communications:
MQTT
MQTT over WebSockets
AMQP
AMQP over WebSockets
HTTPS
For information about how these protocols support specific IoT Hub features, see Device-to-cloud communications
guidance and Cloud-to-device communications guidance.
The following table provides the high-level recommendations for your choice of protocol:

PROTOCOL WHEN YOU SHOULD CHOOSE THIS PROTOCOL

MQTT Use on all devices that do not require to connect multiple


MQTT over WebSocket devices (each with its own per-device credentials) over the
same TLS connection.

AMQP Use on field and cloud gateways to take advantage of


AMQP over WebSocket connection multiplexing across devices.

HTTPS Use for devices that cannot support other protocols.

Consider the following points when you choose your protocol for device-side communications:
Cloud-to-device pattern. HTTPS does not have an efficient way to implement server push. As such, when you
are using HTTPS, devices poll IoT Hub for cloud-to-device messages. This approach is inefficient for both the
device and IoT Hub. Under current HTTPS guidelines, each device should poll for messages every 25 minutes or
more. MQTT and AMQP support server push when receiving cloud-to-device messages. They enable
immediate pushes of messages from IoT Hub to the device. If delivery latency is a concern, MQTT or AMQP are
the best protocols to use. For rarely connected devices, HTTPS works as well.
Field gateways. When using MQTT and HTTPS, you cannot connect multiple devices (each with its own per-
device credentials) using the same TLS connection. For Field gateway scenarios that require one TLS connection
between the field gateway and IoT Hub for each connected device, these protocols are suboptimal.
Low resource devices. The MQTT and HTTPS libraries have a smaller footprint than the AMQP libraries. As
such, if the device has limited resources (for example, less than 1-MB RAM ), these protocols might be the only
protocol implementation available.
Network traversal. The standard AMQP protocol uses port 5671, and MQTT listens on port 8883. USe of
these ports could cause problems in networks that are closed to non-HTTPS protocols. Use MQTT over
WebSockets, AMQP over WebSockets, or HTTPS in this scenario.
Payload size. MQTT and AMQP are binary protocols, which result in more compact payloads than HTTPS.
WARNING
When using HTTPS, each device should poll for cloud-to-device messages every 25 minutes or more. However, during
development, it is acceptable to poll more frequently than every 25 minutes.

Port numbers
Devices can communicate with IoT Hub in Azure using various protocols. Typically, the choice of protocol is driven
by the specific requirements of the solution. The following table lists the outbound ports that must be open for a
device to be able to use a specific protocol:

PROTOCOL PORT

MQTT 8883

MQTT over WebSockets 443

AMQP 5671

AMQP over WebSockets 443

HTTPS 443

Once you have created an IoT hub in an Azure region, the IoT hub keeps the same IP address for the lifetime of
that IoT hub. However, if Microsoft moves the IoT hub to a different scale unit to maintain quality of service, then it
is assigned a new IP address.

Next steps
To learn more about how IoT Hub implements the MQTT protocol, see Communicate with your IoT hub using the
MQTT protocol.
Upload files with IoT Hub
5/29/2018 • 5 min to read • Edit Online

As detailed in the IoT Hub endpoints article, a device can initiate a file upload by sending a notification through a
device-facing endpoint (/devices/{deviceId}/files). When a device notifies IoT Hub that an upload is complete,
IoT Hub sends a file upload notification message through the /messages/servicebound/filenotifications
service-facing endpoint.
Instead of brokering messages through IoT Hub itself, IoT Hub instead acts as a dispatcher to an associated Azure
Storage account. A device requests a storage token from IoT Hub that is specific to the file the device wishes to
upload. The device uses the SAS URI to upload the file to storage, and when the upload is complete the device
sends a notification of completion to IoT Hub. IoT Hub checks the file upload is complete and then adds a file
upload notification message to the service-facing file notification endpoint.
Before you upload a file to IoT Hub from a device, you must configure your hub by associating an Azure Storage
account to it.
Your device can then initialize an upload and then notify IoT hub when the upload completes. Optionally, when a
device notifies IoT Hub that the upload is complete, the service can generate a notification message.
When to use
Use file upload to send media files and large telemetry batches uploaded by intermittently connected devices or
compressed to save bandwidth.
Refer to Device-to-cloud communication guidance if in doubt between using reported properties, device-to-cloud
messages, or file upload.

Associate an Azure Storage account with IoT Hub


To use the file upload functionality, you must first link an Azure Storage account to the IoT Hub. You can complete
this task either through the Azure portal, or programmatically through the IoT Hub resource provider REST APIs.
Once you have associated an Azure Storage account with your IoT Hub, the service returns a SAS URI to a device
when the device initiates a file upload request.

NOTE
The Azure IoT SDKs automatically handle retrieving the SAS URI, uploading the file, and notifying IoT Hub of a completed
upload.

Initialize a file upload


IoT Hub has an endpoint specifically for devices to request a SAS URI for storage to upload a file. To initiate the file
upload process, the device sends a POST request to {iot hub}.azure-devices.net/devices/{deviceId}/files with the
following JSON body:

{
"blobName": "{name of the file for which a SAS URI will be generated}"
}

IoT Hub returns the following data, which the device uses to upload the file:
{
"correlationId": "somecorrelationid",
"hostName": "contoso.azure-devices.net",
"containerName": "testcontainer",
"blobName": "test-device1/image.jpg",
"sasToken": "1234asdfSAStoken"
}

Deprecated: initialize a file upload with a GET

NOTE
This section describes deprecated functionality for how to receive a SAS URI from IoT Hub. Use the POST method described
previously.

IoT Hub has two REST endpoints to support file upload, one to get the SAS URI for storage and the other to notify
the IoT hub of a completed upload. The device initiates the file upload process by sending a GET to the IoT hub at
{iot hub}.azure-devices.net/devices/{deviceId}/files/{filename} . The IoT hub returns:

A SAS URI specific to the file to be uploaded.


A correlation ID to be used once the upload is completed.

Notify IoT Hub of a completed file upload


The device is responsible for uploading the file to storage using the Azure Storage SDKs. When the upload is
complete, the device sends a POST request to {iot hub}.azure-devices.net/devices/{deviceId}/files/notifications
with the following JSON body:

{
"correlationId": "{correlation ID received from the initial request}",
"isSuccess": bool,
"statusCode": XXX,
"statusDescription": "Description of status"
}

The value of isSuccess is a Boolean representing whether the file was uploaded successfully. The status code for
statusCode is the status for the upload of the file to storage, and the statusDescription corresponds to the
statusCode .

Reference topics:
The following reference topics provide you with more information about uploading files from a device.

File upload notifications


Optionally, when a device notifies IoT Hub that an upload is complete, IoT Hub generates a notification message
that contains the name and storage location of the file.
As explained in Endpoints, IoT Hub delivers file upload notifications through a service-facing endpoint
(/messages/servicebound/fileuploadnotifications) as messages. The receive semantics for file upload
notifications are the same as for cloud-to-device messages and have the same message lifecycle. Each message
retrieved from the file upload notification endpoint is a JSON record with the following properties:
PROPERTY DESCRIPTION

EnqueuedTimeUtc Timestamp indicating when the notification was created.

DeviceId DeviceId of the device which uploaded the file.

BlobUri URI of the uploaded file.

BlobName Name of the uploaded file.

LastUpdatedTime Timestamp indicating when the file was last updated.

BlobSizeInBytes Size of the uploaded file.

Example. This example shows the body of a file upload notification message.

{
"deviceId":"mydevice",
"blobUri":"https://{storage account}.blob.core.windows.net/{container name}/mydevice/myfile.jpg",
"blobName":"mydevice/myfile.jpg",
"lastUpdatedTime":"2016-06-01T21:22:41+00:00",
"blobSizeInBytes":1234,
"enqueuedTimeUtc":"2016-06-01T21:22:43.7996883Z"
}

File upload notification configuration options


Each IoT hub exposes the following configuration options for file upload notifications:

PROPERTY DESCRIPTION RANGE AND DEFAULT

enableFileUploadNotifications Controls whether file upload Bool. Default: True.


notifications are written to the file
notifications endpoint.

fileNotifications.ttlAsIso8601 Default TTL for file upload notifications. ISO_8601 interval up to 48H (minimum
1 minute). Default: 1 hour.

fileNotifications.lockDuration Lock duration for the file upload 5 to 300 seconds (minimum 5 seconds).
notifications queue. Default: 60 seconds.

fileNotifications.maxDeliveryCount Maximum delivery count for the file 1 to 100. Default: 100.
upload notification queue.

Additional reference material


Other reference topics in the IoT Hub developer guide include:
IoT Hub endpoints describes the various endpoints that each IoT hub exposes for run-time and management
operations.
Throttling and quotas describes the quotas and throttling behaviors that apply to the IoT Hub service.
Azure IoT device and service SDKs lists the various language SDKs you can use when you develop both device
and service apps that interact with IoT Hub.
IoT Hub query language describes the query language you can use to retrieve information from IoT Hub about
your device twins and jobs.
IoT Hub MQTT support provides more information about IoT Hub support for the MQTT protocol.

Next steps
Now you have learned how to upload files from devices using IoT Hub, you may be interested in the following IoT
Hub developer guide topics:
Manage device identities in IoT Hub
Control access to IoT Hub
Use device twins to synchronize state and configurations
Invoke a direct method on a device
Schedule jobs on multiple devices
To try out some of the concepts described in this article, see the following IoT Hub tutorial:
How to upload files from devices to the cloud with IoT Hub
Understand the identity registry in your IoT hub
5/29/2018 • 10 min to read • Edit Online

Every IoT hub has an identity registry that stores information about the devices and modules permitted to connect
to the IoT hub. Before a device or module can connect to an IoT hub, there must be an entry for that device or
module in the IoT hub's identity registry. A device or module must also authenticate with the IoT hub based on
credentials stored in the identity registry.
The device or module ID stored in the identity registry is case-sensitive.
At a high level, the identity registry is a REST-capable collection of device or module identity resources. When you
add an entry in the identity registry, IoT Hub creates a set of per-device resources such as the queue that contains
in-flight cloud-to-device messages.
Use the identity registry when you need to:
Provision devices or modules that connect to your IoT hub.
Control per-device/per-module access to your hub's device or module-facing endpoints.

NOTE
The identity registry does not contain any application-specific metadata.

Identity registry operations


The IoT Hub identity registry exposes the following operations:
Create device or module identity
Update device or module identity
Retrieve device or module identity by ID
Delete device or module identity
List up to 1000 identities > Module identity and module twin is in public preview. Below feature will be
supported on module identity when it's general available.
Export device identities to Azure blob storage
Import device identities from Azure blob storage
All these operations can use optimistic concurrency, as specified in RFC7232.

IMPORTANT
The only way to retrieve all identities in an IoT hub's identity registry is to use the Export functionality.

An IoT Hub identity registry:


Does not contain any application metadata.
Can be accessed like a dictionary, by using the deviceId or moduleId as the key.
Does not support expressive queries.
An IoT solution typically has a separate solution-specific store that contains application-specific metadata. For
example, the solution-specific store in a smart building solution would record the room in which a temperature
sensor is deployed.

IMPORTANT
Only use the identity registry for device management and provisioning operations. High throughput operations at run time
should not depend on performing operations in the identity registry. For example, checking the connection state of a device
before sending a command is not a supported pattern. Make sure to check the throttling rates for the identity registry, and
the device heartbeat pattern.

Disable devices
You can disable devices by updating the status property of an identity in the identity registry. Typically, you use this
property in two scenarios:
During a provisioning orchestration process. For more information, see Device Provisioning.
If, for any reason, you think a device is compromised or has become unauthorized.
This feature is not availble for modules.

Import and export device identities


Use asynchronous operations on the IoT Hub resource provider endpoint to export device identities in bulk from
an IoT hub's identity registry. Exports are long-running jobs that use a customer-supplied blob container to save
device identity data read from the identity registry.
Use asynchronous operations on the IoT Hub resource provider endpoint to import device identities in bulk to an
IoT hub's identity registry. Imports are long-running jobs that use data in a customer-supplied blob container to
write device identity data into the identity registry.
For more information about the import and export APIs, see IoT Hub resource provider REST APIs. To learn more
about running import and export jobs, see Bulk management of IoT Hub device identities.

Device provisioning
The device data that a given IoT solution stores depends on the specific requirements of that solution. But, as a
minimum, a solution must store device identities and authentication keys. Azure IoT Hub includes an identity
registry that can store values for each device such as IDs, authentication keys, and status codes. A solution can use
other Azure services such as table storage, blob storage, or Cosmos DB to store any additional device data.
Device provisioning is the process of adding the initial device data to the stores in your solution. To enable a new
device to connect to your hub, you must add a device ID and keys to the IoT Hub identity registry. As part of the
provisioning process, you might need to initialize device-specific data in other solution stores. You can also use the
Azure IoT Hub Device Provisioning Service to enable zero-touch, just-in-time provisioning to one or more IoT hubs
without requiring human intervention. To learn more, see the provisioning service documentation.

Device heartbeat
The IoT Hub identity registry contains a field called connectionState. Only use the connectionState field during
development and debugging. IoT solutions should not query the field at run time. For example, do not query the
connectionState field to check if a device is connected before you send a cloud-to-device message or an SMS.
If your IoT solution needs to know if a device is connected, you should implement the heartbeat pattern.
In the heartbeat pattern, the device sends device-to-cloud messages at least once every fixed amount of time (for
example, at least once every hour). Therefore, even if a device does not have any data to send, it still sends an
empty device-to-cloud message (usually with a property that identifies it as a heartbeat). On the service side, the
solution maintains a map with the last heartbeat received for each device. If the solution does not receive a
heartbeat message within the expected time from the device, it assumes that there is a problem with the device.
A more complex implementation could include the information from operations monitoring to identify devices that
are trying to connect or communicate but failing. When you implement the heartbeat pattern, make sure to check
IoT Hub Quotas and Throttles.

NOTE
If an IoT solution uses the connection state solely to determine whether to send cloud-to-device messages, and messages are
not broadcast to large sets of devices, consider using the simpler short expiry time pattern. This pattern achieves the same
result as maintaining a device connection state registry using the heartbeat pattern, while being more efficient. If you request
message acknowledgements, IoT Hub can notify you about which devices are able to receive messages and which are not.

Device and module lifecycle notifications


IoT Hub can notify your IoT solution when an identity is created or deleted by sending lifecycle notifications. To do
so, your IoT solution needs to create a route and to set the Data Source equal to DeviceLifecycleEvents or
ModuleLifecycleEvents. By default, no lifecycle notifications are sent, that is, no such routes pre-exist. The
notification message includes properties, and body.
Properties: Message system properties are prefixed with the '$' symbol.
Notification message for device:

NAME VALUE

$content-type application/json

$iothub-enqueuedtime Time when the notification was sent

$iothub-message-source deviceLifecycleEvents

$content-encoding utf-8

opType createDeviceIdentity or deleteDeviceIdentity

hubName Name of IoT Hub

deviceId ID of the device

operationTimestamp ISO8601 timestamp of operation

iothub-message-schema deviceLifecycleNotification

Body: This section is in JSON format and represents the twin of the created device identity. For example,
{
"deviceId":"11576-ailn-test-0-67333793211",
"etag":"AAAAAAAAAAE=",
"properties": {
"desired": {
"$metadata": {
"$lastUpdated": "2016-02-30T16:24:48.789Z"
},
"$version": 1
},
"reported": {
"$metadata": {
"$lastUpdated": "2016-02-30T16:24:48.789Z"
},
"$version": 1
}
}
}

Notification message for module:

NAME VALUE

$content-type application/json

$iothub-enqueuedtime Time when the notification was sent

$iothub-message-source moduleLifecycleEvents

$content-encoding utf-8

opType createModuleIdentity or deleteModuleIdentity

hubName Name of IoT Hub

moduleId ID of the module

operationTimestamp ISO8601 timestamp of operation

iothub-message-schema moduleLifecycleNotification

Body: This section is in JSON format and represents the twin of the created module identity. For example,
{
"deviceId":"11576-ailn-test-0-67333793211",
"moduleId":"tempSensor",
"etag":"AAAAAAAAAAE=",
"properties": {
"desired": {
"$metadata": {
"$lastUpdated": "2016-02-30T16:24:48.789Z"
},
"$version": 1
},
"reported": {
"$metadata": {
"$lastUpdated": "2016-02-30T16:24:48.789Z"
},
"$version": 1
}
}
}

Device identity properties


Device identities are represented as JSON documents with the following properties:

PROPERTY OPTIONS DESCRIPTION

deviceId required, read-only on updates A case-sensitive string (up to 128


characters long) of ASCII 7-bit
alphanumeric characters plus certain
special characters:
- . + % _ # * ? ! ( ) , = @ $ ' .

generationId required, read-only An IoT hub-generated, case-sensitive


string up to 128 characters long. This
value is used to distinguish devices with
the same deviceId, when they have
been deleted and re-created.

etag required, read-only A string representing a weak ETag for


the device identity, as per RFC7232.

auth optional A composite object containing


authentication information and security
materials.

auth.symkey optional A composite object containing a


primary and a secondary key, stored in
base64 format.

status required An access indicator. Can be Enabled or


Disabled. If Enabled, the device is
allowed to connect. If Disabled, this
device cannot access any device-facing
endpoint.

statusReason optional A 128 character-long string that stores


the reason for the device identity status.
All UTF-8 characters are allowed.
PROPERTY OPTIONS DESCRIPTION

statusUpdateTime read-only A temporal indicator, showing the date


and time of the last status update.

connectionState read-only A field indicating connection status:


either Connected or Disconnected.
This field represents the IoT Hub view of
the device connection status.
Important: This field should be used
only for development/debugging
purposes. The connection state is
updated only for devices using MQTT or
AMQP. Also, it is based on protocol-level
pings (MQTT pings, or AMQP pings),
and it can have a maximum delay of
only 5 minutes. For these reasons, there
can be false positives, such as devices
reported as connected but that are
disconnected.

connectionStateUpdatedTime read-only A temporal indicator, showing the date


and last time the connection state was
updated.

lastActivityTime read-only A temporal indicator, showing the date


and last time the device connected,
received, or sent a message.

NOTE
Connection state can only represent the IoT Hub view of the status of the connection. Updates to this state may be delayed,
depending on network conditions and configurations.

Module identity properties


Module identities are represented as JSON documents with the following properties:

PROPERTY OPTIONS DESCRIPTION

deviceId required, read-only on updates A case-sensitive string (up to 128


characters long) of ASCII 7-bit
alphanumeric characters plus certain
special characters:
- . + % _ # * ? ! ( ) , = @ $ ' .

moduleId required, read-only on updates A case-sensitive string (up to 128


characters long) of ASCII 7-bit
alphanumeric characters plus certain
special characters:
- . + % _ # * ? ! ( ) , = @ $ ' .

generationId required, read-only An IoT hub-generated, case-sensitive


string up to 128 characters long. This
value is used to distinguish devices with
the same deviceId, when they have
been deleted and re-created.
PROPERTY OPTIONS DESCRIPTION

etag required, read-only A string representing a weak ETag for


the device identity, as per RFC7232.

auth optional A composite object containing


authentication information and security
materials.

auth.symkey optional A composite object containing a


primary and a secondary key, stored in
base64 format.

status required An access indicator. Can be Enabled or


Disabled. If Enabled, the device is
allowed to connect. If Disabled, this
device cannot access any device-facing
endpoint.

statusReason optional A 128 character-long string that stores


the reason for the device identity status.
All UTF-8 characters are allowed.

statusUpdateTime read-only A temporal indicator, showing the date


and time of the last status update.

connectionState read-only A field indicating connection status:


either Connected or Disconnected.
This field represents the IoT Hub view of
the device connection status.
Important: This field should be used
only for development/debugging
purposes. The connection state is
updated only for devices using MQTT or
AMQP. Also, it is based on protocol-level
pings (MQTT pings, or AMQP pings),
and it can have a maximum delay of
only 5 minutes. For these reasons, there
can be false positives, such as devices
reported as connected but that are
disconnected.

connectionStateUpdatedTime read-only A temporal indicator, showing the date


and last time the connection state was
updated.

lastActivityTime read-only A temporal indicator, showing the date


and last time the device connected,
received, or sent a message.

Additional reference material


Other reference topics in the IoT Hub developer guide include:
IoT Hub endpoints describes the various endpoints that each IoT hub exposes for run-time and management
operations.
Throttling and quotas describes the quotas and throttling behaviors that apply to the IoT Hub service.
Azure IoT device and service SDKs lists the various language SDKs you can use when you develop both device
and service apps that interact with IoT Hub.
IoT Hub query language describes the query language you can use to retrieve information from IoT Hub about
your device twins and jobs.
IoT Hub MQTT support provides more information about IoT Hub support for the MQTT protocol.

Next steps
Now that you have learned how to use the IoT Hub identity registry, you may be interested in the following IoT
Hub developer guide topics:
Control access to IoT Hub
Use device twins to synchronize state and configurations
Invoke a direct method on a device
Schedule jobs on multiple devices
To try out some of the concepts described in this article, see the following IoT Hub tutorial:
Get started with Azure IoT Hub
To explore using the IoT Hub Device Provisioning Service to enable zero-touch, just-in-time provisioning, see:
Azure IoT Hub Device Provisioning Service
Control access to IoT Hub
6/6/2018 • 16 min to read • Edit Online

This article describes the options for securing your IoT hub. IoT Hub uses permissions to grant access to each IoT
hub endpoint. Permissions limit the access to an IoT hub based on functionality.
This article introduces:
The different permissions that you can grant to a device or back-end app to access your IoT hub.
The authentication process and the tokens it uses to verify permissions.
How to scope credentials to limit access to specific resources.
IoT Hub support for X.509 certificates.
Custom device authentication mechanisms that use existing device identity registries or authentication schemes.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are only
available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to choose
the right IoT Hub tier.

You must have appropriate permissions to access any of the IoT Hub endpoints. For example, a device must include
a token containing security credentials along with every message it sends to IoT Hub.

Access control and permissions


You can grant permissions in the following ways:
IoT hub-level shared access policies. Shared access policies can grant any combination of permissions.
You can define policies in the Azure portal, or programmatically by using the IoT Hub resource provider
REST APIs. A newly created IoT hub has the following default policies:
iothubowner: Policy with all permissions.
service: Policy with ServiceConnect permission.
device: Policy with DeviceConnect permission.
registryRead: Policy with RegistryRead permission.
registryReadWrite: Policy with RegistryRead and RegistryWrite permissions.
Per-device security credentials. Each IoT Hub contains an identity registry. For each device in this
identity registry, you can configure security credentials that grant DeviceConnect permissions scoped to
the corresponding device endpoints.
For example, in a typical IoT solution:
The device management component uses the registryReadWrite policy.
The event processor component uses the service policy.
The run-time device business logic component uses the service policy.
Individual devices connect using credentials stored in the IoT hub's identity registry.
NOTE
See permissions for detailed information.

Authentication
Azure IoT Hub grants access to endpoints by verifying a token against the shared access policies and identity
registry security credentials.
Security credentials, such as symmetric keys, are never sent over the wire.

NOTE
The Azure IoT Hub resource provider is secured through your Azure subscription, as are all providers in the Azure Resource
Manager.

For more information about how to construct and use security tokens, see IoT Hub security tokens.
Protocol specifics
Each supported protocol, such as MQTT, AMQP, and HTTPS, transports tokens in different ways.
When using MQTT, the CONNECT packet has the deviceId as the ClientId, {iothubhostname}/{deviceId} in the
Username field, and a SAS token in the Password field. {iothubhostname} should be the full CName of the IoT hub
(for example, contoso.azure-devices.net).
When using AMQP, IoT Hub supports SASL PL AIN and AMQP Claims-Based-Security.
If you use AMQP claims-based-security, the standard specifies how to transmit these tokens.
For SASL PL AIN, the username can be:
{policyName}@sas.root.{iothubName} if using IoT hub-level tokens.
{deviceId}@sas.{iothubname} if using device-scoped tokens.

In both cases, the password field contains the token, as described in IoT Hub security tokens.
HTTPS implements authentication by including a valid token in the Authorization request header.
Example
Username (DeviceId is case-sensitive): iothubname.azure-devices.net/DeviceId

Password (Generate SAS token with the device explorer tool):


SharedAccessSignature sr=iothubname.azure-
devices.net%2fdevices%2fDeviceId&sig=kPszxZZZZZZZZZZZZZZZZZAhLT%2bV7o%3d&se=1487709501

NOTE
The Azure IoT SDKs automatically generate tokens when connecting to the service. In some cases, the Azure IoT SDKs do not
support all the protocols or all the authentication methods.

Special considerations for SASL PLAIN


When using SASL PL AIN with AMQP, a client connecting to an IoT hub can use a single token for each TCP
connection. When the token expires, the TCP connection disconnects from the service and triggers a reconnection.
This behavior, while not problematic for a back-end app, is damaging for a device app for the following reasons:
Gateways usually connect on behalf of many devices. When using SASL PL AIN, they have to create a distinct
TCP connection for each device connecting to an IoT hub. This scenario considerably increases the consumption
of power and networking resources, and increases the latency of each device connection.
Resource-constrained devices are adversely affected by the increased use of resources to reconnect after each
token expiration.

Scope IoT hub-level credentials


You can scope IoT hub-level security policies by creating tokens with a restricted resource URI. For example, the
endpoint to send device-to-cloud messages from a device is /devices/{deviceId}/messages/events. You can also
use an IoT hub-level shared access policy with DeviceConnect permissions to sign a token whose resourceURI is
/devices/{deviceId}. This approach creates a token that is only usable to send messages on behalf of device
deviceId.
This mechanism is similar to the Event Hubs publisher policy, and enables you to implement custom authentication
methods.

Security tokens
IoT Hub uses security tokens to authenticate devices and services to avoid sending keys on the wire. Additionally,
security tokens are limited in time validity and scope. Azure IoT SDKs automatically generate tokens without
requiring any special configuration. Some scenarios do require you to generate and use security tokens directly.
Such scenarios include:
The direct use of the MQTT, AMQP, or HTTPS surfaces.
The implementation of the token service pattern, as explained in Custom device authentication.
IoT Hub also allows devices to authenticate with IoT Hub using X.509 certificates.
Security token structure
You use security tokens to grant time-bounded access to devices and services to specific functionality in IoT Hub. To
get authorization to connect to IoT Hub, devices and services must send security tokens signed with either a shared
access or symmetric key. These keys are stored with a device identity in the identity registry.
A token signed with a shared access key grants access to all the functionality associated with the shared access
policy permissions. A token signed with a device identity's symmetric key only grants the DeviceConnect
permission for the associated device identity.
The security token has the following format:
SharedAccessSignature sig={signature-string}&se={expiry}&skn={policyName}&sr={URL-encoded-resourceURI}

Here are the expected values:

VALUE DESCRIPTION

{signature} An HMAC-SHA256 signature string of the form:


{URL-encoded-resourceURI} + "\n" + expiry . Important:
The key is decoded from base64 and used as key to perform
the HMAC-SHA256 computation.

{resourceURI} URI prefix (by segment) of the endpoints that can be accessed
with this token, starting with host name of the IoT hub (no
protocol). For example,
myHub.azure-devices.net/devices/device1
VALUE DESCRIPTION

{expiry} UTF8 strings for number of seconds since the epoch 00:00:00
UTC on 1 January 1970.

{URL-encoded-resourceURI} Lower case URL-encoding of the lower case resource URI

{policyName} The name of the shared access policy to which this token
refers. Absent if the token refers to device-registry credentials.

Note on prefix: The URI prefix is computed by segment and not by character. For example /a/b is a prefix for
/a/b/c but not for /a/bc .

The following Node.js snippet shows a function called generateSasToken that computes the token from the inputs
resourceUri, signingKey, policyName, expiresInMins . The next sections detail how to initialize the different inputs
for the different token use cases.

var generateSasToken = function(resourceUri, signingKey, policyName, expiresInMins) {


resourceUri = encodeURIComponent(resourceUri);

// Set expiration in seconds


var expires = (Date.now() / 1000) + expiresInMins * 60;
expires = Math.ceil(expires);
var toSign = resourceUri + '\n' + expires;

// Use crypto
var hmac = crypto.createHmac('sha256', new Buffer(signingKey, 'base64'));
hmac.update(toSign);
var base64UriEncoded = encodeURIComponent(hmac.digest('base64'));

// Construct autorization string


var token = "SharedAccessSignature sr=" + resourceUri + "&sig="
+ base64UriEncoded + "&se=" + expires;
if (policyName) token += "&skn="+policyName;
return token;
};

As a comparison, the equivalent Python code to generate a security token is:


from base64 import b64encode, b64decode
from hashlib import sha256
from time import time
from urllib import quote_plus, urlencode
from hmac import HMAC

def generate_sas_token(uri, key, policy_name, expiry=3600):


ttl = time() + expiry
sign_key = "%s\n%d" % ((quote_plus(uri)), int(ttl))
print sign_key
signature = b64encode(HMAC(b64decode(key), sign_key, sha256).digest())

rawtoken = {
'sr' : uri,
'sig': signature,
'se' : str(int(ttl))
}

if policy_name is not None:


rawtoken['skn'] = policy_name

return 'SharedAccessSignature ' + urlencode(rawtoken)

The functionality in C# to generate a security token is:

using System;
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;

public static string generateSasToken(string resourceUri, string key, string policyName, int expiryInSeconds =
3600)
{
TimeSpan fromEpochStart = DateTime.UtcNow - new DateTime(1970, 1, 1);
string expiry = Convert.ToString((int)fromEpochStart.TotalSeconds + expiryInSeconds);

string stringToSign = WebUtility.UrlEncode(resourceUri) + "\n" + expiry;

HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(key));


string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));

string token = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}",


WebUtility.UrlEncode(resourceUri), WebUtility.UrlEncode(signature), expiry);

if (!String.IsNullOrEmpty(policyName))
{
token += "&skn=" + policyName;
}

return token;
}

NOTE
Since the time validity of the token is validated on IoT Hub machines, the drift on the clock of the machine that generates the
token must be minimal.

Use SAS tokens in a device app


There are two ways to obtain DeviceConnect permissions with IoT Hub with security tokens: use a symmetric
device key from the identity registry, or use a shared access key.
Remember that all functionality accessible from devices is exposed by design on endpoints with prefix
/devices/{deviceId} .

IMPORTANT
The only way that IoT Hub authenticates a specific device is using the device identity symmetric key. In cases when a shared
access policy is used to access device functionality, the solution must consider the component issuing the security token as a
trusted subcomponent.

The device-facing endpoints are (irrespective of the protocol):

ENDPOINT FUNCTIONALITY

{iot hub host Send device-to-cloud messages.


name}/devices/{deviceId}/messages/events

{iot hub host Receive cloud-to-device messages.


name}/devices/{deviceId}/messages/devicebound

Use a symmetric key in the identity registry


When using a device identity's symmetric key to generate a token, the policyName ( skn ) element of the token is
omitted.
For example, a token created to access all device functionality should have the following parameters:
resource URI: {IoT hub name}.azure-devices.net/devices/{device id} ,
signing key: any symmetric key for the {device id} identity,
no policy name,
any expiration time.
An example using the preceding Node.js function would be:

var endpoint ="myhub.azure-devices.net/devices/device1";


var deviceKey ="...";

var token = generateSasToken(endpoint, deviceKey, null, 60);

The result, which grants access to all functionality for device1, would be:
SharedAccessSignature sr=myhub.azure-
devices.net%2fdevices%2fdevice1&sig=13y8ejUk2z7PLmvtwR5RqlGBOVwiq7rQR3WZ5xZX3N4%3D&se=1456971697

NOTE
It is possible to generate a SAS token using the .NET device explorer tool or the cross-platform, Python-based The IoT
extension for Azure CLI 2.0 command-line utility.

Use a shared access policy


When you create a token from a shared access policy, set the skn field to the name of the policy. This policy must
grant the DeviceConnect permission.
The two main scenarios for using shared access policies to access device functionality are:
cloud protocol gateways,
token services used to implement custom authentication schemes.
Since the shared access policy can potentially grant access to connect as any device, it is important to use the
correct resource URI when creating security tokens. This setting is especially important for token services, which
have to scope the token to a specific device using the resource URI. This point is less relevant for protocol gateways
as they are already mediating traffic for all devices.
As an example, a token service using the pre-created shared access policy called device would create a token with
the following parameters:
resource URI: {IoT hub name}.azure-devices.net/devices/{device id} ,
signing key: one of the keys of the device policy,
policy name: device ,
any expiration time.
An example using the preceding Node.js function would be:

var endpoint ="myhub.azure-devices.net/devices/device1";


var policyName = 'device';
var policyKey = '...';

var token = generateSasToken(endpoint, policyKey, policyName, 60);

The result, which grants access to all functionality for device1, would be:
SharedAccessSignature sr=myhub.azure-
devices.net%2fdevices%2fdevice1&sig=13y8ejUk2z7PLmvtwR5RqlGBOVwiq7rQR3WZ5xZX3N4%3D&se=1456971697&skn=device

A protocol gateway could use the same token for all devices simply setting the resource URI to
myhub.azure-devices.net/devices .

Use security tokens from service components


Service components can only generate security tokens using shared access policies granting the appropriate
permissions as explained previously.
Here is the service functions exposed on the endpoints:

ENDPOINT FUNCTIONALITY

{iot hub host name}/devices Create, update, retrieve, and delete device identities.

{iot hub host name}/messages/events Receive device-to-cloud messages.

{iot hub host name}/servicebound/feedback Receive feedback for cloud-to-device messages.

{iot hub host name}/devicebound Send cloud-to-device messages.

As an example, a service generating using the pre-created shared access policy called registryRead would create a
token with the following parameters:
resource URI: {IoT hub name}.azure-devices.net/devices ,
signing key: one of the keys of the registryRead policy,
policy name: registryRead ,
any expiration time.
var endpoint ="myhub.azure-devices.net/devices";
var policyName = 'device';
var policyKey = '...';

var token = generateSasToken(endpoint, policyKey, policyName, 60);

The result, which would grant access to read all device identities, would be:
SharedAccessSignature sr=myhub.azure-
devices.net%2fdevices&sig=JdyscqTpXdEJs49elIUCcohw2DlFDR3zfH5KqGJo4r4%3D&se=1456973447&skn=registryRead

Supported X.509 certificates


You can use any X.509 certificate to authenticate a device with IoT Hub by uploading either a certificate thumbprint
or a certificate authority (CA) to Azure IoT Hub. Authentication using certificate thumbprints only verifies that the
presented thumbprint matches the configured thumbprint. Authentication using certificate authority validates the
certificate chain.
Supported certificates include:
An existing X.509 certificate. A device may already have an X.509 certificate associated with it. The device can
use this certificate to authenticate with IoT Hub. Works with either thumbprint or CA authentication.
CA -signed X.509 certificate. To identify a device and authenticate it with IoT Hub, you can use an X.509
certificate generated and signed by a Certification Authority (CA). Works with either thumbprint or CA
authentication.
A self-generated and self-signed X-509 certificate. A device manufacturer or in-house deployer can
generate these certificates and store the corresponding private key (and certificate) on the device. You can use
tools such as OpenSSL and Windows SelfSignedCertificate utility for this purpose. Only works with thumbprint
authentication.
A device may either use an X.509 certificate or a security token for authentication, but not both.
For more information about authentication using certificate authority, see Conceptual understanding of X.509 CA
certificates.
Register an X.509 certificate for a device
The Azure IoT Service SDK for C# (version 1.0.8+) supports registering a device that uses an X.509 certificate for
authentication. Other APIs such as import/export of devices also support X.509 certificates.
C# Support
The RegistryManager class provides a programmatic way to register a device. In particular, the AddDeviceAsync
and UpdateDeviceAsync methods enable you to register and update a device in the IoT Hub identity registry.
These two methods take a Device instance as input. The Device class includes an Authentication property that
allows you to specify primary and secondary X.509 certificate thumbprints. The thumbprint represents a SHA256
hash of the X.509 certificate (stored using binary DER encoding). You have the option of specifying a primary
thumbprint or a secondary thumbprint or both. Primary and secondary thumbprints are supported to handle
certificate rollover scenarios.
Here is a sample C# code snippet to register a device using an X.509 certificate thumbprint:
var device = new Device(deviceId)
{
Authentication = new AuthenticationMechanism()
{
X509Thumbprint = new X509Thumbprint()
{
PrimaryThumbprint = "B4172AB44C28F3B9E117648C6F7294978A00CDCBA34A46A1B8588B3F7D82C4F1"
}
}
};
RegistryManager registryManager = RegistryManager.CreateFromConnectionString(deviceGatewayConnectionString);
await registryManager.AddDeviceAsync(device);

Use an X.509 certificate during run-time operations


The Azure IoT device SDK for .NET (version 1.0.11+) supports the use of X.509 certificates.
C# Support
The class DeviceAuthenticationWithX509Certificate supports the creation of DeviceClient instances using an
X.509 certificate. The X.509 certificate must be in the PFX (also called PKCS #12) format that includes the private
key.
Here is a sample code snippet:

var authMethod = new DeviceAuthenticationWithX509Certificate("<device id>", x509Certificate);

var deviceClient = DeviceClient.Create("<IotHub DNS HostName>", authMethod);

Custom device and module authentication


You can use the IoT Hub identity registry to configure per-device/module security credentials and access control
using tokens. If an IoT solution already has a custom identity registry and/or authentication scheme, consider
creating a token service to integrate this infrastructure with IoT Hub. In this way, you can use other IoT features in
your solution.
A token service is a custom cloud service. It uses an IoT Hub shared access policy with DeviceConnect or
ModuleConnect permissions to create device-scoped or module-scoped tokens. These tokens enable a device and
module to connect to your IoT hub.
Here are the main steps of the token service pattern:
1. Create an IoT Hub shared access policy with DeviceConnect or ModuleConnect permissions for your IoT
hub. You can create this policy in the Azure portal or programmatically. The token service uses this policy to sign
the tokens it creates.
2. When a device/module needs to access your IoT hub, it requests a signed token from your token service. The
device can authenticate with your custom identity registry/authentication scheme to determine the
device/module identity that the token service uses to create the token.
3. The token service returns a token. The token is created by using /devices/{deviceId} or
/devices/{deviceId}/module/{moduleId} as resourceURI , with deviceId as the device being authenticated or
moduleId as the module being authenticated. The token service uses the shared access policy to construct the
token.
4. The device/module uses the token directly with the IoT hub.

NOTE
You can use the .NET class SharedAccessSignatureBuilder or the Java class IotHubServiceSasToken to create a token in your
token service.

The token service can set the token expiration as desired. When the token expires, the IoT hub severs the
device/module connection. Then, the device/module must request a new token from the token service. A short
expiry time increases the load on both the device/module and the token service.
For a device/module to connect to your hub, you must still add it to the IoT Hub identity registry — even though
the it is using a token and not a key to connect. Therefore, you can continue to use per-device/per-module access
control by enabling or disabling device/module identities in the identity registry. This approach mitigates the risks
of using tokens with long expiry times.
Comparison with a custom gateway
The token service pattern is the recommended way to implement a custom identity registry/authentication scheme
with IoT Hub. This pattern is recommended because IoT Hub continues to handle most of the solution traffic.
However, if the custom authentication scheme is so intertwined with the protocol, you may require a custom
gateway to process all the traffic. An example of such a scenario is usingTransport Layer Security (TLS ) and pre-
shared keys (PSKs). For more information, see the protocol gateway article.

Reference topics:
The following reference topics provide you with more information about controlling access to your IoT hub.

IoT Hub permissions


The following table lists the permissions you can use to control access to your IoT hub.

PERMISSION NOTES

RegistryRead Grants read access to the identity registry. For more


information, see Identity registry.
This permission is used by back-end cloud services.

RegistryReadWrite Grants read and write access to the identity registry. For more
information, see Identity registry.
This permission is used by back-end cloud services.

ServiceConnect Grants access to cloud service-facing communication and


monitoring endpoints.
Grants permission to receive device-to-cloud messages, send
cloud-to-device messages, and retrieve the corresponding
delivery acknowledgments.
Grants permission to retrieve delivery acknowledgements for
file uploads.
Grants permission to access twins to update tags and desired
properties, retrieve reported properties, and run queries.
This permission is used by back-end cloud services.

DeviceConnect Grants access to device-facing endpoints.


Grants permission to send device-to-cloud messages and
receive cloud-to-device messages.
Grants permission to perform file upload from a device.
Grants permission to receive device twin desired property
notifications and update device twin reported properties.
Grants permission to perform file uploads.
This permission is used by devices.

Additional reference material


Other reference topics in the IoT Hub developer guide include:
IoT Hub endpoints describes the various endpoints that each IoT hub exposes for run-time and management
operations.
Throttling and quotas describes the quotas and throttling behaviors that apply to the IoT Hub service.
Azure IoT device and service SDKs lists the various language SDKs you can use when you develop both device
and service apps that interact with IoT Hub.
IoT Hub query language describes the query language you can use to retrieve information from IoT Hub about
your device twins and jobs.
IoT Hub MQTT support provides more information about IoT Hub support for the MQTT protocol.

Next steps
Now that you have learned how to control access IoT Hub, you may be interested in the following IoT Hub
developer guide topics:
Use device twins to synchronize state and configurations
Invoke a direct method on a device
Schedule jobs on multiple devices
If you would like to try out some of the concepts described in this article, see the following IoT Hub tutorials:
Get started with Azure IoT Hub
How to send cloud-to-device messages with IoT Hub
How to process IoT Hub device-to-cloud messages
Understand and use device twins in IoT Hub
5/29/2018 • 11 min to read • Edit Online

Device twins are JSON documents that store device state information including metadata, configurations, and
conditions. Azure IoT Hub maintains a device twin for each device that you connect to IoT Hub.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This article describes:


The structure of the device twin: tags, desired and reported properties.
The operations that device apps and back ends can perform on device twins.
Use device twins to:
Store device-specific metadata in the cloud. For example, the deployment location of a vending machine.
Report current state information such as available capabilities and conditions from your device app. For
example, a device is connected to your IoT hub over cellular or WiFi.
Synchronize the state of long-running workflows between device app and back-end app. For example, when the
solution back end specifies the new firmware version to install, and the device app reports the various stages of
the update process.
Query your device metadata, configuration, or state.
Refer to Device-to-cloud communication guidance for guidance on using reported properties, device-to-cloud
messages, or file upload. Refer to Cloud-to-device communication guidance for guidance on using desired
properties, direct methods, or cloud-to-device messages.

Device twins
Device twins store device-related information that:
Device and back ends can use to synchronize device conditions and configuration.
The solution back end can use to query and target long-running operations.
The lifecycle of a device twin is linked to the corresponding device identity. Device twins are implicitly created and
deleted when a device identity is created or deleted in IoT Hub.
A device twin is a JSON document that includes:
Tags. A section of the JSON document that the solution back end can read from and write to. Tags are not
visible to device apps.
Desired properties. Used along with reported properties to synchronize device configuration or conditions.
The solution back end can set desired properties, and the device app can read them. The device app can also
receive notifications of changes in the desired properties.
Reported properties. Used along with desired properties to synchronize device configuration or conditions.
The device app can set reported properties, and the solution back end can read and query them.
Device identity properties. The root of the device twin JSON document contains the read-only properties
from the corresponding device identity stored in the identity registry.
The following example shows a device twin JSON document:

{
"deviceId": "devA",
"etag": "AAAAAAAAAAc=",
"status": "enabled",
"statusReason": "provisioned",
"statusUpdateTime": "0001-01-01T00:00:00",
"connectionState": "connected",
"lastActivityTime": "2015-02-30T16:24:48.789Z",
"cloudToDeviceMessageCount": 0,
"authenticationType": "sas",
"x509Thumbprint": {
"primaryThumbprint": null,
"secondaryThumbprint": null
},
"version": 2,
"tags": {
"$etag": "123",
"deploymentLocation": {
"building": "43",
"floor": "1"
}
},
"properties": {
"desired": {
"telemetryConfig": {
"sendFrequency": "5m"
},
"$metadata" : {...},
"$version": 1
},
"reported": {
"telemetryConfig": {
"sendFrequency": "5m",
"status": "success"
}
"batteryLevel": 55,
"$metadata" : {...},
"$version": 4
}
}
}
In the root object are the device identity properties, and container objects for tags and both reported and
desired properties. The properties container contains some read-only elements ( $metadata , $etag , and
$version ) described in the Device twin metadata and Optimistic concurrency sections.

Reported property example


In the previous example, the device twin contains a batteryLevel property that is reported by the device app. This
property makes it possible to query and operate on devices based on the last reported battery level. Other
examples include the device app reporting device capabilities or connectivity options.

NOTE
Reported properties simplify scenarios where the solution back end is interested in the last known value of a property. Use
device-to-cloud messages if the solution back end needs to process device telemetry in the form of sequences of
timestamped events, such as time series.

Desired property example


In the previous example, the telemetryConfig device twin desired and reported properties are used by the solution
back end and the device app to synchronize the telemetry configuration for this device. For example:
1. The solution back end sets the desired property with the desired configuration value. Here is the portion of
the document with the desired property set:

...
"desired": {
"telemetryConfig": {
"sendFrequency": "5m"
},
...
},
...

2. The device app is notified of the change immediately if connected, or at the first reconnect. The device app
then reports the updated configuration (or an error condition using the status property). Here is the
portion of the reported properties:

...
"reported": {
"telemetryConfig": {
"sendFrequency": "5m",
"status": "success"
}
...
}
...

3. The solution back end can track the results of the configuration operation across many devices, by querying
device twins.

NOTE
The preceding snippets are examples, optimized for readability, of one way to encode a device configuration and its status. IoT
Hub does not impose a specific schema for the device twin desired and reported properties in the device twins.

You can use twins to synchronize long-running operations such as firmware updates. For more information on how
to use properties to synchronize and track a long running operation across devices, see Use desired properties to
configure devices.

Back-end operations
The solution back end operates on the device twin using the following atomic operations, exposed through HTTPS:
Retrieve device twin by ID. This operation returns the device twin document, including tags and desired and
reported system properties.
Partially update device twin. This operation enables the solution back end to partially update the tags or
desired properties in a device twin. The partial update is expressed as a JSON document that adds or
updates any property. Properties set to null are removed. The following example creates a new desired
property with value {"newProperty": "newValue"} , overwrites the existing value of existingProperty with
"otherNewValue" , and removes otherOldProperty . No other changes are made to existing desired properties
or tags:

{
"properties": {
"desired": {
"newProperty": {
"nestedProperty": "newValue"
},
"existingProperty": "otherNewValue",
"otherOldProperty": null
}
}
}

Replace desired properties. This operation enables the solution back end to completely overwrite all
existing desired properties and substitute a new JSON document for properties/desired .
Replace tags. This operation enables the solution back end to completely overwrite all existing tags and
substitute a new JSON document for tags .
Receive twin notifications. This operation allows the solution back end to be notified when the twin is
modified. To do so, your IoT solution needs to create a route and to set the Data Source equal to
twinChangeEvents. By default, no twin notifications are sent, that is, no such routes pre-exist. If the rate of
change is too high, or for other reasons such as internal failures, the IoT Hub might send only one
notification that contains all changes. Therefore, if your application needs reliable auditing and logging of all
intermediate states, you should use device-to-cloud messages. The twin notification message includes
properties and body.
Properties

NAME VALUE

$content-type application/json

$iothub-enqueuedtime Time when the notification was sent

$iothub-message-source twinChangeEvents

$content-encoding utf-8

deviceId ID of the device

hubName Name of IoT Hub


NAME VALUE

operationTimestamp ISO8601 timestamp of operation

iothub-message-schema deviceLifecycleNotification

opType "replaceTwin" or "updateTwin"

Message system properties are prefixed with the '$' symbol.


Body
This section includes all the twin changes in a JSON format. It uses the same format as a patch, with
the difference that it can contain all twin sections: tags, properties.reported, properties.desired, and
that it contains the “$metadata” elements. For example,

{
"properties": {
"desired": {
"$metadata": {
"$lastUpdated": "2016-02-30T16:24:48.789Z"
},
"$version": 1
},
"reported": {
"$metadata": {
"$lastUpdated": "2016-02-30T16:24:48.789Z"
},
"$version": 1
}
}
}

All the preceding operations support Optimistic concurrency and require the ServiceConnect permission, as
defined in the Security article.
In addition to these operations, the solution back end can:
Query the device twins using the SQL -like IoT Hub query language.
Perform operations on large sets of device twins using jobs.

Device operations
The device app operates on the device twin using the following atomic operations:
Retrieve device twin. This operation returns the device twin document (including tags and desired and
reported system properties) for the currently connected device.
Partially update reported properties. This operation enables the partial update of the reported properties of
the currently connected device. This operation uses the same JSON update format that the solution back end
uses for a partial update of desired properties.
Observe desired properties. The currently connected device can choose to be notified of updates to the
desired properties when they happen. The device receives the same form of update (partial or full replacement)
executed by the solution back end.
All the preceding operations require the DeviceConnect permission, as defined in the Security article.
The Azure IoT device SDKs make it easy to use the preceding operations from many languages and platforms. For
more information on the details of IoT Hub primitives for desired properties synchronization, see Device
reconnection flow.

Tags and properties format


Tags, desired properties, and reported properties are JSON objects with the following restrictions:
All keys in JSON objects are case-sensitive 64 bytes UTF -8 UNICODE strings. Allowed characters exclude
UNICODE control characters (segments C0 and C1), and '.' , ' ' , and '$' .
All values in JSON objects can be of the following JSON types: boolean, number, string, object. Arrays are not
allowed. The maximum value for integers is 4503599627370495 and the minimum value for integers is -
4503599627370496.
All JSON objects in tags, desired, and reported properties can have a maximum depth of 5. For instance, the
following object is valid:

{
...
"tags": {
"one": {
"two": {
"three": {
"four": {
"five": {
"property": "value"
}
}
}
}
}
},
...
}

All string values can be at most 4 KB in length.

Device twin size


IoT Hub enforces an 8KB size limitation on each of the respective total values of tags , properties/desired , and
properties/reported , excluding read-only elements. The size is computed by counting all characters, excluding
UNICODE control characters (segments C0 and C1) and spaces that are outside of string constants. IoT Hub rejects
with an error all operations that would increase the size of those documents above the limit.

Device twin metadata


IoT Hub maintains the timestamp of the last update for each JSON object in device twin desired and reported
properties. The timestamps are in UTC and encoded in the ISO8601 format YYYY-MM-DDTHH:MM:SS.mmmZ . For
example:
{
...
"properties": {
"desired": {
"telemetryConfig": {
"sendFrequency": "5m"
},
"$metadata": {
"telemetryConfig": {
"sendFrequency": {
"$lastUpdated": "2016-03-30T16:24:48.789Z"
},
"$lastUpdated": "2016-03-30T16:24:48.789Z"
},
"$lastUpdated": "2016-03-30T16:24:48.789Z"
},
"$version": 23
},
"reported": {
"telemetryConfig": {
"sendFrequency": "5m",
"status": "success"
}
"batteryLevel": "55%",
"$metadata": {
"telemetryConfig": {
"sendFrequency": "5m",
"status": {
"$lastUpdated": "2016-03-31T16:35:48.789Z"
},
"$lastUpdated": "2016-03-31T16:35:48.789Z"
}
"batteryLevel": {
"$lastUpdated": "2016-04-01T16:35:48.789Z"
},
"$lastUpdated": "2016-04-01T16:24:48.789Z"
},
"$version": 123
}
}
...
}

This information is kept at every level (not just the leaves of the JSON structure) to preserve updates that remove
object keys.

Optimistic concurrency
Tags, desired, and reported properties all support optimistic concurrency. Tags have an ETag, as per RFC7232, that
represents the tag's JSON representation. You can use ETags in conditional update operations from the solution
back end to ensure consistency.
Device twin desired and reported properties do not have ETags, but have a $version value that is guaranteed to be
incremental. Similarly to an ETag, the version can be used by the updating party to enforce consistency of updates.
For example, a device app for a reported property or the solution back end for a desired property.
Versions are also useful when an observing agent (such as the device app observing the desired properties) must
reconcile races between the result of a retrieve operation and an update notification. The section Device
reconnection flow provides more information.

Device reconnection flow


IoT Hub does not preserve desired properties update notifications for disconnected devices. It follows that a device
that is connecting must retrieve the full desired properties document, in addition to subscribing for update
notifications. Given the possibility of races between update notifications and full retrieval, the following flow must
be ensured:
1. Device app connects to an IoT hub.
2. Device app subscribes for desired properties update notifications.
3. Device app retrieves the full document for desired properties.
The device app can ignore all notifications with $version less or equal than the version of the full retrieved
document. This approach is possible because IoT Hub guarantees that versions always increment.

NOTE
This logic is already implemented in the Azure IoT device SDKs. This description is useful only if the device app cannot use any
of Azure IoT device SDKs and must program the MQTT interface directly.

Additional reference material


Other reference topics in the IoT Hub developer guide include:
The IoT Hub endpoints article describes the various endpoints that each IoT hub exposes for run-time and
management operations.
The Throttling and quotas article describes the quotas that apply to the IoT Hub service and the throttling
behavior to expect when you use the service.
The Azure IoT device and service SDKs article lists the various language SDKs you can use when you develop
both device and service apps that interact with IoT Hub.
The IoT Hub query language for device twins, jobs, and message routing article describes the IoT Hub query
language you can use to retrieve information from IoT Hub about your device twins and jobs.
The IoT Hub MQTT support article provides more information about IoT Hub support for the MQTT protocol.

Next steps
Now you have learned about device twins, you may be interested in the following IoT Hub developer guide topics:
Understand and use module twins in IoT Hub
Invoke a direct method on a device
Schedule jobs on multiple devices
To try out some of the concepts described in this article, see the following IoT Hub tutorials:
How to use the device twin
How to use device twin properties
Understand and invoke direct methods from IoT Hub
6/4/2018 • 5 min to read • Edit Online

IoT Hub gives you the ability to invoke direct methods on devices from the cloud. Direct methods represent a
request-reply interaction with a device similar to an HTTP call in that they succeed or fail immediately (after a user-
specified timeout). This approach is useful for scenarios where the course of immediate action is different
depending on whether the device was able to respond.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Each device method targets a single device. Jobs provide a way to invoke direct methods on multiple devices, and
schedule method invocation for disconnected devices.
Anyone with service connect permissions on IoT Hub may invoke a method on a device.
Direct methods follow a request-response pattern and are meant for communications that require immediate
confirmation of their result. For example, interactive control of the device, such as turning on a fan.
Refer to Cloud-to-device communication guidance if in doubt between using desired properties, direct methods, or
cloud-to-device messages.

Method lifecycle
Direct methods are implemented on the device and may require zero or more inputs in the method payload to
correctly instantiate. You invoke a direct method through a service-facing URI (
{iot hub}/twins/{device id}/methods/ ). A device receives direct methods through a device-specific MQTT topic (
$iothub/methods/POST/{method name}/ ) or through AMQP links ( IoThub-methodname and IoThub-status application
properties).

NOTE
When you invoke a direct method on a device, property names and values can only contain US-ASCII printable alphanumeric,
except any in the following set:
{'$', '(', ')', '<', '>', '@', ',', ';', ':', '\', '"', '/', '[', ']', '?', '=', '{', '}', SP, HT} .

Direct methods are synchronous and either succeed or fail after the timeout period (default: 30 seconds, settable up
to 3600 seconds). Direct methods are useful in interactive scenarios where you want a device to act if and only if
the device is online and receiving commands. For example, turning on a light from a phone. In these scenarios, you
want to see an immediate success or failure so the cloud service can act on the result as soon as possible. The
device may return some message body as a result of the method, but it isn't required for the method to do so.
There is no guarantee on ordering or any concurrency semantics on method calls.
Direct methods are HTTPS -only from the cloud side, and MQTT or AMQP from the device side.
The payload for method requests and responses is a JSON document up to 128 KB.

Invoke a direct method from a back-end app


Method invocation
Direct method invocations on a device are HTTPS calls that comprise:
The URI specific to the device ( {iot hub}/twins/{device id}/methods/ )
The POST method
Headers that contain the authorization, request ID, content type, and content encoding
A transparent JSON body in the following format:

{
"methodName": "reboot",
"responseTimeoutInSeconds": 200,
"payload": {
"input1": "someInput",
"input2": "anotherInput"
}
}

Timeout is in seconds. If timeout is not set, it defaults to 30 seconds.


Response
The back-end app receives a response that comprises:
HTTP status code, which is used for errors coming from the IoT Hub, including a 404 error for devices not
currently connected
Headers that contain the ETag, request ID, content type, and content encoding
A JSON body in the following format:

{
"status" : 201,
"payload" : {...}
}

Both status and body are provided by the device and used to respond with the device's own status code
and/or description.
Method invocation for IoT Edge modules
Invoking direct methods using a module ID is supported in the C# preview SDK (available here).
For this purpose, use the ServiceClient.InvokeDeviceMethodAsync() method and pass in the deviceId and
moduleId as parameters.

Handle a direct method on a device


MQTT
Method invocation
Devices receive direct method requests on the MQTT topic: $iothub/methods/POST/{method name}/?$rid={request id}

The body that the device receives is in the following format:

{
"input1": "someInput",
"input2": "anotherInput"
}

Method requests are QoS 0.


Response
The device sends responses to $iothub/methods/res/{status}/?$rid={request id} , where:
The status property is the device-supplied status of method execution.
The $rid property is the request ID from the method invocation received from IoT Hub.
The body is set by the device and can be any status.
AMQP
Method invocation
The device receives direct method requests by creating a receive link on address
amqps://{hostname}:5671/devices/{deviceId}/methods/deviceBound

The AMQP message arrives on the receive link that represents the method request. It contains the following:
The correlation ID property, which contains a request ID that should be passed back with the corresponding
method response
An application property named IoThub-methodname , which contains the name of the method being invoked
The AMQP message body containing the method payload as JSON
Response
The device creates a sending link to return the method response on address
amqps://{hostname}:5671/devices/{deviceId}/methods/deviceBound

The method’s response is returned on the sending link and is structured as follows:
The correlation ID property, which contains the request ID passed in the method’s request message
An application property named IoThub-status , which contains the user supplied method status
The AMQP message body containing the method response as JSON

Additional reference material


Other reference topics in the IoT Hub developer guide include:
IoT Hub endpoints describes the various endpoints that each IoT hub exposes for run-time and management
operations.
Throttling and quotas describes the quotas that apply and the throttling behavior to expect when you use IoT
Hub.
Azure IoT device and service SDKs lists the various language SDKs you can use when you develop both device
and service apps that interact with IoT Hub.
IoT Hub query language for device twins, jobs, and message routing describes the IoT Hub query language you
can use to retrieve information from IoT Hub about your device twins and jobs.
IoT Hub MQTT support provides more information about IoT Hub support for the MQTT protocol.

Next steps
Now you have learned how to use direct methods, you may be interested in the following IoT Hub developer guide
article:
Schedule jobs on multiple devices
If you would like to try out some of the concepts described in this article, you may be interested in the following IoT
Hub tutorial:
Use direct methods
Schedule jobs on multiple devices
5/29/2018 • 4 min to read • Edit Online

Azure IoT Hub enables a number of building blocks like device twin properties and tags and direct methods.
Typically, back-end apps enable device administrators and operators to update and interact with IoT devices in bulk
and at a scheduled time. Jobs execute device twin updates and direct methods against a set of devices at a
scheduled time. For example, an operator would use a back-end app that initiates and tracks a job to reboot a set of
devices in building 43 and floor 3 at a time that would not be disruptive to the operations of the building.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Consider using jobs when you need to schedule and track progress any of the following activities on a set of
devices:
Update desired properties
Update tags
Invoke direct methods

Job lifecycle
Jobs are initiated by the solution back end and maintained by IoT Hub. You can initiate a job through a service-
facing URI ( {iot hub}/jobs/v2/{device id}/methods/<jobID>?api-version=2016-11-14 ) and query for progress on an
executing job through a service-facing URI ( {iot hub}/jobs/v2/<jobId>?api-version=2016-11-14 ). To refresh the
status of running jobs once a job is initiated, run a job query.

NOTE
When you initiate a job, property names and values can only contain US-ASCII printable alphanumeric, except any in the
following set: $ ( ) < > @ , ; : \ " / [ ] ? = { } SP HT .

Jobs to execute direct methods


The following snippet shows the HTTPS 1.1 request details for executing a direct method on a set of devices using
a job:
PUT /jobs/v2/<jobId>?api-version=2016-11-14

Authorization: <config.sharedAccessSignature>
Content-Type: application/json; charset=utf-8
Request-Id: <guid>
User-Agent: <sdk-name>/<sdk-version>

{
jobId: '<jobId>',
type: 'scheduleDirectRequest',
cloudToDeviceMethod: {
methodName: '<methodName>',
payload: <payload>,
responseTimeoutInSeconds: methodTimeoutInSeconds
},
queryCondition: '<queryOrDevices>', // query condition
startTime: <jobStartTime>, // as an ISO-8601 date string
maxExecutionTimeInSeconds: <maxExecutionTimeInSeconds>
}

The query condition can also be on a single device ID or on a list of device IDs as shown in the following examples:

queryCondition = "deviceId = 'MyDevice1'"


queryCondition = "deviceId IN ['MyDevice1','MyDevice2']"
queryCondition = "deviceId IN ['MyDevice1']

IoT Hub Query Language covers IoT Hub query language in additional detail.

Jobs to update device twin properties


The following snippet shows the HTTPS 1.1 request details for updating device twin properties using a job:

PUT /jobs/v2/<jobId>?api-version=2016-11-14
Authorization: <config.sharedAccessSignature>
Content-Type: application/json; charset=utf-8
Request-Id: <guid>
User-Agent: <sdk-name>/<sdk-version>

{
jobId: '<jobId>',
type: 'scheduleTwinUpdate',
updateTwin: <patch> // Valid JSON object
queryCondition: '<queryOrDevices>', // query condition
startTime: <jobStartTime>, // as an ISO-8601 date string
maxExecutionTimeInSeconds: <maxExecutionTimeInSeconds> // format TBD
}

Querying for progress on jobs


The following snippet shows the HTTPS 1.1 request details for querying for jobs:

GET /jobs/v2/query?api-version=2016-11-14[&jobType=<jobType>][&jobStatus=<jobStatus>][&pageSize=<pageSize>]
[&continuationToken=<continuationToken>]

Authorization: <config.sharedAccessSignature>
Content-Type: application/json; charset=utf-8
Request-Id: <guid>
User-Agent: <sdk-name>/<sdk-version>
The continuationToken is provided from the response.

Jobs Properties
The following list shows the properties and corresponding descriptions, which can be used when querying for jobs
or job results.

PROPERTY DESCRIPTION

jobId Application provided ID for the job.

startTime Application provided start time (ISO-8601) for the job.

endTime IoT Hub provided date (ISO-8601) for when the job
completed. Valid only after the job reaches the 'completed'
state.

type Types of jobs:

scheduledUpdateTwin: A job used to update a set of desired


properties or tags.

scheduledDeviceMethod: A job used to invoke a device


method on a set of device twins.

status Current state of the job. Possible values for status:

pending: Scheduled and waiting to be picked up by the job


service.

scheduled: Scheduled for a time in the future.

running: Currently active job.

canceled: Job has been canceled.

failed: Job failed.

completed: Job has completed.

deviceJobStatistics Statistics about the job's execution.

deviceJobStatistics properties:

deviceJobStatistics.deviceCount: Number of devices in the


job.

deviceJobStatistics.failedCount: Number of devices where


the job failed.

deviceJobStatistics.succeededCount: Number of devices


where the job succeeded.
PROPERTY DESCRIPTION

deviceJobStatistics.runningCount: Number of devices that


are currently running the job.

deviceJobStatistics.pendingCount: Number of devices that


are pending to run the job.

Additional reference material


Other reference topics in the IoT Hub developer guide include:
IoT Hub endpoints describes the various endpoints that each IoT hub exposes for run-time and management
operations.
Throttling and quotas describes the quotas that apply to the IoT Hub service and the throttling behavior to
expect when you use the service.
Azure IoT device and service SDKs lists the various language SDKs you can use when you develop both device
and service apps that interact with IoT Hub.
IoT Hub query language for device twins, jobs, and message routing describes the IoT Hub query language. Use
this query language to retrieve information from IoT Hub about your device twins and jobs.
IoT Hub MQTT support provides more information about IoT Hub support for the MQTT protocol.

Next steps
To try out some of the concepts described in this article, see the following IoT Hub tutorial:
Schedule and broadcast jobs
Reference - IoT Hub endpoints
5/29/2018 • 5 min to read • Edit Online

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are only
available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to choose
the right IoT Hub tier.

IoT Hub names


You can find the name of the IoT hub that hosts your endpoints in the portal on the Overview blade. By default,
the DNS name of an IoT hub looks like: {your iot hub name}.azure-devices.net .
You can use Azure DNS to create a custom DNS name for your IoT hub. For more information, see Use Azure
DNS to provide custom domain settings for an Azure service.

List of built-in IoT Hub endpoints


Azure IoT Hub is a multi-tenant service that exposes its functionality to various actors. The following diagram
shows the various endpoints that IoT Hub exposes.

The following list describes the endpoints:


Resource provider. The IoT Hub resource provider exposes an Azure Resource Manager interface. This
interface enables Azure subscription owners to create and delete IoT hubs, and to update IoT hub properties.
IoT Hub properties govern hub-level security policies, as opposed to device-level access control, and functional
options for cloud-to-device and device-to-cloud messaging. The IoT Hub resource provider also enables you to
export device identities.
Device identity management. Each IoT hub exposes a set of HTTPS REST endpoints to manage device
identities (create, retrieve, update, and delete). Device identities are used for device authentication and access
control.
Device twin management. Each IoT hub exposes a set of service-facing HTTPS REST endpoint to query and
update device twins (update tags and properties).
Jobs management. Each IoT hub exposes a set of service-facing HTTPS REST endpoint to query and manage
jobs.
Device endpoints. For each device in the identity registry, IoT Hub exposes a set of endpoints:
Send device-to -cloud messages. A device uses this endpoint to send device-to-cloud messages.
Receive cloud -to -device messages. A device uses this endpoint to receive targeted cloud-to-device
messages.
Initiate file uploads. A device uses this endpoint to receive an Azure Storage SAS URI from IoT Hub to
upload a file.
Retrieve and update device twin properties. A device uses this endpoint to access its device twin's
properties.
Receive direct method requests. A device uses this endpoint to listen for direct method's requests.
These endpoints are exposed using MQTT v3.1.1, HTTPS 1.1, and AMQP 1.0 protocols. AMQP is also
available over WebSockets on port 443.
Service endpoints. Each IoT hub exposes a set of endpoints for your solution back end to communicate
with your devices. With one exception, these endpoints are only exposed using the AMQP protocol. The
method invocation endpoint is exposed over the HTTPS protocol.
Receive device-to -cloud messages. This endpoint is compatible with Azure Event Hubs. A back-end
service can use it to read the device-to-cloud messages sent by your devices. You can create custom
endpoints on your IoT hub in addition to this built-in endpoint.
Send cloud -to -device messages and receive delivery acknowledgments. These endpoints enable your
solution back end to send reliable cloud-to-device messages, and to receive the corresponding delivery or
expiration acknowledgments.
Receive file notifications. This messaging endpoint allows you to receive notifications of when your
devices successfully upload a file.
Direct method invocation. This endpoint allows a back-end service to invoke a direct method on a device.
Receive operations monitoring events. This endpoint allows you to receive operations monitoring events
if your IoT hub has been configured to emit them. For more information, see IoT Hub operations
monitoring.
The Azure IoT SDKs article describes the various ways to access these endpoints.
All IoT Hub endpoints use the TLS protocol, and no endpoint is ever exposed on unencrypted/unsecured channels.

Custom endpoints
You can link existing Azure services in your subscription to your IoT hub to act as endpoints for message routing.
These endpoints act as service endpoints and are used as sinks for message routes. Devices cannot write directly to
the additional endpoints. To learn more about message routes, see the developer guide entry on sending and
receiving messages with IoT hub.
IoT Hub currently supports the following Azure services as additional endpoints:
Azure Storage containers
Event Hubs
Service Bus Queues
Service Bus Topics
IoT Hub needs write access to these service endpoints for message routing to work. If you configure your
endpoints through the Azure portal, the necessary permissions are added for you. Make sure you configure your
services to support the expected throughput. When you first configure your IoT solution, you may need to monitor
your additional endpoints and make any necessary adjustments for the actual load.
If a message matches multiple routes that all point to the same endpoint, IoT Hub delivers message to that
endpoint only once. Therefore, you do not need to configure deduplication on your Service Bus queue or topic. In
partitioned queues, partition affinity guarantees message ordering.
For the limits on the number of endpoints you can add, see Quotas and throttling.
When using Azure Storage containers
IoT Hub only supports writing data to Azure Storage containers as blobs in the Apache Avro format. IoT Hub
batches messages and writes data to a blob whenever:
The batch reaches a certain size.
Or a certain amount of time has elapsed.
IoT Hub will write to an empty blob if there is no data to write.
IoT Hub defaults to the following file naming convention:

{iothub}/{partition}/{YYYY}/{MM}/{DD}/{HH}/{mm}

You may use whatever file naming convention you wish, however you must use all listed tokens.
When using Service Bus queues and topics
Service Bus queues and topics used as IoT Hub endpoints must not have Sessions or Duplicate Detection
enabled. If either of those options are enabled, the endpoint appears as Unreachable in the Azure portal.

Field gateways
In an IoT solution, a field gateway sits between your devices and your IoT Hub endpoints. It is typically located
close to your devices. Your devices communicate directly with the field gateway by using a protocol supported by
the devices. The field gateway connects to an IoT Hub endpoint using a protocol that is supported by IoT Hub. A
field gateway might be a dedicated hardware device or a low -power computer running custom gateway software.
You can use Azure IoT Edge to implement a field gateway. IoT Edge offers functionality such as multiplexing
communications from multiple devices onto the same IoT Hub connection.

Next steps
Other reference topics in this IoT Hub developer guide include:
IoT Hub query language for device twins, jobs, and message routing
Quotas and throttling
IoT Hub MQTT support
IoT Hub query language for device and module
twins, jobs, and message routing
5/29/2018 • 15 min to read • Edit Online

IoT Hub provides a powerful SQL -like language to retrieve information regarding device twins and jobs, and
message routing. This article presents:
An introduction to the major features of the IoT Hub query language, and
The detailed description of the language.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are only
available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to choose
the right IoT Hub tier.

Device and module twin queries


Device twins and module twins can contain arbitrary JSON objects as both tags and properties. IoT Hub enables
you to query device twins and module twins as a single JSON document containing all twin information. Assume,
for instance, that your IoT hub device twins have the following structure (module twin would be similar just with an
additional moduleId):
{
"deviceId": "myDeviceId",
"etag": "AAAAAAAAAAc=",
"status": "enabled",
"statusUpdateTime": "0001-01-01T00:00:00",
"connectionState": "Disconnected",
"lastActivityTime": "0001-01-01T00:00:00",
"cloudToDeviceMessageCount": 0,
"authenticationType": "sas",
"x509Thumbprint": {
"primaryThumbprint": null,
"secondaryThumbprint": null
},
"version": 2,
"tags": {
"location": {
"region": "US",
"plant": "Redmond43"
}
},
"properties": {
"desired": {
"telemetryConfig": {
"configId": "db00ebf5-eeeb-42be-86a1-458cccb69e57",
"sendFrequencyInSecs": 300
},
"$metadata": {
...
},
"$version": 4
},
"reported": {
"connectivity": {
"type": "cellular"
},
"telemetryConfig": {
"configId": "db00ebf5-eeeb-42be-86a1-458cccb69e57",
"sendFrequencyInSecs": 300,
"status": "Success"
},
"$metadata": {
...
},
"$version": 7
}
}
}

Device twin queries


IoT Hub exposes the device twins as a document collection called devices. So the following query retrieves the
whole set of device twins:

SELECT * FROM devices

NOTE
Azure IoT SDKs support paging of large results.

IoT Hub allows you to retrieve device twins filtering with arbitrary conditions. For instance, to receive device twins
where the location.region tag is set to US use the following query:
SELECT * FROM devices
WHERE tags.location.region = 'US'

Boolean operators and arithmetic comparisons are supported as well. For example, to retrieve device twins located
in the US and configured to send telemetry less than every minute use the following query:

SELECT * FROM devices


WHERE tags.location.region = 'US'
AND properties.reported.telemetryConfig.sendFrequencyInSecs >= 60

As a convenience, it is also possible to use array constants with the IN and NIN (not in) operators. For instance, to
retrieve device twins that report WiFi or wired connectivity use the following query:

SELECT * FROM devices


WHERE properties.reported.connectivity IN ['wired', 'wifi']

It is often necessary to identify all device twins that contain a specific property. IoT Hub supports the function
is_defined() for this purpose. For instance, to retrieve device twins that define the connectivity property use the
following query:

SELECT * FROM devices


WHERE is_defined(properties.reported.connectivity)

Refer to the WHERE clause section for the full reference of the filtering capabilities.
Grouping and aggregations are also supported. For instance, to find the count of devices in each telemetry
configuration status use the following query:

SELECT properties.reported.telemetryConfig.status AS status,


COUNT() AS numberOfDevices
FROM devices
GROUP BY properties.reported.telemetryConfig.status

This grouping query would return a result similar to the following example:

[
{
"numberOfDevices": 3,
"status": "Success"
},
{
"numberOfDevices": 2,
"status": "Pending"
},
{
"numberOfDevices": 1,
"status": "Error"
}
]

In this example, three devices reported successful configuration, two are still applying the configuration, and one
reported an error.
Projection queries allow developers to return only the properties they care about. For example, to retrieve the last
activity time of all disconnected devices use the following query:
SELECT LastActivityTime FROM devices WHERE status = 'enabled'

Module twin queries


Querying on module twins is similar to query on device twins, but using a different collection/namespace, i.e.
instead of “from devices” you can query

SELECT * FROM devices.modules

We don't allow join between the devices and devices.modules collections. If you want to query module twins across
devices, you do do it based on tags. This query will return all module twins across all devices with the scanning
status:

Select * from devices.modules where reported.properties.status = 'scanning'

This query will return all module twins with the scanning status, but only on the specified subset of devices.

Select * from devices.modules where reported.properties.status = 'scanning' and deviceId IN ('device1',


'device2')

C# example
The query functionality is exposed by the C# service SDK in the RegistryManager class. Here is an example of a
simple query:

var query = registryManager.CreateQuery("SELECT * FROM devices", 100);


while (query.HasMoreResults)
{
var page = await query.GetNextAsTwinAsync();
foreach (var twin in page)
{
// do work on twin object
}
}

The query object is instantiated with a page size (up to 100). Then multiple pages are retrieved by calling the
GetNextAsTwinAsync methods multiple times.
The query object exposes multiple Next values, depending on the deserialization option required by the query. For
example, device twin or job objects, or plain JSON when using projections.
Node.js example
The query functionality is exposed by the Azure IoT service SDK for Node.js in the Registry object. Here is an
example of a simple query:
var query = registry.createQuery('SELECT * FROM devices', 100);
var onResults = function(err, results) {
if (err) {
console.error('Failed to fetch the results: ' + err.message);
} else {
// Do something with the results
results.forEach(function(twin) {
console.log(twin.deviceId);
});

if (query.hasMoreResults) {
query.nextAsTwin(onResults);
}
}
};
query.nextAsTwin(onResults);

The query object is instantiated with a page size (up to 100). Then multiple pages are retrieved by calling the
nextAsTwin method multiple times.
The query object exposes multiple Next values, depending on the deserialization option required by the query. For
example, device twin or job objects, or plain JSON when using projections.
Limitations

IMPORTANT
Query results can have a few minutes of delay with respect to the latest values in device twins. If querying individual device
twins by ID, use the retrieve device twin API. This API always contains the latest values and has higher throttling limits.

Currently, comparisons are supported only between primitive types (no objects), for instance
... WHERE properties.desired.config = properties.reported.config is supported only if those properties have
primitive values.

Get started with jobs queries


Jobs provide a way to execute operations on sets of devices. Each device twin contains the information of the jobs
of which it is part in a collection called jobs. Logically,
{
"deviceId": "myDeviceId",
"etag": "AAAAAAAAAAc=",
"tags": {
...
},
"properties": {
...
},
"jobs": [
{
"deviceId": "myDeviceId",
"jobId": "myJobId",
"jobType": "scheduleTwinUpdate",
"status": "completed",
"startTimeUtc": "2016-09-29T18:18:52.7418462",
"endTimeUtc": "2016-09-29T18:20:52.7418462",
"createdDateTimeUtc": "2016-09-29T18:18:56.7787107Z",
"lastUpdatedDateTimeUtc": "2016-09-29T18:18:56.8894408Z",
"outcome": {
"deviceMethodResponse": null
}
},
...
]
}

Currently, this collection is queryable as devices.jobs in the IoT Hub query language.

IMPORTANT
Currently, the jobs property is never returned when querying device twins. That is, queries that contain 'FROM devices'. The
jobs property can only be accessed directly with queries using FROM devices.jobs .

For instance, to get all jobs (past and scheduled) that affect a single device, you can use the following query:

SELECT * FROM devices.jobs


WHERE devices.jobs.deviceId = 'myDeviceId'

Note how this query provides the device-specific status (and possibly the direct method response) of each job
returned. It is also possible to filter with arbitrary Boolean conditions on all object properties in the devices.jobs
collection. For instance, to retrieve all completed device twin update jobs that were created after September 2016
for a specific device, use the following query:

SELECT * FROM devices.jobs


WHERE devices.jobs.deviceId = 'myDeviceId'
AND devices.jobs.jobType = 'scheduleTwinUpdate'
AND devices.jobs.status = 'completed'
AND devices.jobs.createdTimeUtc > '2016-09-01'

You can also retrieve the per-device outcomes of a single job.

SELECT * FROM devices.jobs


WHERE devices.jobs.jobId = 'myJobId'

Limitations
Currently, queries on devices.jobs do not support:
Projections, therefore only SELECT * is possible.
Conditions that refer to the device twin in addition to job properties (see the preceding section).
Performing aggregations, such as count, avg, group by.

Device-to-cloud message routes query expressions


Using device-to-cloud routes, you can configure IoT Hub to dispatch device-to-cloud messages to different
endpoints. Dispatching is based on expressions evaluated against individual messages.
The route condition uses the same IoT Hub query language as conditions in twin and job queries. Route conditions
are evaluated on the message headers and body. Your routing query expression may involve only message headers,
only the message body, or both. IoT Hub assumes a specific schema for the headers and message body in order to
route messages. The following sections describe what is required for IoT Hub to properly route.
Routing on message headers
IoT Hub assumes the following JSON representation of message headers for message routing:

{
"message": {
"systemProperties": {
"contentType": "application/json",
"contentEncoding": "utf-8",
"iothub-message-source": "deviceMessages",
"iothub-enqueuedtime": "2017-05-08T18:55:31.8514657Z"
},
"appProperties": {
"processingPath": "<optional>",
"verbose": "<optional>",
"severity": "<optional>",
"testDevice": "<optional>"
},
"body": "{\"Weather\":{\"Temperature\":50}}"
}
}

Message system properties are prefixed with the '$' symbol. User properties are always accessed with their
name. If a user property name coincides with a system property (such as $contentType ), the user property is
retrieved with the $contentType expression. You can always access the system property using brackets {} : for
instance, you can use the expression {$contentType} to access the system property contentType . Bracketed
property names always retrieve the corresponding system property.
Remember that property names are case insensitive.

NOTE
All message properties are strings. System properties, as described in the developer guide, are currently not available to use
in queries.

For example, if you use a messageType property, you might want to route all telemetry to one endpoint, and all
alerts to another endpoint. You can write the following expression to route the telemetry:

messageType = 'telemetry'

And the following expression to route the alert messages:


messageType = 'alert'

Boolean expressions and functions are also supported. This feature enables you to distinguish between severity
level, for example:

messageType = 'alerts' AND as_number(severity) <= 2

Refer to the Expression and conditions section for the full list of supported operators and functions.
Routing on message bodies
IoT Hub can only route based on message body contents if the message body is properly formed JSON encoded in
UTF -8, UTF -16, or UTF -32. Set the content type of the message to application/json . Set the content encoding to
one of the supported UTF encodings in the message headers. If either of the headers is not specified, IoT Hub does
not attempt to evaluate any query expression involving the body against the message. If your message is not a
JSON message, or if the message does not specify the content type and content encoding, you can still use
message routing to route the message based on the message headers.
The following example shows how to create a message with a properly formed and encoded JSON body:
string messageBody = @"{
""Weather"":{
""Temperature"":50,
""Time"":""2017-03-09T00:00:00.000Z"",
""PrevTemperatures"":[
20,
30,
40
],
""IsEnabled"":true,
""Location"":{
""Street"":""One Microsoft Way"",
""City"":""Redmond"",
""State"":""WA""
},
""HistoricalData"":[
{
""Month"":""Feb"",
""Temperature"":40
},
{
""Month"":""Jan"",
""Temperature"":30
}
]
}
}";

// Encode message body using UTF-8


byte[] messageBytes = Encoding.UTF8.GetBytes(messageBody);

using (var message = new Message(messageBytes))


{
// Set message body type and content encoding.
message.ContentEncoding = "utf-8";
message.ContentType = "application/json";

// Add other custom application properties.


message.Properties["Status"] = "Active";

await deviceClient.SendEventAsync(message);
}

You can use $body in the query expression to route the message. You can use a simple body reference, body array
reference, or multiple body references in the query expression. Your query expression can also combine a body
reference with a message header reference. For example, the following are all valid query expressions:

$body.Weather.HistoricalData[0].Month = 'Feb'
$body.Weather.Temperature = 50 AND $body.Weather.IsEnabled
length($body.Weather.Location.State) = 2
$body.Weather.Temperature = 50 AND Status = 'Active'

Basics of an IoT Hub query


Every IoT Hub query consists of SELECT and FROM clauses, with optional WHERE and GROUP BY clauses. Every
query is run on a collection of JSON documents, for example device twins. The FROM clause indicates the
document collection to be iterated on (devices or devices.jobs). Then, the filter in the WHERE clause is applied.
With aggregations, the results of this step are grouped as specified in the GROUP BY clause. For each group, a row
is generated as specified in the SELECT clause.
SELECT <select_list>
FROM <from_specification>
[WHERE <filter_condition>]
[GROUP BY <group_specification>]

FROM clause
The FROM <from_specification> clause can assume only two values: FROM devices to query device twins, or
FROM devices.jobs to query job per-device details.

WHERE clause
The WHERE <filter_condition> clause is optional. It specifies one or more conditions that the JSON documents
in the FROM collection must satisfy to be included as part of the result. Any JSON document must evaluate the
specified conditions to "true" to be included in the result.
The allowed conditions are described in section Expressions and conditions.

SELECT clause
The SELECT <select_list> is mandatory and specifies what values are retrieved from the query. It specifies the
JSON values to be used to generate new JSON objects. For each element of the filtered (and optionally grouped)
subset of the FROM collection, the projection phase generates a new JSON object. This object is constructed with
the values specified in the SELECT clause.
Following is the grammar of the SELECT clause:

SELECT [TOP <max number>] <projection list>

<projection_list> ::=
'*'
| <projection_element> AS alias [, <projection_element> AS alias]+

<projection_element> :==
attribute_name
| <projection_element> '.' attribute_name
| <aggregate>

<aggregate> :==
count()
| avg(<projection_element>)
| sum(<projection_element>)
| min(<projection_element>)
| max(<projection_element>)

Attribute_name refers to any property of the JSON document in the FROM collection. Some examples of
SELECT clauses can be found in the Getting started with device twin queries section.
Currently, selection clauses different than SELECT* are only supported in aggregate queries on device twins.

GROUP BY clause
The GROUP BY <group_specification> clause is an optional step that executes after the filter specified in the
WHERE clause, and before the projection specified in the SELECT. It groups documents based on the value of an
attribute. These groups are used to generate aggregated values as specified in the SELECT clause.
An example of a query using GROUP BY is:
SELECT properties.reported.telemetryConfig.status AS status,
COUNT() AS numberOfDevices
FROM devices
GROUP BY properties.reported.telemetryConfig.status

The formal syntax for GROUP BY is:

GROUP BY <group_by_element>
<group_by_element> :==
attribute_name
| < group_by_element > '.' attribute_name

Attribute_name refers to any property of the JSON document in the FROM collection.
Currently, the GROUP BY clause is only supported when querying device twins.

Expressions and conditions


At a high level, an expression:
Evaluates to an instance of a JSON type (such as Boolean, number, string, array, or object).
Is defined by manipulating data coming from the device JSON document and constants using built-in operators
and functions.
Conditions are expressions that evaluate to a Boolean. Any constant different than Boolean true is considered as
false. This rule includes null, undefined, any object or array instance, any string, and the Boolean false.
The syntax for expressions is:

<expression> ::=
<constant> |
attribute_name |
<function_call> |
<expression> binary_operator <expression> |
<create_array_expression> |
'(' <expression> ')'

<function_call> ::=
<function_name> '(' expression ')'

<constant> ::=
<undefined_constant>
| <null_constant>
| <number_constant>
| <string_constant>
| <array_constant>

<undefined_constant> ::= undefined


<null_constant> ::= null
<number_constant> ::= decimal_literal | hexadecimal_literal
<string_constant> ::= string_literal
<array_constant> ::= '[' <constant> [, <constant>]+ ']'

To understand what each symbol in the expressions syntax stands for, refer to the following table:

SYMBOL DEFINITION

attribute_name Any property of the JSON document in the FROM collection.


SYMBOL DEFINITION

binary_operator Any binary operator listed in the Operators section.

function_name Any function listed in the Functions section.

decimal_literal A float expressed in decimal notation.

hexadecimal_literal A number expressed by the string ‘0x’ followed by a string of


hexadecimal digits.

string_literal String literals are Unicode strings represented by a sequence of


zero or more Unicode characters or escape sequences. String
literals are enclosed in single quotes or double quotes. Allowed
escapes: \' , \" , \\ , \uXXXX for Unicode characters
defined by 4 hexadecimal digits.

Operators
The following operators are supported:

FAMILY OPERATORS

Arithmetic +, -, *, /, %

Logical AND, OR, NOT

Comparison =, !=, <, >, <=, >=, <>

Functions
When querying twins and jobs the only supported function is:

FUNCTION DESCRIPTION

IS_DEFINED(property) Returns a Boolean indicating if the property has been assigned


a value (including null ).

In routes conditions, the following math functions are supported:

FUNCTION DESCRIPTION

ABS(x) Returns the absolute (positive) value of the specified numeric


expression.

EXP(x) Returns the exponential value of the specified numeric


expression (e^x).

POWER(x,y) Returns the value of the specified expression to the specified


power (x^y).

SQUARE(x) Returns the square of the specified numeric value.

CEILING(x) Returns the smallest integer value greater than, or equal to,
the specified numeric expression.
FUNCTION DESCRIPTION

FLOOR(x) Returns the largest integer less than or equal to the specified
numeric expression.

SIGN(x) Returns the positive (+1), zero (0), or negative (-1) sign of the
specified numeric expression.

SQRT(x) Returns the square root of the specified numeric value.

In routes conditions, the following type checking and casting functions are supported:

FUNCTION DESCRIPTION

AS_NUMBER Converts the input string to a number. noop if input is a


number; Undefined if string does not represent a number.

IS_ARRAY Returns a Boolean value indicating if the type of the specified


expression is an array.

IS_BOOL Returns a Boolean value indicating if the type of the specified


expression is a Boolean.

IS_DEFINED Returns a Boolean indicating if the property has been assigned


a value.

IS_NULL Returns a Boolean value indicating if the type of the specified


expression is null.

IS_NUMBER Returns a Boolean value indicating if the type of the specified


expression is a number.

IS_OBJECT Returns a Boolean value indicating if the type of the specified


expression is a JSON object.

IS_PRIMITIVE Returns a Boolean value indicating if the type of the specified


expression is a primitive (string, Boolean, numeric, or null ).

IS_STRING Returns a Boolean value indicating if the type of the specified


expression is a string.

In routes conditions, the following string functions are supported:

FUNCTION DESCRIPTION

CONCAT(x, y, …) Returns a string that is the result of concatenating two or


more string values.

LENGTH(x) Returns the number of characters of the specified string


expression.

LOWER(x) Returns a string expression after converting uppercase


character data to lowercase.
FUNCTION DESCRIPTION

UPPER(x) Returns a string expression after converting lowercase


character data to uppercase.

SUBSTRING(string, start [, length]) Returns part of a string expression starting at the specified
character zero-based position and continues to the specified
length, or to the end of the string.

INDEX_OF(string, fragment) Returns the starting position of the first occurrence of the
second string expression within the first specified string
expression, or -1 if the string is not found.

STARTS_WITH(x, y) Returns a Boolean indicating whether the first string


expression starts with the second.

ENDS_WITH(x, y) Returns a Boolean indicating whether the first string


expression ends with the second.

CONTAINS(x,y) Returns a Boolean indicating whether the first string


expression contains the second.

Next steps
Learn how to execute queries in your apps using Azure IoT SDKs.
Reference - IoT Hub quotas and throttling
5/29/2018 • 4 min to read • Edit Online

Quotas and throttling


Each Azure subscription can have at most 10 IoT hubs, and at most 1 Free hub.
Each IoT hub is provisioned with a certain number of units in a specific tier. For more information, see Azure IoT
Hub Pricing. The tier and number of units determine the maximum daily quota of messages that you can send.
The tier also determines the throttling limits that IoT Hub enforces on all operations.

Operation throttles
Operation throttles are rate limitations that are applied in minute ranges, and are intended to prevent abuse. IoT
Hub tries to avoid returning errors whenever possible, but starts returning exceptions if the throttle is violated for
too long.
At any given time, you can increase quotas or throttle limits by increasing the number of provisioned units in an IoT
hub.
The following table shows the enforced throttles. Values refer to an individual hub.

THROTTLE FREE, B1, AND S1 B2 AND S2 B3 AND S3

Identity registry operations 1.67/sec/unit (100/min/unit) 1.67/sec/unit (100/min/unit) 83.33/sec/unit


(create, retrieve, list, update, (5000/min/unit)
delete)

New device connections (this Higher of 100/sec or 120 new 6000 new
limit applies to the rate at 12/sec/unit connections/sec/unit connections/sec/unit
which new connections are For example, two S1 units
established, not the total are 2*12 = 24 new
number of connections) connections/sec, but you
have at least 100 new
connections/sec across your
units. With nine S1 units,
you have 108 new
connections/sec (9*12)
across your units.

Device-to-cloud sends Higher of 100/sec or 120/sec/unit 6000/sec/unit


12/sec/unit
For example, two S1 units
are 2*12 = 24/sec, but you
have at least 100/sec across
your units. With nine S1
units, you have 108/sec
(9*12) across your units.

Cloud-to-device sends1 1.67/sec/unit (100/min/unit) 1.67/sec/unit (100/min/unit) 83.33/sec/unit


(5000/min/unit)
THROTTLE FREE, B1, AND S1 B2 AND S2 B3 AND S3

Cloud-to-device receives1 16.67/sec/unit 16.67/sec/unit 833.33/sec/unit


(only when device uses (1000/min/unit) (1000/min/unit) (50000/min/unit)
HTTPS)

File upload 1.67 file upload 1.67 file upload 83.33 file upload
notifications/sec/unit notifications/sec/unit notifications/sec/unit
(100/min/unit) (100/min/unit) (5000/min/unit)

Direct methods1 160KB/sec/unit2 480KB/sec/unit2 24MB/sec/unit2

Twin (device and module) 10/sec Higher of 10/sec or 50/sec/unit


reads1 1/sec/unit

Twin updates (device and 10/sec Higher of 10/sec or 50/sec/unit


module)1 1/sec/unit

Jobs operations1 1.67/sec/unit (100/min/unit) 1.67/sec/unit (100/min/unit) 83.33/sec/unit


(create, update, list, delete) (5000/min/unit)

Jobs per-device operation 10/sec Higher of 10/sec or 50/sec/unit


throughput1 1/sec/unit

Configurations and edge 0.33/sec/unit (20/min/unit) 0.33/sec/unit (20/min/unit) 0.33/sec/unit (20/min/unit)


deployments1
(create, update, list, delete)

1This feature is not available in the basic tier of IoT Hub. For more information, see How to choose the right IoT
Hub.
2Throttling meter size is 8 KB.

The device connections throttle governs the rate at which new device connections can be established with an IoT
hub. The device connections throttle does not govern the maximum number of simultaneously connected devices.
The throttle depends on the number of units that are provisioned for the IoT hub.
For example, if you buy a single S1 unit, you get a throttle of 100 connections per second. Therefore, to connect
100,000 devices, it takes at least 1000 seconds (approximately 16 minutes). However, you can have as many
simultaneously connected devices as you have devices registered in your identity registry.
For an in-depth discussion of IoT Hub throttling behavior, see the blog post IoT Hub throttling and you.

IMPORTANT
Identity registry operations are intended for run-time use in device management and provisioning scenarios. Reading or
updating a large number of device identities is supported through import and export jobs.

Other limits
IoT Hub enforces other operational limits:

OPERATION LIMIT

File upload URIs 10000 SAS URIs can be out for a storage account at one time.
10 SAS URIs/device can be out at one time.
OPERATION LIMIT

Jobs1 Job history is retained up to 30 days


Maximum concurrent jobs is 1 (for Free) and S1, 5 (for S2), 10
(for S3).

Additional endpoints Paid SKU hubs may have 10 additional endpoints. Free SKU
hubs may have one additional endpoint.

Message routing rules Paid SKU hubs may have 100 routing rules. Free SKU hubs
may have five routing rules.

Device-to-cloud messaging Maximum message size 256 KB

Cloud-to-device messaging1 Maximum message size 64 KB. Maximum pending messages


for delivery is 50.

Direct method1 Maximum direct method payload size is 128 KB.

Configurations 20 configurations per hub.

Edge deployments 20 deployments per hub. 20 modules per deployment.

Twins Maximum size per twin section (tags, desired properties,


reported properties) is 8 KB

1This feature is not available in the basic tier of IoT Hub. For more information, see How to choose the right IoT
Hub.

NOTE
Currently, the maximum number of devices you can connect to a single IoT hub is 500,000. If you want to increase this limit,
contact Microsoft Support.

Latency
IoT Hub strives to provide low latency for all operations. However, due to network conditions and other
unpredictable factors it cannot guarantee a maximum latency. When designing your solution, you should:
Avoid making any assumptions about the maximum latency of any IoT Hub operation.
Provision your IoT hub in the Azure region closest to your devices.
Consider using Azure IoT Edge to perform latency-sensitive operations on the device or on a gateway close to
the device.
Multiple IoT Hub units affect throttling as described previously, but do not provide any additional latency benefits
or guarantees. If you see unexpected increases in operation latency, contact Microsoft Support.

Next steps
Other reference topics in this IoT Hub developer guide include:
IoT Hub endpoints
IoT Hub query language for device twins, jobs, and message routing
IoT Hub MQTT support
Azure IoT Hub pricing information
5/29/2018 • 3 min to read • Edit Online

Azure IoT Hub pricing provides the general information on different SKUs and pricing for IoT Hub. This article
contains additional details on how the various IoT Hub functionalities are metered as messages by IoT Hub.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are only
available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to choose
the right IoT Hub tier.

Charges per operation


OPERATION BILLING INFORMATION

Identity registry operations Not charged.


(create, retrieve, list, update, delete)

Device-to-cloud messages Successfully sent messages are charged in 4-KB chunks on


ingress into IoT Hub. For example, a 6-KB message is charged
2 messages.

Cloud-to-device messages Successfully sent messages are charged in 4-KB chunks, for
example a 6-KB message is charged 2 messages.

File uploads File transfer to Azure Storage is not metered by IoT Hub. File
transfer initiation and completion messages are charged as
messaged metered in 4-KB increments. For example,
transferring a 10-MB file is charged two messages in addition
to the Azure Storage cost.

Direct methods Successful method requests are charged in 4-KB chunks,


responses with non-empty bodies are charged in 4-KB chunks
as additional messages. Requests to disconnected devices are
charged as messages in 4-KB chunks. For example, a method
with a 6-KB body that results in a response with no body from
the device, is charged as two messages. A method with a 6-KB
body that results in a 1-KB response from the device is
charged as two messages for the request plus another
message for the response.

Device and module twin reads Twin reads from the device or module and from the solution
back end are charged as messages in 512-byte chunks. For
example, reading a 6-KB twin is charged as 12 messages.

Device and module twin updates (tags and properties) Twin updates from the device or module and from the solution
back end are charged as messages in 512-byte chunks. For
example, reading a 6-KB twin is charged as 12 messages.

Device and module twin queries Queries are charged as messages depending on the result size
in 512-byte chunks.
OPERATION BILLING INFORMATION

Jobs operations Not charged.


(create, update, list, delete)

Jobs per-device operations Jobs operations (such as twin updates, and methods) are
charged as normal. For example, a job resulting in 1000
method calls with 1-KB requests and empty-body responses is
charged 1000 messages.

NOTE
All sizes are computed considering the payload size in bytes (protocol framing is ignored). For messages, which have
properties and body, the size is computed in a protocol-agnostic way. For more information, see IoT Hub messaging
developer's guide.

Example #1
A device sends one 1-KB device-to-cloud message per minute to IoT Hub, which is then read by Azure Stream
Analytics. The solution back end invokes a method (with 512-byte payload) on the device every 10 minutes to
trigger a specific action. The device responds to the method with a result of 200 bytes.
The device consumes:
One message * 60 minutes * 24 hours = 1440 messages per day for the device-to-cloud messages.
Two request plus response * 6 times per hour * 24 hours = 288 messages for the methods.
This calculation gives a total of 1728 messages per day.

Example #2
A device sends one 100-KB device-to-cloud message every hour. It also updates its device twin with 1-KB payloads
every four hours. The solution back end, once per day, reads the 14-KB device twin and updates it with 512-byte
payloads to change configurations.
The device consumes:
25 (100 KB / 4 KB ) messages * 24 hours for device-to-cloud messages.
Two messages (1 KB / 0.5 KB ) * six times per day for device twin updates.
This calculation gives a total of 612 messages per day.
The solution back end consumes 28 messages (14 KB / 0.5 KB ) to read the device twin, plus one message to update
it, for a total of 29 messages.
In total, the device and the solution back end consume 641 messages per day.
Understand and use Azure IoT Hub SDKs
6/6/2018 • 2 min to read • Edit Online

There are two categories of software development kits (SDKs) for working with IoT Hub:
Device SDKs enable you to build apps that run on your IoT devices. These apps send telemetry to your IoT
hub, and optionally receive messages, job, method, or twin updates from your IoT hub.
Service SDKs enable you to manage your IoT hub, and optionally send messages, schedule jobs, invoke
direct methods, or send desired property updates to your IoT devices.
Learn about the benefits of developing using Azure IoT SDKs here.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are only
available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to choose
the right IoT Hub tier.

Azure IoT device SDKs


The Microsoft Azure IoT device SDKs contain code that facilitates building devices and applications that connect to
and are managed by Azure IoT Hub services.
Azure IoT Hub device SDK for .NET:
Install from Nuget
Source code
API reference
Azure IoT Hub device SDK for C: written in ANSI C (C99) for portability and broad platform compatibility
Install from apt-get, MBED, Arduino IDE, or Nuget
Source code
API reference
Azure IoT Hub device SDK for Java:
Add to Maven project
Source code
API reference
Azure IoT Hub device SDK for Node.js:
Install from npm
Source code
API reference
Azure IoT Hub device SDK for Python:
Install from pip
Source code
Azure IoT Hub device SDK for iOS:
Install from CocoaPod
Samples

NOTE
See the readme files in the GitHub repositories for information about using language and platform-specific package managers
to install binaries and dependencies on your development machine.

OS platform and hardware compatibility


For more information about SDK compatibility with specific hardware devices, see the Azure Certified for IoT
device catalog or individual repository.

Azure IoT service SDKs


The Azure IoT service SDKs contain code to facilitate building applications that interact directly with IoT Hub to
manage devices and security.
Azure IoT Hub service SDK for .NET:
Download from Nuget
Source code
API reference
Azure IoT Hub service SDK for Java:
Add to Maven project
Source code
API reference
Azure IoT Hub service SDK for Node.js:
Download from npm
Source code
API reference
Azure IoT Hub service SDK for Python:
Download from pip
Source code
Azure IoT Hub service SDK for C:
Download from apt-get, MBED, Arduino IDE, or Nuget
Source code
Azure IoT Hub service SDK for iOS:
Install from CocoaPod
Samples
NOTE
See the readme files in the GitHub repositories for information about using language and platform-specific package managers
to install binaries and dependencies on your development machine.

Next steps
Other reference topics in this IoT Hub developer guide include:
IoT Hub endpoints
IoT Hub query language for device twins, jobs, and message routing
Quotas and throttling
IoT Hub MQTT support
IoT Hub REST API reference
Develop for constrained devices using Azure IoT
SDKs
5/25/2018 • 3 min to read • Edit Online

Develop using Azure IoT Hub C SDK


Azure IoT Hub C SDK is written in ANSI C (C99), which makes it well-suited to operate a variety of platforms with
small disk and memory footprint. The recommended RAM is at least 64 KB, but the exact memory footprint
depends on the protocol used, the number of connections opened, as well as the platform targeted.
C SDK is available in package form from apt-get, NuGet, and MBED. To target constrained devices, you may want
to build the SDK locally for your target platform. This documentation demonstrates how to remove certain features
to shrink the footprint of the C SDK using cmake. In addition, this documentation discusses the best practice
programming models for working with constrained devices.
Building the C SDK for constrained devices
Prerequisites
Follow this setup guide to prepare your development environment for building the C SDK. Before you get to the
step for building with cmake, you can invoke cmake flags to remove unused features.
Remove additional protocol libraries
C SDK supports five protocols today: MQTT, MQTT over WebSocket, AMQPs, AMQP over WebSocket, and
HTTPS. Most scenarios require one to two protocols running on a client, hence you can remove the protocol library
you are not using from the SDK. Additional information about choosing the appropriate communication protocol
for your scenario can be found in this document. For example, MQTT is a lightweight protocol that is often better
suited for constrained devices.
You can remove AMQP and HTTP libraries using the following cmake command:

cmake -Duse_amqp=OFF -Duse_http=OFF <Path_to_cmake>

Remove SDK logging capability


The C SDK provides extensive logging throughout to help with debugging. You can remove the logging capability
for production devices using the following cmake command:

cmake -Dno_logging=OFF <Path_to_cmake>

Remove upload to blob capability


You can upload large files to Azure Storage using the built-in capability in the SDK. Azure IoT Hub acts as a
dispatcher to an associated Azure Storage account. You can use this feature to send media files, large telemetry
batches, and logs. Learn more about upload files with IoT Hub in this document. If your application does not
require this functionality, you can remove this feature using the following cmake command:

cmake -Ddont_use_uploadtoblob=ON <Path_to_cmake>

Running strip on Linux environment


If your binaries run on Linux system, you can leverage the strip command to reduce the size of the final application
after compiling.
strip -s <Path_to_executable>

Programming models for constrained devices


Avoid using the Serializer
The C SDK has an optional serializer, which allows you to use declarative mapping tables to define methods and
device twin properties. The serializer is designed to simplify development, but it adds overhead, which is not
optimal for constrained devices. In this case, consider using primitive client APIs and parse json by using a
lightweight parser such as parson.
Use the lower layer (LL)
The C SDK supports two programming models. One set has APIs with an LL infix, which stands for lower layer. This
set of APIs are lighter weight and do not spin up worker threads, which means the user must manually control
scheduling. For example, for the device client, the LL APIs can be found in this header file. Another set of APIs
without the LL index is called the convenience layer, where a worker thread is spun automatically. For example, the
convenience layer APIs for the device client can be found in this header file. For constrained devices where each
extra thread can take a substantial percentage of system resources, consider using LL APIs.

Next steps
To learn more about Azure IoT C SDK architecture:
Azure IoT C SDK source code
Azure IoT device SDK for C introduction
Develop for mobile devices using Azure IoT SDKs
5/29/2018 • 2 min to read • Edit Online

Things in the Internet of Things may refer to a wide range of devices with varying capability: sensors,
microcontrollers, smart devices, industrial gateways, and even mobile devices. A mobile device can be an IoT
device, where it is sending device-to-cloud telemetry and managed by the cloud. It can also be the device running a
back-end service application, which manages other IoT devices. In both cases, Azure IoT Hub SDKs can be used to
develop applications that work for mobile devices.

Develop for native iOS platform


Azure IoT Hub SDKs provide native iOS platform support through Azure IoT Hub C SDK. You can think of it as an
iOS SDK that you can incorporate in your Swift or Objective C XCode project. There are two ways to use the C
SDK on iOS:
Use the CocoaPod libraries in XCode project directly.
Download the source code for C SDK and build for iOS platform following the build instruction for MacOS.
Azure IoT Hub C SDK is written in C99 for maximum portability to various platforms. The porting process involves
writing a thin adoption layer for the platform-specific components, which can be found here for iOS. The features in
the C SDK can be leveraged on iOS platform, including the Azure IoT Hub primitives supported and SDK-specific
features such as retry policy for network reliability. The interface for iOS SDK is also similar to the interface for
Azure IoT Hub C SDK.
These documentations walk through how to develop a device application or service application on an iOS device:
Quickstart: Send telemetry from a device to an IoT hub
Send messages from the cloud to your device with IoT hub
Develop with Azure IoT Hub CocoaPod libraries
Azure IoT Hub SDKs releases a set of Objective-C CocoaPod libraries for iOS development. To see the latest list of
CocoaPod libraries, see CocoaPods for Microsoft Azure IoT. Once the relevant libraries are incorporated into your
XCode project, there are two ways to write IoT Hub related code:
Objective C function: If your project is written in Objective-C, you can call APIs from Azure IoT Hub C SDK
directly. If your project is written in Swift, you can call @objc func before creating your function, and proceed to
writing all logics related to Azure IoT Hub using C or Objective-C code. A set of samples demonstrating both
can be found in the sample repository.
Incorporate C samples: If you have written a C device application, you can reference it directly in your XCode
project:
Add the sample.c file to your XCode project from XCode.
Add the header file to your dependency. A header file is included in the sample repository as example.
For more information, please visit Apple's documentation page for Objective-C.

Next steps
IoT Hub REST API reference
Azure IoT C SDK source code
Communicate with your IoT hub using the MQTT
protocol
5/29/2018 • 11 min to read • Edit Online

IoT Hub enables devices to communicate with the IoT Hub device endpoints using:
MQTT v3.1.1 on port 8883
MQTT v3.1.1 over WebSocket on port 443.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are only
available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to choose
the right IoT Hub tier.

All device communication with IoT Hub must be secured using TLS/SSL. Therefore, IoT Hub doesn’t support non-
secure connections over port 1883.

Connecting to IoT Hub


A device can use the MQTT protocol to connect to an IoT hub using:
Either the libraries in the Azure IoT SDKs.
Or the MQTT protocol directly.

Using the device SDKs


Device SDKs that support the MQTT protocol are available for Java, Node.js, C, C#, and Python. The device SDKs
use the standard IoT Hub connection string to establish a connection to an IoT hub. To use the MQTT protocol, the
client protocol parameter must be set to MQTT. By default, the device SDKs connect to an IoT Hub with the
CleanSession flag set to 0 and use QoS 1 for message exchange with the IoT hub.
When a device is connected to an IoT hub, the device SDKs provide methods that enable the device to exchange
messages with an IoT hub.
The following table contains links to code samples for each supported language and specifies the parameter to use
to establish a connection to IoT Hub using the MQTT protocol.

LANGUAGE PROTOCOL PARAMETER

Node.js azure-iot-device-mqtt

Java IotHubClientProtocol.MQTT

C MQTT_Protocol

C# TransportType.Mqtt

Python IoTHubTransportProvider.MQTT
Migrating a device app from AMQP to MQTT
If you are using the device SDKs, switching from using AMQP to MQTT requires changing the protocol parameter
in the client initialization as stated previously.
When doing so, make sure to check the following items:
AMQP returns errors for many conditions, while MQTT terminates the connection. As a result your exception
handling logic might require some changes.
MQTT does not support the reject operations when receiving cloud-to-device messages. If your back-end app
needs to receive a response from the device app, consider using direct methods.

Using the MQTT protocol directly


If a device cannot use the device SDKs, it can still connect to the public device endpoints using the MQTT protocol
on port 8883. In the CONNECT packet the device should use the following values:
For the ClientId field, use the deviceId.
For the Username field, use {iothubhostname}/{device_id}/api-version=2016-11-14 , where {iothubhostname}
is the full CName of the IoT hub.
For example, if the name of your IoT hub is contoso.azure-devices.net and if the name of your device is
MyDevice01, the full Username field should contain:
contoso.azure-devices.net/MyDevice01/api-version=2016-11-14

For the Password field, use a SAS token. The format of the SAS token is the same as for both the HTTPS
and AMQP protocols:
SharedAccessSignature sig={signature-string}&se={expiry}&sr={URL-encoded-resourceURI}

NOTE
If you use X.509 certificate authentication, SAS token passwords are not required. For more information, see Set up
X.509 security in your Azure IoT Hub

For more information about how to generate SAS tokens, see the device section of Using IoT Hub security
tokens.
When testing, you can also use the device explorer tool to quickly generate a SAS token that you can copy
and paste into your own code:
1. Go to the Management tab in Device Explorer.
2. Click SAS Token (top right).
3. On SASTokenForm, select your device in the DeviceID drop down. Set your TTL.
4. Click Generate to create your token.
The SAS token that's generated has the following structure:
HostName={your hub name}.azure-
devices.net;DeviceId=javadevice;SharedAccessSignature=SharedAccessSignature sr={your hub
name}.azure-devices.net%2Fdevices%2FMyDevice01%2Fapi-version%3D2016-11-
14&sig=vSgHBMUG.....Ntg%3d&se=1456481802

The part of this token to use as the Password field to connect using MQTT is:
SharedAccessSignature sr={your hub name}.azure-devices.net%2Fdevices%2FMyDevice01%2Fapi-
version%3D2016-11-14&sig=vSgHBMUG.....Ntg%3d&se=1456481802
For MQTT connect and disconnect packets, IoT Hub issues an event on the Operations Monitoring channel. This
event has additional information that can help you to troubleshoot connectivity issues.
The device app can specify a Will message in the CONNECT packet. The device app should use
devices/{device_id}/messages/events/{property_bag} or devices/{device_id}/messages/events/{property_bag} as the
Will topic name to define Will messages to be forwarded as a telemetry message. In this case, if the network
connection is closed, but a DISCONNECT packet was not previously received from the device, then IoT Hub sends
the Will message supplied in the CONNECT packet to the telemetry channel. The telemetry channel can be either
the default Events endpoint or a custom endpoint defined by IoT Hub routing. The message has the iothub-
MessageType property with a value of Will assigned to it.
TLS/SSL configuration
To use the MQTT protocol directly, your client must connect over TLS/SSL. Attempts to skip this step fail with
connection errors.
In order to establish a TLS connection, you may need to download and reference the DigiCert Baltimore Root
Certificate. This certificate is the one that Azure uses to secure the connection. You can find this certificate in the
Azure-iot-sdk-c repository. More information about these certificates can be found on Digicert's website.
An example of how to implement this using the Python version of the Paho MQTT library by the Eclipse
Foundation might look like the following.
First, install the Paho library from your command-line environment:

pip install paho-mqtt

Then, implement the client in a Python script. Replace the placeholders as follows:
<local path to digicert.cer> is the path to a local file that contains the DigiCert Baltimore Root certificate. You
can create this file by copying the certificate information from certs.c in the Azure IoT SDK for C. Include the
lines -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- , remove the " marks at the beginning and
end of every line, and remove the \r\n characters at the end of every line.
<device id from device registry> is the ID of a device you added to your IoT hub.
<generated SAS token> is a SAS token for the device created as described previously in this article.
<iot hub name> the name of your IoT hub.
from paho.mqtt import client as mqtt
import ssl

path_to_root_cert = "<local path to digicert.cer>"


device_id = "<device id from device registry>"
sas_token = "<generated SAS token>"
iot_hub_name = "<iot hub name>"

def on_connect(client, userdata, flags, rc):


print ("Device connected with result code: " + str(rc))
def on_disconnect(client, userdata, rc):
print ("Device disconnected with result code: " + str(rc))
def on_publish(client, userdata, mid):
print ("Device sent message")

client = mqtt.Client(client_id=device_id, protocol=mqtt.MQTTv311)

client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish

client.username_pw_set(username=iot_hub_name+".azure-devices.net/" + device_id, password=sas_token)

client.tls_set(ca_certs=path_to_root_cert, certfile=None, keyfile=None, cert_reqs=ssl.CERT_REQUIRED,


tls_version=ssl.PROTOCOL_TLSv1, ciphers=None)
client.tls_insecure_set(False)

client.connect(iot_hub_name+".azure-devices.net", port=8883)

client.publish("devices/" + device_id + "/messages/events/", "{id=123}", qos=1)


client.loop_forever()

Sending device -to -cloud messages


After making a successful connection, a device can send messages to IoT Hub using
devices/{device_id}/messages/events/ or devices/{device_id}/messages/events/{property_bag} as a Topic Name.
The {property_bag} element enables the device to send messages with additional properties in a url-encoded
format. For example:

RFC 2396-encoded(<PropertyName1>)=RFC 2396-encoded(<PropertyValue1>)&RFC 2396-encoded(<PropertyName2>)=RFC


2396-encoded(<PropertyValue2>)…

NOTE
This {property_bag} element uses the same encoding as for query strings in the HTTPS protocol.

The following is a list of IoT Hub implementation-specific behaviors:


IoT Hub does not support QoS 2 messages. If a device app publishes a message with QoS 2, IoT Hub closes the
network connection.
IoT Hub does not persist Retain messages. If a device sends a message with the RETAIN flag set to 1, IoT Hub
adds the x-opt-retain application property to the message. In this case, instead of persisting the retain message,
IoT Hub passes it to the backend app.
IoT Hub only supports one active MQTT connection per device. Any new MQTT connection on behalf of the
same device ID causes IoT Hub to drop the existing connection.
For more information, see Messaging developer's guide.
Receiving cloud-to -device messages
To receive messages from IoT Hub, a device should subscribe using devices/{device_id}/messages/devicebound/# as
a Topic Filter. The multi-level wildcard # in the Topic Filter is used only to allow the device to receive additional
properties in the topic name. IoT Hub does not allow the usage of the # or ? wildcards for filtering of subtopics.
Since IoT Hub is not a general-purpose pub-sub messaging broker, it only supports the documented topic names
and topic filters.
The device does not receive any messages from IoT Hub, until it has successfully subscribed to its device-specific
endpoint, represented by the devices/{device_id}/messages/devicebound/# topic filter. After a subscription has been
established, the device receives cloud-to-device messages that were sent to it after the time of the subscription. If
the device connects with CleanSession flag set to 0, the subscription is persisted across different sessions. In this
case, the next time the device connects with CleanSession 0 it receives any outstanding messages sent to it while
disconnected. If the device uses CleanSession flag set to 1 though, it does not receive any messages from IoT Hub
until it subscribes to its device-endpoint.
IoT Hub delivers messages with the Topic Name devices/{device_id}/messages/devicebound/, or
devices/{device_id}/messages/devicebound/{property_bag} when there are message properties. {property_bag}
contains url-encoded key/value pairs of message properties. Only application properties and user-settable system
properties (such as messageId or correlationId) are included in the property bag. System property names have
the prefix $, application properties use the original property name with no prefix.
When a device app subscribes to a topic with QoS 2, IoT Hub grants maximum QoS level 1 in the SUBACK packet.
After that, IoT Hub delivers messages to the device using QoS 1.
Retrieving a device twin's properties
First, a device subscribes to $iothub/twin/res/# , to receive the operation's responses. Then, it sends an empty
message to topic $iothub/twin/GET/?$rid={request id} , with a populated value for request ID. The service then
sends a response message containing the device twin data on topic $iothub/twin/res/{status}/?$rid={request id} ,
using the same request ID as the request.
Request ID can be any valid value for a message property value, as per IoT Hub messaging developer's guide, and
status is validated as an integer.
The response body contains the properties section of the device twin. The following snippet shows the body of the
identity registry entry limited to the "properties" member, for example:

{
"properties": {
"desired": {
"telemetrySendFrequency": "5m",
"$version": 12
},
"reported": {
"telemetrySendFrequency": "5m",
"batteryLevel": 55,
"$version": 123
}
}
}

The possible status codes are:

STATUS DESCRIPTION

200 Success

429 Too many requests (throttled), as per IoT Hub throttling


STATUS DESCRIPTION

5** Server errors

For more information, see Device twins developer's guide.


Update device twin's reported properties
The following sequence describes how a device updates the reported properties in the device twin in IoT Hub:
1. A device must first subscribe to the $iothub/twin/res/# topic to receive the operation's responses from IoT
Hub.
2. A device sends a message that contains the device twin update to the
$iothub/twin/PATCH/properties/reported/?$rid={request id} topic. This message includes a request ID value.

3. The service then sends a response message that contains the new ETag value for the reported properties
collection on topic $iothub/twin/res/{status}/?$rid={request id} . This response message uses the same
request ID as the request.
The request message body contains a JSON document, that contains new values for reported properties. Each
member in the JSON document updates or add the corresponding member in the device twin’s document. A
member set to null , deletes the member from the containing object. For example:

{
"telemetrySendFrequency": "35m",
"batteryLevel": 60
}

The possible status codes are:

STATUS DESCRIPTION

200 Success

400 Bad Request. Malformed JSON

429 Too many requests (throttled), as per IoT Hub throttling

5** Server errors

For more information, see Device twins developer's guide.


Receiving desired properties update notifications
When a device is connected, IoT Hub sends notifications to the topic
$iothub/twin/PATCH/properties/desired/?$version={new version} , which contain the content of the update performed
by the solution back end. For example:

{
"telemetrySendFrequency": "5m",
"route": null
}

As for property updates, null values means that the JSON object member is being deleted.
IMPORTANT
IoT Hub generates change notifications only when devices are connected. Make sure to implement the device reconnection
flow to keep the desired properties synchronized between IoT Hub and the device app.

For more information, see Device twins developer's guide.


Respond to a direct method
First, a device has to subscribe to $iothub/methods/POST/# . IoT Hub sends method requests to the topic
$iothub/methods/POST/{method name}/?$rid={request id} , with either a valid JSON or an empty body.
To respond, the device sends a message with a valid JSON or empty body to the topic
$iothub/methods/res/{status}/?$rid={request id} . In this message, the request ID must match the one in the
request message, and status must be an integer.
For more information, see Direct method developer's guide.
Additional considerations
As a final consideration, if you need to customize the MQTT protocol behavior on the cloud side, you should review
the Azure IoT protocol gateway. This software enables you to deploy a high-performance custom protocol gateway
that interfaces directly with IoT Hub. The Azure IoT protocol gateway enables you to customize the device protocol
to accommodate brownfield MQTT deployments or other custom protocols. This approach does require, however,
that you run and operate a custom protocol gateway.

Next steps
To learn more about the MQTT protocol, see the MQTT documentation.
To learn more about planning your IoT Hub deployment, see:
Azure Certified for IoT device catalog
Support additional protocols
Compare with Event Hubs
Scaling, HA, and DR
To further explore the capabilities of IoT Hub, see:
IoT Hub developer guide
Deploying AI to edge devices with Azure IoT Edge
Glossary of IoT Hub terms
5/29/2018 • 19 min to read • Edit Online

This article lists some of the common terms used in the IoT Hub articles.

Advanced Message Queueing Protocol


Advanced Message Queueing Protocol (AMQP ) is one of the messaging protocols that IoT Hub supports for
communicating with devices. For more information about the messaging protocols that IoT Hub supports, see
Send and receive messages with IoT Hub.

Automatic Device Management


Automatic Device Management in Azure IoT Hub automates many of the repetitive and complex tasks of managing
large device fleets over the entirety of their lifecycles. With Automatic Device Management, you can target a set of
devices based on their properties, define a desired configuration, and let IoT Hub update devices whenever they
come into scope. Consists of automatic device configurations and IoT Edge automatic deployments.

Automatic device configuration


Your solution back end can use automatic device configurations to assign desired properties to a set of device twins
and report status using system metrics and custom metrics.

Azure CLI
The Azure CLI is a cross-platform, open-source, shell-based, command tool for creating and managing resources in
Microsoft Azure. This version of the CLI is implemented using Node.js.

Azure CLI 2.0


The Azure CLI 2.0 is a cross-platform, open-source, shell-based, command tool for creating and managing
resources in Microsoft Azure. This preview version of the CLI is implemented using Python.

Azure IoT device SDKs


There are device SDKs available for multiple languages that enable you to create device apps that interact with an
IoT hub. The IoT Hub tutorials show you how to use these device SDKs. You can find the source code and further
information about the device SDKs in this GitHub repository.

Azure IoT service SDKs


There are service SDKs available for multiple languages that enable you to create back-end apps that interact with
an IoT hub. The IoT Hub tutorials show you how to use these service SDKs. You can find the source code and
further information about the service SDKs in this GitHub repository.

Azure portal
The Microsoft Azure portal is a central place where you can provision and manage your Azure resources. It
organizes its content using blades.
Azure PowerShell
Azure PowerShell is a collection of cmdlets you can use to manage Azure with Windows PowerShell. You can use
the cmdlets to create, test, deploy, and manage solutions and services delivered through the Azure platform.

Azure Resource Manager


Azure Resource Manager enables you to work with the resources in your solution as a group. You can deploy,
update, or delete the resources for your solution in a single, coordinated operation.

Azure Service Bus


Service Bus provides cloud-enabled communication with enterprise messaging and relayed communication that
helps you connect on-premises solutions with the cloud. Some IoT Hub tutorials make use Service Bus queues.

Azure Storage
Azure Storage is a cloud storage solution. It includes the Blob Storage service that you can use to store
unstructured object data. Some IoT Hub tutorials use blob storage.

Back-end app
In the context of IoT Hub, a back-end app is an app that connects to one of the service-facing endpoints on an IoT
hub. For example, a back-end app might retrieve device-to-cloudmessages or manage the identity registry.
Typically, a back-end app runs in the cloud, but in many of the tutorials the back-end apps are console apps running
on your local development machine.

Built-in endpoints
Every IoT hub includes a built-in endpoint that is Event Hub-compatible. You can use any mechanism that works
with Event Hubs to read device-to-cloud messages from this endpoint.

Cloud gateway
A cloud gateway enables connectivity for devices that cannot connect directly to IoT Hub. A cloud gateway is
hosted in the cloud in contrast to a field gateway that runs local to your devices. A typical use case for a cloud
gateway is to implement protocol translation for your devices.

Cloud-to-device
Refers to messages sent from an IoT hub to a connected device. Often, these messages are commands that instruct
the device to take an action. For more information, see Send and receive messages with IoT Hub.

Configuration
In the context of automatic device configuration, a configuration within IoT Hub defines the desired configuration
for a set of devices twins and provides a set of metrics to report status and progress.

Connection string
You use connection strings in your app code to encapsulate the information required to connect to an endpoint. A
connection string typically includes the address of the endpoint and security information, but connection string
formats vary across services. There are two types of connection string associated with the IoT Hub service:
Device connection strings enable devices to connect to the device-facing endpoints on an IoT hub.
IoT Hub connection strings enable back-end apps to connect to the service-facing endpoints on an IoT hub.

Custom endpoints
You can create custom endpoints on an IoT hub to deliver messages dispatched by a routing rule. Custom
endpoints connect directly to an Event hub, a Service Bus queue, or a Service Bus topic.

Custom gateway
A gateway enables connectivity for devices that cannot connect directly to IoT Hub. You can use Azure IoT Edge to
build custom gateways that implement custom logic to handle messages, custom protocol conversions, and other
processing on the edge.

Data-point message
A data-point message is a device-to-cloud message that contains telemetry data such as wind speed or
temperature.

Desired configuration
In the context of a device twin, desired configuration refers to the complete set of properties and metadata in the
device twin that should be synchronized with the device.

Desired properties
In the context of a device twin, desired properties is a subsection of the device twin that is used with reported
properties to synchronize device configuration or condition. Desired properties can only be set by a back-end app
and are observed by the device app.

Device-to-cloud
Refers to messages sent from a connected device to IoT Hub. These messages may be data-point or interactive
messages. For more information, see Send and receive messages with IoT Hub.

Device
In the context of IoT, a device is typically a small-scale, standalone computing device that may collect data or control
other devices. For example, a device might be an environmental monitoring device, or a controller for the watering
and ventilation systems in a greenhouse. The device catalog provides a list of hardware devices certified to work
with IoT Hub.

Device app
A device app runs on your device and handles the communication with your IoT hub. Typically, you use one of the
Azure IoT device SDKs when you implement a device app. In many of the IoT tutorials, you use a simulated device
for convenience.

Device condition
Refers to device state information, such as the connectivity method currently in use, as reported by a device app.
Device apps can also report their capabilities. You can query for condition and capability information using device
twins.
Device data
Device data refers to the per-device data stored in the IoT Hub identity registry. It is possible to import and export
this data.

Device explorer
The device explorer is a tool that runs on Windows and enables you to manage your devices in the identity
registry.The tool can also send and receive messages to your devices.

Device Identities REST API


The Device Identities REST API enables you to manage your devices registered in the identity registry using a
REST API. Typically, you should use one of the higher-level service SDKs as shown in the IoT Hub tutorials.

Device identity
The device identity is the unique identifier assigned to every device registered in the identity registry.

Module identity
The module identity is the unique identifier assigned to every module that belong to a device. Module identity is
also registered in the identity registry.

Device management
Device management encompasses the full lifecycle associated with managing the devices in your IoT solution
including planning, provisioning, configuring, monitoring, and retiring.

Device management patterns


IoT hub enables common device management patterns including rebooting, performing factory resets, and
performing firmware updates on your devices.

Device Messaging REST API


You can use the Device Messaging REST API from a device to send device-to-cloud messages to an IoT hub, and
receive cloud-to-device messages from an IoT hub. Typically, you should use one of the higher-level device SDKs as
shown in the IoT Hub tutorials.

Device provisioning
Device provisioning is the process of adding the initial device data to the stores in your solution. To enable a new
device to connect to your hub, you must add a device ID and keys to the IoT Hub identity registry. As part of the
provisioning process, you might need to initialize device-specific data in other solution stores.

Device twin
A device twin is JSON document that stores device state information such as metadata, configurations, and
conditions. IoT Hub persists a device twin for each device that you provision in your IoT hub. Device twins enable
you to synchronize device conditions and configurations between the device and the solution back end. You can
query device twins to locate specific devices and query the status of long-running operations.
Module twin
Similar to device twin, a module twin is JSON document that stores module state information such as metadata,
configurations, and conditions. IoT Hub persists a module twin for each module identity that you provision under a
device identity in your IoT hub. Module twins enable you to synchronize module conditions and configurations
between the module and the solution back end. You can query module twins to locate specific modules and query
the status of long-running operations.

Twin queries
Device and module twin queries use the SQL -like IoT Hub query language to retrieve information from your
device twins or module twins. You can use the same IoT Hub query language to retrieve information about jobs
running in your IoT hub.

Device Twin REST API


You can use the Device Twin REST API from the solution back end to manage your device twins. The API enables
you to retrieve and update device twin properties and invoke direct methods. Typically, you should use one of the
higher-level service SDKs as shown in the IoT Hub tutorials.

Twin synchronization
Twin synchronization uses the desired properties in your device twins or module twins to configure your devices or
modules and retrieve reported properties from them to store in the twin.

Direct method
A direct method is a way for you to trigger a method to execute on a device by invoking an API on your IoT hub.

Endpoint
An IoT hub exposes multiple endpoints that enable your apps to connect to the IoT hub. There are device-facing
endpoints that enable devices to perform operations such as sending device-to-cloud messages and receiving
cloud-to-device messages. There are service-facing management endpoints that enable back-end apps to perform
operations such as device identity management and device twin management. There are service-facing built-in
endpoints for reading device-to-cloud messages. You can create custom endpoints to receive device-to-cloud
messages dispatched by a routing rule.

Event Hubs service


Event Hubs is a highly scalable data ingress service that can ingest millions of events per second. The service
enables you to process and analyze the massive amounts of data produced by your connected devices and
applications. For a comparison with the IoT Hub service, see Comparison of Azure IoT Hub and Azure Event Hubs.

Event Hub-compatible endpoint


To read device-to-cloud messages sent to your IoT hub, you can connect to an endpoint on your hub and use any
Event Hub-compatible method to read those messages. Event Hub-compatible methods include using the Event
Hubs SDKs and Azure Stream Analytics.

Field gateway
A field gateway enables connectivity for devices that cannot connect directly to IoT Hub and is typically deployed
locally with your devices. For more information, see What is Azure IoT Hub?
Free account
You can create a free Azure account to complete the IoT Hub tutorials and experiment with the IoT Hub service
(and other Azure services).

Gateway
A gateway enables connectivity for devices that cannot connect directly to IoT Hub. See also Field Gateway, Cloud
Gateway, and Custom Gateway.

Identity registry
The identity registry is the built-in component of an IoT hub that stores information about the individual devices
permitted to connect to an IoT hub.

Interactive message
An interactive message is a cloud-to-device message that triggers an immediate action in the solution back end. For
example, a device might send an alarm about a failure that should be automatically logged in to a CRM system.

Automatic Device Management


Automatic Device Management in Azure IoT Hub automates many of the repetitive and complex tasks of managing
large device fleets over the entirety of their lifecycles. With Automatic Device Management, you can target a set of
devices based on their properties, define a desired configuration, and let IoT Hub update devices whenever they
come into scope. Consists of automatic device configurations and IoT Edge automatic deployments.

IoT Edge
Azure IoT Edge enables cloud-driven deployment of Azure services and solution-specific code to on-premises
devices. IoT Edge devices can aggregate data from other devices to perform computing and analytics before the
data is sent to the cloud. For more information please see Azure IoT Edge.

IoT Edge agent


The part of the IoT Edge runtime responsible for deploying and monitoring modules.

IoT Edge device


IoT Edge devices have the IoT Edge runtime installed and are flagged as “IoT Edge device” in the device details.
Learn how to deploy Azure IoT Edge on a simulated device in Linux - preview.

IoT Edge automatic deployment


An IoT Edge automatic deployment configures a target set of IoT Edge devices to run a set of IoT Edge modules.
Each deployment continuously ensures that all devices that match its target condition are running the specified set
of modules, even when new devices are created or are modified to match the target condition. Each IoT Edge device
only receives the highest priority deployment whose target condition it meets. Learn more about IoT Edge
automatic deployment.

IoT Edge deployment manifest


A Json document containing the information to be copied in one or more IoT Edge devices' module twin(s) to
deploy a set of modules, routes and associated module desired properties.
IoT Edge gateway device
An IoT Edge device with downstream device. The downstream device can be either IoT Edge or not IoT Edge
device.

IoT Edge hub


The part of the IoT Edge runtime responsible for module to module communications, upstream (toward IoT Hub)
and downstream (away from IoT Hub) communications.

IoT Edge leaf device


An IoT Edge device with no downstream device.

IoT Edge module


An IoT Edge module is a Docker container that you can deploy to IoT Edge devices. It performs a specific task, such
as ingesting a message from a device, transforming a message, or sending a message to an IoT hub. It
communicates with other modules and sends data to the IoT Edge runtime. Understand the requirements and tools
for developing IoT Edge modules.

IoT Edge module identity


A record in the IoT Hub module identity registry detailing the existence and security credentials to be used by a
module to authenticate with an edge hub or IoT Hub.

IoT Edge module image


The docker image that is used by the IoT Edge runtime to instantiate module instances.

IoT Edge module twin


A Json document persisted in the IoT Hub that stores the state information for a module instance.

IoT Edge priority


When two IoT Edge deployments target the same device, the deployment with higher priority gets applied. If two
deployments have the same priority, the deployment with the later creation date gets applied. Learn more about
priority.

IoT Edge runtime


IoT Edge runtime includes everything that Microsoft distributes to be installed on an IoT Edge device. It included
Edge agent, Edge hub and Edge CTL tool.

IoT Edge set modules to a single device


An operation that copies the content of an IoT Edge manifest on one device' module twin. The underlying API is a
generic 'apply configuration', which simply takes an IoT Edge manifest as an input.

IoT Edge target condition


In an IoT Edge deployment, Target condition is any Boolean condition on device twins’ tags to select the target
devices of the deployment, e.g. "tag.environment = prod". The target condition is continuously evaluated to include
any new devices that meet the requirements or remove devices that no longer do. Learn more about target
condition

IoT Hub
IoT Hub is a fully managed Azure service that enables reliable and secure bidirectional communications between
millions of devices and a solution back end. For more information, see What is Azure IoT Hub? Using your Azure
subscription, you can create IoT hubs to handle your IoT messaging workloads.

IoT Hub metrics


IoT Hub metrics give you data about the state of the IoT hubs in your Azure subscription. IoT Hub metrics enable
you to assess the overall health of the service and the devices connected to it. IoT Hub metrics can help you see
what is going on with your IoT hub and investigate root-cause issues without needing to contact Azure support.

IoT Hub query language


The IoT Hub query language is a SQL -like language that enables you to query your jobs and device twins.

IoT Hub Resource Provider REST API


You can use the IoT Hub Resource Provider REST API to manage the IoT hubs in your Azure subscription
performing operations such as creating, updating, and deleting hubs.

IoT solution accelerators


Azure IoT solution accelerators package together multiple Azure services into solutions. These solutions enable you
to get started quickly with end-to-end implementations of common IoT scenarios. For more information, see What
are Azure IoT solution accelerators?

The IoT extension for Azure CLI 2.0


The IoT extension for Azure CLI 2.0 is a cross-platform, command-line tool. The tool enables you to manage your
devices in the identity registry, send and receive messages and files from your devices, and monitor your IoT hub
operations.

Job
Your solution back end can use jobs to schedule and track activities on a set of devices registered with your IoT hub.
Activities include updating device twin desired properties, updating device twin tags, and invoking direct methods.
IoT Hub also uses jobs to import to and export from the identity registry.

Jobs REST API


The Jobs REST API enables you to manage jobs running in your IoT hub.

MQTT
MQTT is one of the messaging protocols that IoT Hub supports for communicating with devices. For more
information about the messaging protocols that IoT Hub supports, see Send and receive messages with IoT Hub.

Operations monitoring
IoT Hub operations monitoring enables you to monitor the status of operations on your IoT hub in real time. IoT
Hub tracks events across several categories of operations. You can opt into sending events from one or more
categories to an IoT Hub endpoint for processing. You can monitor the data for errors or set up more complex
processing based on data patterns.

Physical device
A physical device is a real device such as a Raspberry Pi that connects to an IoT hub. For convenience, many of the
IoT Hub tutorials use simulated devices to enable you to run samples on your local machine.

Primary and secondary keys


When you connect to a device-facing or service-facing endpoint on an IoT hub, your connection string includes key
to grant you access. When you add a device to the identity registry or add a shared access policy to your hub, the
service generates a primary and secondary key. Having two keys enables you to roll over from one key to another
when you update a key without losing access to the IoT hub.

Protocol gateway
A protocol gateway is typically deployed in the cloud and provides protocol translation services for devices
connecting to IoT Hub. For more information, see What is Azure IoT Hub?

Quotas and throttling


There are various quotas that apply to your use of IoT Hub, many of the quotas vary based on the tier of the IoT
hub. IoT Hub also applies throttles to your use of the service at run time.

Reported configuration
In the context of a device twin, reported configuration refers to the complete set of properties and metadata in the
device twin that should be reported to the solution back end.

Reported properties
In the context of a device twin, reported properties is a subsection of the device twin used with desired properties
to synchronize device configuration or condition. Reported properties can only be set by the device app and can be
read and queried by a back-end app.

Resource group
Azure Resource Manager uses resource groups to group related resources together. You can use a resource group
to perform operations on all the resources on the group simultaneously.

Retry policy
You use a retry policy to handle transient errors when you connect to a cloud service.

Routing rules
You configure routing rules in your IoT hub to route device-to-cloud messages to a built-in endpoint or to custom
endpoints for processing by your solution back end.

SASL PLAIN
SASL PL AIN is a protocol that the AMQP protocol uses to transfer security tokens.
Shared access signature
Shared Access Signatures (SAS ) are an authentication mechanism based on SHA-256 secure hashes or URIs. SAS
authentication has two components: a Shared Access Policy and a Shared Access Signature (often called a token). A
device uses SAS to authenticate with an IoT hub. Back-end apps also use SAS to authenticate with the service-
facing endpoints on an IoT hub. Typically, you include the SAS token in the connection string that an app uses to
establish a connection to an IoT hub.

Shared access policy


A shared access policy defines the permissions granted to anyone who has a valid primary or secondary key
associated with that policy. You can manage the shared access policies and keys for your hub in the portal.

Simulated device
For convenience, many of the IoT Hub tutorials use simulated devices to enable you to run samples on your local
machine. In contrast, a physical device is a real device such as a Raspberry Pi that connects to an IoT hub.

Solution
A solution can refer to a Visual Studio solution that includes one or more projects. A solution might also refer to an
IoT solution that includes elements such as devices, device apps, an IoT hub, other Azure services, and back-end
apps.

Subscription
An Azure subscription is where billing takes place. Each Azure resource you create or Azure service you use is
associated with a single subscription. Many quotas also apply at the level of a subscription.

System properties
In the context of a device twin, system properties are read-only and include information regarding the device usage
such as last activity time and connection state.

Tags
In the context of a device twin, tags are device metadata stored and retrieved by the solution back end in the form
of a JSON document. Tags are not visible to apps on a device.

Telemetry
Devices collect telemetry data, such as wind speed or temperature, and use data-point messages to send the
telemetry to an IoT hub.

Token service
You can use a token service to implement an authentication mechanism for your devices. It uses an IoT Hub shared
access policy with DeviceConnect permissions to create device-scoped tokens. These tokens enable a device to
connect to your IoT hub. A device uses a custom authentication mechanism to authenticate with the token service.
IF the device authenticates successfully, the token service issues a SAS token for the device to use to access your
IoT hub.

X.509 client certificate


A device can use an X.509 certificate to authenticate with IoT Hub. Using an X.509 certificate is an alternative to
using a SAS token.
1 min to read •
Edit Online
1 min to read •
Edit Online
1 min to read •
Edit Online
1 min to read •
Edit Online
1 min to read •
Edit Online
Azure IoT device SDK for C
5/29/2018 • 17 min to read • Edit Online

The Azure IoT device SDK is a set of libraries designed to simplify the process of sending messages to and
receiving messages from the Azure IoT Hub service. There are different variations of the SDK, each targeting a
specific platform, but this article describes the Azure IoT device SDK for C.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are only
available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to choose
the right IoT Hub tier.

The Azure IoT device SDK for C is written in ANSI C (C99) to maximize portability. This feature makes the libraries
well-suited to operate on multiple platforms and devices, especially where minimizing disk and memory footprint is
a priority.
There are a broad range of platforms on which the SDK has been tested (see the Azure Certified for IoT device
catalog for details). Although this article includes walkthroughs of sample code running on the Windows platform,
the code described in this article is identical across the range of supported platforms.
The following video presents an overview of the Azure IoT SDK for C:

This article introduces you to the architecture of the Azure IoT device SDK for C. It demonstrates how to initialize
the device library, send data to IoT Hub, and receive messages from it. The information in this article should be
enough to get started using the SDK, but also provides pointers to additional information about the libraries.

SDK architecture
You can find the Azure IoT device SDK for C GitHub repository and view details of the API in the C API
reference.
The latest version of the libraries can be found in the master branch of the repository:
The core implementation of the SDK is in the iothub_client folder that contains the implementation of the
lowest API layer in the SDK: the IoTHubClient library. The IoTHubClient library contains APIs implementing
raw messaging for sending messages to IoT Hub and receiving messages from IoT Hub. When using this
library, you are responsible for implementing message serialization, but other details of communicating with IoT
Hub are handled for you.
The serializer folder contains helper functions and samples that show you how to serialize data before sending
to Azure IoT Hub using the client library. The use of the serializer is not mandatory and is provided as a
convenience. To use the serializer library, you define a model that specifies the data to send to IoT Hub and the
messages you expect to receive from it. Once the model is defined, the SDK provides you with an API surface
that enables you to easily work with device-to-cloud and cloud-to-device messages without worrying about the
serialization details. The library depends on other open source libraries that implement transport using
protocols such as MQTT and AMQP.
The IoTHubClient library depends on other open source libraries:
The Azure C shared utility library, which provides common functionality for basic tasks (such as strings,
list manipulation, and IO ) needed across several Azure-related C SDKs.
The Azure uAMQP library, which is a client-side implementation of AMQP optimized for resource
constrained devices.
The Azure uMQTT library, which is a general-purpose library implementing the MQTT protocol and
optimized for resource constrained devices.
Use of these libraries is easier to understand by looking at example code. The following sections walk you through
several of the sample applications that are included in the SDK. This walkthrough should give you a good feel for
the various capabilities of the architectural layers of the SDK and an introduction to how the APIs work.
Before you run the samples
Before you can run the samples in the Azure IoT device SDK for C, you must create an instance of the IoT Hub
service in your Azure subscription. Then complete the following tasks:
Prepare your development environment
Obtain device credentials.
Prepare your development environment
Packages are provided for common platforms (such as NuGet for Windows or apt_get for Debian and Ubuntu) and
the samples use these packages when available. In some cases, you need to compile the SDK for or on your device.
If you need to compile the SDK, see Prepare your development environment in the GitHub repository.
To obtain the sample application code, download a copy of the SDK from GitHub. Get your copy of the source from
the master branch of the GitHub repository.
Obtain the device credentials
Now that you have the sample source code, the next thing to do is to get a set of device credentials. For a device to
be able to access an IoT hub, you must first add the device to the IoT Hub identity registry. When you add your
device, you get a set of device credentials that you need for the device to be able to connect to the IoT hub. The
sample applications discussed in the next section expect these credentials in the form of a device connection
string.
There are several open source tools to help you manage your IoT hub.
A Windows application called device explorer.
A cross-platform Python CLI tool called the IoT extension for Azure CLI 2.0.
This tutorial uses the graphical device explorer tool. You can also use the the IoT extension for Azure CLI 2.0 tool if
you prefer to use a CLI tool.
The device explorer tool uses the Azure IoT service libraries to perform various functions on IoT Hub, including
adding devices. If you use the device explorer tool to add a device, you get a connection string for your device. You
need this connection string to run the sample applications.
If you're not familiar with the device explorer tool, the following procedure describes how to use it to add a device
and obtain a device connection string.
To install the device explorer tool, see How to use the Device Explorer for IoT Hub devices.
When you run the program, you see this interface:
Enter your IoT Hub Connection String in the first field and click Update. This step configures the tool so that it
can communicate with IoT Hub.
When the IoT Hub connection string is configured, click the Management tab:
This tab is where you manage the devices registered in your IoT hub.
You create a device by clicking the Create button. A dialog displays with a set of pre-populated keys (primary and
secondary). Enter a Device ID and then click Create.

When the device is created, the Devices list updates with all the registered devices, including the one you just
created. If you right-click your new device, you see this menu:
If you choose Copy connection string for selected device, the device connection string is copied to the
clipboard. Keep a copy of the device connection string. You need it when running the sample applications described
in the following sections.
When you've completed the steps above, you're ready to start running some code. Both samples have a constant at
the top of the main source file that enables you to enter a connection string. For example, the corresponding line
from the iothub_client_sample_mqtt application appears as follows.

static const char* connectionString = "[device connection string]";

Use the IoTHubClient library


Within the iothub_client folder in the azure-iot-sdk-c repository, there is a samples folder that contains an
application called iothub_client_sample_mqtt.
The Windows version of the iothub_client_sample_mqtt application includes the following Visual Studio
solution:
NOTE
If you open this project in Visual Studio 2017, accept the prompts to retarget the project to the latest version.

This solution contains a single project. There are four NuGet packages installed in this solution:
Microsoft.Azure.C.SharedUtility
Microsoft.Azure.IoTHub.MqttTransport
Microsoft.Azure.IoTHub.IoTHubClient
Microsoft.Azure.umqtt
You always need the Microsoft.Azure.C.SharedUtility package when you are working with the SDK. This sample
uses the MQTT protocol, therefore you must include the Microsoft.Azure.umqtt and
Microsoft.Azure.IoTHub.MqttTransport packages (there are equivalent packages for AMQP and HTTPS ).
Because the sample uses the IoTHubClient library, you must also include the
Microsoft.Azure.IoTHub.IoTHubClient package in your solution.
You can find the implementation for the sample application in the iothub_client_sample_mqtt.c source file.
The following steps use this sample application to walk you through what's required to use the IoTHubClient
library.
Initialize the library

NOTE
Before you start working with the libraries, you may need to perform some platform-specific initialization. For example, if you
plan to use AMQP on Linux you must initialize the OpenSSL library. The samples in the GitHub repository call the utility
function platform_init when the client starts and call the platform_deinit function before exiting. These functions are
declared in the platform.h header file. Examine the definitions of these functions for your target platform in the repository to
determine whether you need to include any platform-specific initialization code in your client.

To start working with the libraries, first allocate an IoT Hub client handle:
if ((iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, MQTT_Protocol)) == NULL)
{
(void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
}
else
{
...

You pass a copy of the device connection string you obtained from the device explorer tool to this function. You also
designate the communications protocol to use. This example uses MQTT, but AMQP and HTTPS are also options.
When you have a valid IOTHUB_CLIENT_HANDLE, you can start calling the APIs to send and receive messages
to and from IoT Hub.
Send messages
The sample application sets up a loop to send messages to your IoT hub. The following snippet:
Creates a message.
Adds a property to the message.
Sends a message.
First, create a message:

size_t iterator = 0;
do
{
if (iterator < MESSAGE_COUNT)
{
sprintf_s(msgText, sizeof(msgText), "{\"deviceId\":\"myFirstDevice\",\"windSpeed\":%.2f}", avgWindSpeed
+ (rand() % 4 + 2));
if ((messages[iterator].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned
char*)msgText, strlen(msgText))) == NULL)
{
(void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
}
else
{
messages[iterator].messageTrackingId = iterator;
MAP_HANDLE propMap = IoTHubMessage_Properties(messages[iterator].messageHandle);
(void)sprintf_s(propText, sizeof(propText), "PropMsg_%zu", iterator);
if (Map_AddOrUpdate(propMap, "PropName", propText) != MAP_OK)
{
(void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
}

if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messages[iterator].messageHandle,
SendConfirmationCallback, &messages[iterator]) != IOTHUB_CLIENT_OK)
{
(void)printf("ERROR: IoTHubClient_LL_SendEventAsync..........FAILED!\r\n");
}
else
{
(void)printf("IoTHubClient_LL_SendEventAsync accepted message [%d] for transmission to IoT
Hub.\r\n", (int)iterator);
}
}
}
IoTHubClient_LL_DoWork(iotHubClientHandle);
ThreadAPI_Sleep(1);

iterator++;
} while (g_continueRunning);
Every time you send a message, you specify a reference to a callback function that's invoked when the data is sent.
In this example, the callback function is called SendConfirmationCallback. The following snippet shows this
callback function:

static void SendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)


{
EVENT_INSTANCE* eventInstance = (EVENT_INSTANCE*)userContextCallback;
(void)printf("Confirmation[%d] received for message tracking id = %zu with result = %s\r\n",
callbackCounter, eventInstance->messageTrackingId, ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result));
/* Some device specific action code goes here... */
callbackCounter++;
IoTHubMessage_Destroy(eventInstance->messageHandle);
}

Note the call to the IoTHubMessage_Destroy function when you're done with the message. This function frees
the resources allocated when you created the message.
Receive messages
Receiving a message is an asynchronous operation. First, you register the callback to invoke when the device
receives a message:

if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext) !=


IOTHUB_CLIENT_OK)
{
(void)printf("ERROR: IoTHubClient_LL_SetMessageCallback..........FAILED!\r\n");
}
else
{
(void)printf("IoTHubClient_LL_SetMessageCallback...successful.\r\n");
...

The last parameter is a void pointer to whatever you want. In the sample, it's a pointer to an integer but it could be a
pointer to a more complex data structure. This parameter enables the callback function to operate on shared state
with the caller of this function.
When the device receives a message, the registered callback function is invoked. This callback function retrieves:
The message id and correlation id from the message.
The message content.
Any custom properties from the message.
static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, void*
userContextCallback)
{
int* counter = (int*)userContextCallback;
const char* buffer;
size_t size;
MAP_HANDLE mapProperties;
const char* messageId;
const char* correlationId;

// Message properties
if ((messageId = IoTHubMessage_GetMessageId(message)) == NULL)
{
messageId = "<null>";
}

if ((correlationId = IoTHubMessage_GetCorrelationId(message)) == NULL)


{
correlationId = "<null>";
}

// Message content
if (IoTHubMessage_GetByteArray(message, (const unsigned char**)&buffer, &size) != IOTHUB_MESSAGE_OK)
{
(void)printf("unable to retrieve the message data\r\n");
}
else
{
(void)printf("Received Message [%d]\r\n Message ID: %s\r\n Correlation ID: %s\r\n Data: <<<%.*s>>> &
Size=%d\r\n", *counter, messageId, correlationId, (int)size, buffer, (int)size);
// If we receive the work 'quit' then we stop running
if (size == (strlen("quit") * sizeof(char)) && memcmp(buffer, "quit", size) == 0)
{
g_continueRunning = false;
}
}

// Retrieve properties from the message


mapProperties = IoTHubMessage_Properties(message);
if (mapProperties != NULL)
{
const char*const* keys;
const char*const* values;
size_t propertyCount = 0;
if (Map_GetInternals(mapProperties, &keys, &values, &propertyCount) == MAP_OK)
{
if (propertyCount > 0)
{
size_t index;

printf(" Message Properties:\r\n");


for (index = 0; index < propertyCount; index++)
{
(void)printf("\tKey: %s Value: %s\r\n", keys[index], values[index]);
}
(void)printf("\r\n");
}
}
}

/* Some device specific action code goes here... */


(*counter)++;
return IOTHUBMESSAGE_ACCEPTED;
}

Use the IoTHubMessage_GetByteArray function to retrieve the message, which in this example is a string.
Uninitialize the library
When you're done sending events and receiving messages, you can uninitialize the IoT library. To do so, issue the
following function call:

IoTHubClient_LL_Destroy(iotHubClientHandle);

This call frees up the resources previously allocated by the IoTHubClient_CreateFromConnectionString


function.
As you can see, it's easy to send and receive messages with the IoTHubClient library. The library handles the
details of communicating with IoT Hub, including which protocol to use (from the perspective of the developer, this
is a simple configuration option).
The IoTHubClient library also provides precise control over how to serialize the data your device sends to IoT
Hub. In some cases this level of control is an advantage, but in others it is an implementation detail that you don't
want to be concerned with. If that's the case, you might consider using the serializer library, which is described in
the next section.

Use the serializer library


Conceptually the serializer library sits on top of the IoTHubClient library in the SDK. It uses the IoTHubClient
library for the underlying communication with IoT Hub, but it adds modeling capabilities that remove the burden of
dealing with message serialization from the developer. How this library works is best demonstrated by an example.
Inside the serializer folder in the azure-iot-sdk-c repository, is a samples folder that contains an application called
simplesample_mqtt. The Windows version of this sample includes the following Visual Studio solution:

NOTE
If you open this project in Visual Studio 2017, accept the prompts to retarget the project to the latest version.

As with the previous sample, this one includes several NuGet packages:
Microsoft.Azure.C.SharedUtility
Microsoft.Azure.IoTHub.MqttTransport
Microsoft.Azure.IoTHub.IoTHubClient
Microsoft.Azure.IoTHub.Serializer
Microsoft.Azure.umqtt
You've seen most of these packages in the previous sample, but Microsoft.Azure.IoTHub.Serializer is new. This
package is required when you use the serializer library.
You can find the implementation of the sample application in the simplesample_mqtt.c file.
The following sections walk you through the key parts of this sample.
Initialize the library
To start working with the serializer library, call the initialization APIs:

if (serializer_init(NULL) != SERIALIZER_OK)
{
(void)printf("Failed on serializer_init\r\n");
}
else
{
IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString,
MQTT_Protocol);
srand((unsigned int)time(NULL));
int avgWindSpeed = 10;

if (iotHubClientHandle == NULL)
{
(void)printf("Failed on IoTHubClient_LL_Create\r\n");
}
else
{
ContosoAnemometer* myWeather = CREATE_MODEL_INSTANCE(WeatherStation, ContosoAnemometer);
if (myWeather == NULL)
{
(void)printf("Failed on CREATE_MODEL_INSTANCE\r\n");
}
else
{
...

The call to the serializer_init function is a one-time call and initializes the underlying library. Then, you call the
IoTHubClient_LL_CreateFromConnectionString function, which is the same API as in the IoTHubClient
sample. This call sets your device connection string (this call is also where you choose the protocol you want to
use). This sample uses MQTT as the transport, but could use AMQP or HTTPS.
Finally, call the CREATE_MODEL_INSTANCE function. WeatherStation is the namespace of the model and
ContosoAnemometer is the name of the model. Once the model instance is created, you can use it to start
sending and receiving messages. However, it's important to understand what a model is.
Define the model
A model in the serializer library defines the messages that your device can send to IoT Hub and the messages,
called actions in the modeling language, which it can receive. You define a model using a set of C macros as in the
simplesample_mqtt sample application:
BEGIN_NAMESPACE(WeatherStation);

DECLARE_MODEL(ContosoAnemometer,
WITH_DATA(ascii_char_ptr, DeviceId),
WITH_DATA(int, WindSpeed),
WITH_ACTION(TurnFanOn),
WITH_ACTION(TurnFanOff),
WITH_ACTION(SetAirResistance, int, Position)
);

END_NAMESPACE(WeatherStation);

The BEGIN_NAMESPACE and END_NAMESPACE macros both take the namespace of the model as an
argument. It's expected that anything between these macros is the definition of your model or models, and the data
structures that the models use.
In this example, there is a single model called ContosoAnemometer. This model defines two pieces of data that
your device can send to IoT Hub: DeviceId and WindSpeed. It also defines three actions (messages) that your
device can receive: TurnFanOn, TurnFanOff, and SetAirResistance. Each data element has a type, and each action
has a name (and optionally a set of parameters).
The data and actions defined in the model define an API surface that you can use to send messages to IoT Hub, and
respond to messages sent to the device. Use of this model is best understood through an example.
Send messages
The model defines the data you can send to IoT Hub. In this example, that means one of the two data items defined
using the WITH_DATA macro. There are several steps required to send DeviceId and WindSpeed values to an
IoT hub. The first is to set the data you want to send:

myWeather->DeviceId = "myFirstDevice";
myWeather->WindSpeed = avgWindSpeed + (rand() % 4 + 2);

The model you defined earlier enables you to set the values by setting members of a struct. Next, serialize the
message you want to send:

unsigned char* destination;


size_t destinationSize;
if (SERIALIZE(&destination, &destinationSize, myWeather->DeviceId, myWeather->WindSpeed) != CODEFIRST_OK)
{
(void)printf("Failed to serialize\r\n");
}
else
{
sendMessage(iotHubClientHandle, destination, destinationSize);
free(destination);
}

This code serializes the device-to-cloud to a buffer (referenced by destination). The code then invokes the
sendMessage function to send the message to IoT Hub:
static void sendMessage(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, const unsigned char* buffer, size_t size)
{
static unsigned int messageTrackingId;
IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromByteArray(buffer, size);
if (messageHandle == NULL)
{
printf("unable to create a new IoTHubMessage\r\n");
}
else
{
if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, (void*)
(uintptr_t)messageTrackingId) != IOTHUB_CLIENT_OK)
{
printf("failed to hand over the message to IoTHubClient");
}
else
{
printf("IoTHubClient accepted the message for delivery\r\n");
}
IoTHubMessage_Destroy(messageHandle);
}
messageTrackingId++;
}

The second to last parameter of IoTHubClient_LL_SendEventAsync is a reference to a callback function that's


called when the data is successfully sent. Here's the callback function in the sample:

void sendCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)


{
unsigned int messageTrackingId = (unsigned int)(uintptr_t)userContextCallback;

(void)printf("Message Id: %u Received.\r\n", messageTrackingId);

(void)printf("Result Call Back Called! Result is: %s \r\n",


ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result));
}

The second parameter is a pointer to user context; the same pointer passed to
IoTHubClient_LL_SendEventAsync. In this case, the context is a simple counter, but it can be anything you want.
That's all there is to sending device-to-cloud messages. The only thing left to cover is how to receive messages.
Receive messages
Receiving a message works similarly to the way messages work in the IoTHubClient library. First, you register a
message callback function:

if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, IoTHubMessage, myWeather) != IOTHUB_CLIENT_OK)


{
printf("unable to IoTHubClient_SetMessageCallback\r\n");
}
else
{
...

Then, you write the callback function that's invoked when a message is received:
static IOTHUBMESSAGE_DISPOSITION_RESULT IoTHubMessage(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback)
{
IOTHUBMESSAGE_DISPOSITION_RESULT result;
const unsigned char* buffer;
size_t size;
if (IoTHubMessage_GetByteArray(message, &buffer, &size) != IOTHUB_MESSAGE_OK)
{
printf("unable to IoTHubMessage_GetByteArray\r\n");
result = IOTHUBMESSAGE_ABANDONED;
}
else
{
/*buffer is not zero terminated*/
char* temp = malloc(size + 1);
if (temp == NULL)
{
printf("failed to malloc\r\n");
result = IOTHUBMESSAGE_ABANDONED;
}
else
{
(void)memcpy(temp, buffer, size);
temp[size] = '\0';
EXECUTE_COMMAND_RESULT executeCommandResult = EXECUTE_COMMAND(userContextCallback, temp);
result =
(executeCommandResult == EXECUTE_COMMAND_ERROR) ? IOTHUBMESSAGE_ABANDONED :
(executeCommandResult == EXECUTE_COMMAND_SUCCESS) ? IOTHUBMESSAGE_ACCEPTED :
IOTHUBMESSAGE_REJECTED;
free(temp);
}
}
return result;
}

This code is boilerplate -- it's the same for any solution. This function receives the message and takes care of
routing it to the appropriate function through the call to EXECUTE_COMMAND. The function called at this point
depends on the definition of the actions in your model.
When you define an action in your model, you're required to implement a function that's called when your device
receives the corresponding message. For example, if your model defines this action:

WITH_ACTION(SetAirResistance, int, Position)

Define a function with this signature:

EXECUTE_COMMAND_RESULT SetAirResistance(ContosoAnemometer* device, int Position)


{
(void)device;
(void)printf("Setting Air Resistance Position to %d.\r\n", Position);
return EXECUTE_COMMAND_SUCCESS;
}

Note how the name of the function matches the name of the action in the model and that the parameters of the
function match the parameters specified for the action. The first parameter is always required and contains a
pointer to the instance of your model.
When the device receives a message that matches this signature, the corresponding function is called. Therefore,
aside from having to include the boilerplate code from IoTHubMessage, receiving messages is just a matter of
defining a simple function for each action defined in your model.
Uninitialize the library
When you're done sending data and receiving messages, you can uninitialize the IoT library:

...
DESTROY_MODEL_INSTANCE(myWeather);
}
IoTHubClient_LL_Destroy(iotHubClientHandle);
}
serializer_deinit();

Each of these three functions aligns with the three initialization functions described previously. Calling these APIs
ensures that you free previously allocated resources.

Next Steps
This article covered the basics of using the libraries in the Azure IoT device SDK for C. It provided you with
enough information to understand what's included in the SDK, its architecture, and how to get started working with
the Windows samples. The next article continues the description of the SDK by explaining more about the
IoTHubClient library.
To learn more about developing for IoT Hub, see the Azure IoT SDKs.
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Azure IoT device SDK for C – more about
IoTHubClient
5/29/2018 • 13 min to read • Edit Online

The first article in this series introduced the Azure IoT device SDK for C. That article explained that there are two
architectural layers in SDK. At the base is the IoTHubClient library which directly manages communication with
IoT Hub. There's also the serializer library that builds on top of that to provide serialization services. In this article
we'll provide additional detail on the IoTHubClient library.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are only
available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to choose
the right IoT Hub tier.

The previous article described how to use the IoTHubClient library to send events to IoT Hub and receive
messages. This article extends that discussion by explaining how to more precisely manage when you send and
receive data, introducing you to the lower-level APIs. We'll also explain how to attach properties to events (and
retrieve them from messages) using the property handling features in the IoTHubClient library. Finally, we'll
provide additional explanation of different ways to handle messages received from IoT Hub.
The article concludes by covering a couple of miscellaneous topics, including more about device credentials and
how to change the behavior of the IoTHubClient through configuration options.
We'll use the IoTHubClient SDK samples to explain these topics. If you want to follow along, see the
iothub_client_sample_http and iothub_client_sample_amqp applications that are included in the Azure IoT
device SDK for C. Everything described in the following sections is demonstrated in these samples.
You can find the Azure IoT device SDK for C GitHub repository and view details of the API in the C API
reference.

The lower-level APIs


The previous article described the basic operation of the IotHubClient within the context of the
iothub_client_sample_amqp application. For example, it explained how to initialize the library using this code.

IOTHUB_CLIENT_HANDLE iotHubClientHandle;
iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, AMQP_Protocol);

It also described how to send events using this function call.

IoTHubClient_SendEventAsync(iotHubClientHandle, message.messageHandle, SendConfirmationCallback, &message);

The article also described how to receive messages by registering a callback function.

int receiveContext = 0;
IoTHubClient_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext);
The article also showed how to free resources using code such as the following.

IoTHubClient_Destroy(iotHubClientHandle);

However there are companion functions to each of these APIs:


IoTHubClient_LL_CreateFromConnectionString
IoTHubClient_LL_SendEventAsync
IoTHubClient_LL_SetMessageCallback
IoTHubClient_LL_Destroy
These functions all include “LL” in the API name. Other than that, the parameters of each of these functions are
identical to their non-LL counterparts. However, the behavior of these functions is different in one important way.
When you call IoTHubClient_CreateFromConnectionString, the underlying libraries create a new thread that
runs in the background. This thread sends events to, and receives messages from, IoT Hub. No such thread is
created when working with the "LL" APIs. The creation of the background thread is a convenience to the developer.
You don’t have to worry about explicitly sending events and receiving messages from IoT Hub -- it happens
automatically in the background. In contrast, the "LL" APIs give you explicit control over communication with IoT
Hub, if you need it.
To understand this better, let’s look at an example:
When you call IoTHubClient_SendEventAsync, what you're actually doing is putting the event in a buffer. The
background thread created when you call IoTHubClient_CreateFromConnectionString continually monitors
this buffer and sends any data that it contains to IoT Hub. This happens in the background at the same time that the
main thread is performing other work.
Similarly, when you register a callback function for messages using IoTHubClient_SetMessageCallback, you're
instructing the SDK to have the background thread invoke the callback function when a message is received,
independent of the main thread.
The "LL" APIs don’t create a background thread. Instead, a new API must be called to explicitly send and receive
data from IoT Hub. This is demonstrated in the following example.
The iothub_client_sample_http application that’s included in the SDK demonstrates the lower-level APIs. In that
sample, we send events to IoT Hub with code such as the following:

EVENT_INSTANCE message;
sprintf_s(msgText, sizeof(msgText), "Message_%d_From_IoTHubClient_LL_Over_HTTP", i);
message.messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText));

IoTHubClient_LL_SendEventAsync(iotHubClientHandle, message.messageHandle, SendConfirmationCallback, &message)

The first three lines create the message, and the last line sends the event. However, as mentioned previously,
"sending" the event means that the data is simply placed in a buffer. Nothing is transmitted on the network when
we call IoTHubClient_LL_SendEventAsync. In order to actually ingress the data to IoT Hub, you must call
IoTHubClient_LL_DoWork, as in this example:

while (1)
{
IoTHubClient_LL_DoWork(iotHubClientHandle);
ThreadAPI_Sleep(1000);
}

This code (from the iothub_client_sample_http application) repeatedly calls IoTHubClient_LL_DoWork. Each
time IoTHubClient_LL_DoWork is called, it sends some events from the buffer to IoT Hub and it retrieves a
queued message being sent to the device. The latter case means that if we registered a callback function for
messages, then the callback is invoked (assuming any messages are queued up). We would have registered such a
callback function with code such as the following:

IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext)

The reason that IoTHubClient_LL_DoWork is often called in a loop is that each time it’s called, it sends some
buffered events to IoT Hub and retrieves the next message queued up for the device. Each call isn’t guaranteed to
send all buffered events or to retrieve all queued messages. If you want to send all events in the buffer and then
continue on with other processing you can replace this loop with code such as the following:

IOTHUB_CLIENT_STATUS status;

while ((IoTHubClient_LL_GetSendStatus(iotHubClientHandle, &status) == IOTHUB_CLIENT_OK) && (status ==


IOTHUB_CLIENT_SEND_STATUS_BUSY))
{
IoTHubClient_LL_DoWork(iotHubClientHandle);
ThreadAPI_Sleep(1000);
}

This code calls IoTHubClient_LL_DoWork until all events in the buffer have been sent to IoT Hub. Note this does
not also imply that all queued messages have been received. Part of the reason for this is that checking for "all"
messages isn’t as deterministic an action. What happens if you retrieve "all" of the messages, but then another one
is sent to the device immediately after? A better way to deal with that is with a programmed timeout. For example,
the message callback function could reset a timer every time it’s invoked. You can then write logic to continue
processing if, for example, no messages have been received in the last X seconds.
When you’re finished ingressing events and receiving messages, be sure to call the corresponding function to clean
up resources.

IoTHubClient_LL_Destroy(iotHubClientHandle);

Basically there’s only one set of APIs to send and receive data with a background thread and another set of APIs
that does the same thing without the background thread. A lot of developers may prefer the non-LL APIs, but the
lower-level APIs are useful when the developer wants explicit control over network transmissions. For example,
some devices collect data over time and only ingress events at specified intervals (for example, once an hour or
once a day). The lower-level APIs give you the ability to explicitly control when you send and receive data from IoT
Hub. Others will simply prefer the simplicity that the lower-level APIs provide. Everything happens on the main
thread rather than some work happening in the background.
Whichever model you choose, be sure to be consistent in which APIs you use. If you start by calling
IoTHubClient_LL_CreateFromConnectionString, be sure you only use the corresponding lower-level APIs for
any follow -up work:
IoTHubClient_LL_SendEventAsync
IoTHubClient_LL_SetMessageCallback
IoTHubClient_LL_Destroy
IoTHubClient_LL_DoWork
The opposite is true as well. If you start with IoTHubClient_CreateFromConnectionString, then use the non-LL
APIs for any additional processing.
In the Azure IoT device SDK for C, see the iothub_client_sample_http application for a complete example of the
lower-level APIs. The iothub_client_sample_amqp application can be referenced for a full example of the non-LL
APIs.

Property handling
So far when we've described sending data, we've been referring to the body of the message. For example, consider
this code:

EVENT_INSTANCE message;
sprintf_s(msgText, sizeof(msgText), "Hello World");
message.messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText));
IoTHubClient_LL_SendEventAsync(iotHubClientHandle, message.messageHandle, SendConfirmationCallback, &message)

This example sends a message to IoT Hub with the text "Hello World." However, IoT Hub also allows properties to
be attached to each message. Properties are name/value pairs that can be attached to the message. For example,
we can modify the previous code to attach a property to the message:

MAP_HANDLE propMap = IoTHubMessage_Properties(message.messageHandle);


sprintf_s(propText, sizeof(propText), "%d", i);
Map_AddOrUpdate(propMap, "SequenceNumber", propText);

We start by calling IoTHubMessage_Properties and passing it the handle of our message. What we get back is a
MAP_HANDLE reference that enables us to start adding properties. The latter is accomplished by calling
Map_AddOrUpdate, which takes a reference to a MAP_HANDLE, the property name, and the property value.
With this API we can add as many properties as we like.
When the event is read from Event Hubs, the receiver can enumerate the properties and retrieve their
corresponding values. For example, in .NET this would be accomplished by accessing the Properties collection on
the EventData object.
In the previous example, we’re attaching properties to an event that we send to IoT Hub. Properties can also be
attached to messages received from IoT Hub. If we want to retrieve properties from a message, we can use code
such as the following in our message callback function:
static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, void*
userContextCallback)
{
. . .

// Retrieve properties from the message


MAP_HANDLE mapProperties = IoTHubMessage_Properties(message);
if (mapProperties != NULL)
{
const char*const* keys;
const char*const* values;
size_t propertyCount = 0;
if (Map_GetInternals(mapProperties, &keys, &values, &propertyCount) == MAP_OK)
{
if (propertyCount > 0)
{
printf("Message Properties:\r\n");
for (size_t index = 0; index < propertyCount; index++)
{
printf("\tKey: %s Value: %s\r\n", keys[index], values[index]);
}
printf("\r\n");
}
}
}

. . .
}

The call to IoTHubMessage_Properties returns the MAP_HANDLE reference. We then pass that reference to
Map_GetInternals to obtain a reference to an array of the name/value pairs (as well as a count of the properties).
At that point it's a simple matter of enumerating the properties to get to the values we want.
You don't have to use properties in your application. However, if you need to set them on events or retrieve them
from messages, the IoTHubClient library makes it easy.

Message handling
As stated previously, when messages arrive from IoT Hub the IoTHubClient library responds by invoking a
registered callback function. There is a return parameter of this function that deserves some additional explanation.
Here’s an excerpt of the callback function in the iothub_client_sample_http sample application:

static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, void*


userContextCallback)
{
. . .
return IOTHUBMESSAGE_ACCEPTED;
}

Note that the return type is IOTHUBMESSAGE_DISPOSITION_RESULT and in this particular case we return
IOTHUBMESSAGE_ACCEPTED. There are other values we can return from this function that change how the
IoTHubClient library reacts to the message callback. Here are the options.
IOTHUBMESSAGE_ACCEPTED – The message has been processed successfully. The IoTHubClient library
will not invoke the callback function again with the same message.
IOTHUBMESSAGE_REJECTED – The message was not processed and there is no desire to do so in the
future. The IoTHubClient library should not invoke the callback function again with the same message.
IOTHUBMESSAGE_ABANDONED – The message was not processed successfully, but the IoTHubClient
library should invoke the callback function again with the same message.
For the first two return codes, the IoTHubClient library sends a message to IoT Hub indicating that the message
should be deleted from the device queue and not delivered again. The net effect is the same (the message is deleted
from the device queue), but whether the message was accepted or rejected is still recorded. Recording this
distinction is useful to senders of the message who can listen for feedback and find out if a device has accepted or
rejected a particular message.
In the last case a message is also sent to IoT Hub, but it indicates that the message should be redelivered. Typically
you’ll abandon a message if you encounter some error but want to try to process the message again. In contrast,
rejecting a message is appropriate when you encounter an unrecoverable error (or if you simply decide you don’t
want to process the message).
In any case, be aware of the different return codes so that you can elicit the behavior you want from the
IoTHubClient library.

Alternate device credentials


As explained previously, the first thing to do when working with the IoTHubClient library is to obtain a
IOTHUB_CLIENT_HANDLE with a call such as the following:

IOTHUB_CLIENT_HANDLE iotHubClientHandle;
iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, AMQP_Protocol);

The arguments to IoTHubClient_CreateFromConnectionString are the device connection string and a


parameter that indicates the protocol we use to communicate with IoT Hub. The device connection string has a
format that appears as follows:

HostName=IOTHUBNAME.IOTHUBSUFFIX;DeviceId=DEVICEID;SharedAccessKey=SHAREDACCESSKEY

There are four pieces of information in this string: IoT Hub name, IoT Hub suffix, device ID, and shared access key.
You obtain the fully qualified domain name (FQDN ) of an IoT hub when you create your IoT hub instance in the
Azure portal — this gives you the IoT hub name (the first part of the FQDN ) and the IoT hub suffix (the rest of the
FQDN ). You get the device ID and the shared access key when you register your device with IoT Hub (as described
in the previous article).
IoTHubClient_CreateFromConnectionString gives you one way to initialize the library. If you prefer, you can
create a new IOTHUB_CLIENT_HANDLE by using these individual parameters rather than the device connection
string. This is achieved with the following code:

IOTHUB_CLIENT_CONFIG iotHubClientConfig;
iotHubClientConfig.iotHubName = "";
iotHubClientConfig.deviceId = "";
iotHubClientConfig.deviceKey = "";
iotHubClientConfig.iotHubSuffix = "";
iotHubClientConfig.protocol = HTTP_Protocol;
IOTHUB_CLIENT_HANDLE iotHubClientHandle = IoTHubClient_LL_Create(&iotHubClientConfig);

This accomplishes the same thing as IoTHubClient_CreateFromConnectionString.


It may seem obvious that you would want to use IoTHubClient_CreateFromConnectionString rather than this
more verbose method of initialization. Keep in mind, however, that when you register a device in IoT Hub what you
get is a device ID and device key (not a connection string). The device explorer SDK tool introduced in the previous
article uses libraries in the Azure IoT service SDK to create the device connection string from the device ID,
device key, and IoT Hub host name. So calling IoTHubClient_LL_Create may be preferable because it saves you
the step of generating a connection string. Use whichever method is convenient.
Configuration options
So far everything described about the way the IoTHubClient library works reflects its default behavior. However,
there are a few options that you can set to change how the library works. This is accomplished by leveraging the
IoTHubClient_LL_SetOption API. Consider this example:

unsigned int timeout = 30000;


IoTHubClient_LL_SetOption(iotHubClientHandle, "timeout", &timeout);

There are a couple of options that are commonly used:


SetBatching (bool) – If true, then data sent to IoT Hub is sent in batches. If false, then messages are sent
individually. The default is false. Note that the SetBatching option only applies to the HTTPS protocol and not
to the MQTT or AMQP protocols.
Timeout (unsigned int) – This value is represented in milliseconds. If sending an HTTPS request or receiving a
response takes longer than this time, then the connection times out.
The batching option is important. By default, the library ingresses events individually (a single event is whatever
you pass to IoTHubClient_LL_SendEventAsync). If the batching option is true, the library collects as many
events as it can from the buffer (up to the maximum message size that IoT Hub will accept). The event batch is sent
to IoT Hub in a single HTTPS call (the individual events are bundled into a JSON array). Enabling batching typically
results in big performance gains since you’re reducing network round-trips. It also significantly reduces bandwidth
since you are sending one set of HTTPS headers with an event batch rather than a set of headers for each
individual event. Unless you have a specific reason to do otherwise, typically you’ll want to enable batching.

Next steps
This article describes in detail the behavior of the IoTHubClient library found in the Azure IoT device SDK for
C. With this information, you should have a good understanding of the capabilities of the IoTHubClient library.
The next article provides similar detail on the serializer library.
To learn more about developing for IoT Hub, see the Azure IoT SDKs.
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Azure IoT device SDK for C – more about serializer
5/29/2018 • 21 min to read • Edit Online

The first article in this series introduced the Azure IoT device SDK for C. The next article provided a more
detailed description of the IoTHubClient. This article completes coverage of the SDK by providing a more detailed
description of the remaining component: the serializer library.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are only
available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to choose
the right IoT Hub tier.

The introductory article described how to use the serializer library to send events to and receive messages from
IoT Hub. In this article, we extend that discussion by providing a more complete explanation of how to model your
data with the serializer macro language. The article also includes more detail about how the library serializes
messages (and in some cases how you can control the serialization behavior). We'll also describe some parameters
you can modify that determine the size of the models you create.
Finally, the article revisits some topics covered in previous articles such as message and property handling. As we'll
find out, those features work in the same way using the serializer library as they do with the IoTHubClient
library.
Everything described in this article is based on the serializer SDK samples. If you want to follow along, see the
simplesample_amqp and simplesample_http applications included in the Azure IoT device SDK for C.
You can find the Azure IoT device SDK for C GitHub repository and view details of the API in the C API
reference.

The modeling language


The introductory article in this series introduced the Azure IoT device SDK for C modeling language through the
example provided in the simplesample_amqp application:

BEGIN_NAMESPACE(WeatherStation);

DECLARE_MODEL(ContosoAnemometer,
WITH_DATA(ascii_char_ptr, DeviceId),
WITH_DATA(double, WindSpeed),
WITH_ACTION(TurnFanOn),
WITH_ACTION(TurnFanOff),
WITH_ACTION(SetAirResistance, int, Position)
);

END_NAMESPACE(WeatherStation);

As you can see, the modeling language is based on C macros. You always begin your definition with
BEGIN_NAMESPACE and always end with END_NAMESPACE. It's common to name the namespace for your
company or, as in this example, the project that you're working on.
What goes inside the namespace are model definitions. In this case, there is a single model for an anemometer.
Once again, the model can be named anything, but typically this is named for the device or type of data you want to
exchange with IoT Hub.
Models contain a definition of the events you can ingress to IoT Hub (the data) as well as the messages you can
receive from IoT Hub (the actions). As you can see from the example, events have a type and a name; actions have a
name and optional parameters (each with a type).
What’s not demonstrated in this sample are additional data types that are supported by the SDK. We'll cover that
next.

NOTE
IoT Hub refers to the data a device sends to it as events, while the modeling language refers to it as data (defined using
WITH_DATA). Likewise, IoT Hub refers to the data you send to devices as messages, while the modeling language refers to it
as actions (defined using WITH_ACTION). Be aware that these terms may be used interchangeably in this article.

Supported data types


The following data types are supported in models created with the serializer library:

TYPE DESCRIPTION

double double precision floating point number

int 32 bit integer

float single precision floating point number

long long integer

int8_t 8 bit integer

int16_t 16 bit integer

int32_t 32 bit integer

int64_t 64 bit integer

bool boolean

ascii_char_ptr ASCII string

EDM_DATE_TIME_OFFSET date time offset

EDM_GUID GUID

EDM_BINARY binary

DECLARE_STRUCT complex data type

Let’s start with the last data type. The DECLARE_STRUCT allows you to define complex data types, which are
groupings of the other primitive types. These groupings allow us to define a model that looks like this:
DECLARE_STRUCT(TestType,
double, aDouble,
int, aInt,
float, aFloat,
long, aLong,
int8_t, aInt8,
uint8_t, auInt8,
int16_t, aInt16,
int32_t, aInt32,
int64_t, aInt64,
bool, aBool,
ascii_char_ptr, aAsciiCharPtr,
EDM_DATE_TIME_OFFSET, aDateTimeOffset,
EDM_GUID, aGuid,
EDM_BINARY, aBinary
);

DECLARE_MODEL(TestModel,
WITH_DATA(TestType, Test)
);

Our model contains a single data event of type TestType. TestType is a complex type that includes several
members, which collectively demonstrate the primitive types supported by the serializer modeling language.
With a model like this, we can write code to send data to IoT Hub that appears as follows:

TestModel* testModel = CREATE_MODEL_INSTANCE(MyThermostat, TestModel);

testModel->Test.aDouble = 1.1;
testModel->Test.aInt = 2;
testModel->Test.aFloat = 3.0f;
testModel->Test.aLong = 4;
testModel->Test.aInt8 = 5;
testModel->Test.auInt8 = 6;
testModel->Test.aInt16 = 7;
testModel->Test.aInt32 = 8;
testModel->Test.aInt64 = 9;
testModel->Test.aBool = true;
testModel->Test.aAsciiCharPtr = "ascii string 1";

time_t now;
time(&now);
testModel->Test.aDateTimeOffset = GetDateTimeOffset(now);

EDM_GUID guid = { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
0x0F } };
testModel->Test.aGuid = guid;

unsigned char binaryArray[3] = { 0x01, 0x02, 0x03 };


EDM_BINARY binaryData = { sizeof(binaryArray), &binaryArray };
testModel->Test.aBinary = binaryData;

SendAsync(iotHubClientHandle, (const void*)&(testModel->Test));

Basically, we’re assigning a value to every member of the Test structure and then calling SendAsync to send the
Test data event to the cloud. SendAsync is a helper function that sends a single data event to IoT Hub:
void SendAsync(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, const void *dataEvent)
{
unsigned char* destination;
size_t destinationSize;
if (SERIALIZE(&destination, &destinationSize, *(const unsigned char*)dataEvent) ==
{
// null terminate the string
char* destinationAsString = (char*)malloc(destinationSize + 1);
if (destinationAsString != NULL)
{
memcpy(destinationAsString, destination, destinationSize);
destinationAsString[destinationSize] = '\0';
IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromString(destinationAsString);
if (messageHandle != NULL)
{
IoTHubClient_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, (void*)0);

IoTHubMessage_Destroy(messageHandle);
}
free(destinationAsString);
}
free(destination);
}
}

This function serializes the given data event and sends it to IoT Hub using IoTHubClient_SendEventAsync. This
is the same code discussed in previous articles (SendAsync encapsulates the logic into a convenient function).
One other helper function used in the previous code is GetDateTimeOffset. This function transforms the given
time into a value of type EDM_DATE_TIME_OFFSET:

EDM_DATE_TIME_OFFSET GetDateTimeOffset(time_t time)


{
struct tm newTime;
gmtime_s(&newTime, &time);
EDM_DATE_TIME_OFFSET dateTimeOffset;
dateTimeOffset.dateTime = newTime;
dateTimeOffset.fractionalSecond = 0;
dateTimeOffset.hasFractionalSecond = 0;
dateTimeOffset.hasTimeZone = 0;
dateTimeOffset.timeZoneHour = 0;
dateTimeOffset.timeZoneMinute = 0;
return dateTimeOffset;
}

If you run this code, the following message is sent to IoT Hub:

{"aDouble":1.100000000000000, "aInt":2, "aFloat":3.000000, "aLong":4, "aInt8":5, "auInt8":6, "aInt16":7,


"aInt32":8, "aInt64":9, "aBool":true, "aAsciiCharPtr":"ascii string 1", "aDateTimeOffset":"2015-09-
14T21:18:21Z", "aGuid":"00010203-0405-0607-0809-0A0B0C0D0E0F", "aBinary":"AQID"}

Note that the serialization is JSON, which is the format generated by the serializer library. Also note that each
member of the serialized JSON object matches the members of the TestType that we defined in our model. The
values also exactly match those used in the code. However, note that the binary data is base64-encoded: "AQID" is
the base64 encoding of {0x01, 0x02, 0x03}.
This example demonstrates the advantage of using the serializer library -- it enables us to send JSON to the cloud,
without having to explicitly deal with serialization in our application. All we have to worry about is setting the
values of the data events in our model and then calling simple APIs to send those events to the cloud.
With this information, we can define models that include the range of supported data types, including complex
types (we could even include complex types within other complex types). However, he serialized JSON generated
by the example above brings up an important point. How we send data with the serializer library determines
exactly how the JSON is formed. That particular point is what we'll cover next.

More about serialization


The previous section highlights an example of the output generated by the serializer library. In this section, we'll
explain how the library serializes data and how you can control that behavior using the serialization APIs.
In order to advance the discussion on serialization, we'll work with a new model based on a thermostat. First, let's
provide some background on the scenario we're trying to address.
We want to model a thermostat that measures temperature and humidity. Each piece of data is going to be sent to
IoT Hub differently. By default, the thermostat ingresses a temperature event once every 2 minutes; a humidity
event is ingressed once every 15 minutes. When either event is ingressed, it must include a timestamp that shows
the time that the corresponding temperature or humidity was measured.
Given this scenario, we'll demonstrate two different ways to model the data, and we'll explain the effect that
modeling has on the serialized output.
Model 1
Here's the first version of a model that supports the previous scenario:

BEGIN_NAMESPACE(Contoso);

DECLARE_STRUCT(TemperatureEvent,
int, Temperature,
EDM_DATE_TIME_OFFSET, Time);

DECLARE_STRUCT(HumidityEvent,
int, Humidity,
EDM_DATE_TIME_OFFSET, Time);

DECLARE_MODEL(Thermostat,
WITH_DATA(TemperatureEvent, Temperature),
WITH_DATA(HumidityEvent, Humidity)
);

END_NAMESPACE(Contoso);

Note that the model includes two data events: Temperature and Humidity. Unlike previous examples, the type of
each event is a structure defined using DECLARE_STRUCT. TemperatureEvent includes a temperature
measurement and a timestamp; HumidityEvent contains a humidity measurement and a timestamp. This model
gives us a natural way to model the data for the scenario described above. When we send an event to the cloud,
we'll either send a temperature/timestamp or a humidity/timestamp pair.
We can send a temperature event to the cloud using code such as the following:
time_t now;
time(&now);
thermostat->Temperature.Temperature = 75;
thermostat->Temperature.Time = GetDateTimeOffset(now);

unsigned char* destination;


size_t destinationSize;
if (SERIALIZE(&destination, &destinationSize, thermostat->Temperature) == IOT_AGENT_OK)
{
sendMessage(iotHubClientHandle, destination, destinationSize);
}

We'll use hard-coded values for temperature and humidity in the sample code, but imagine that we’re actually
retrieving these values by sampling the corresponding sensors on the thermostat.
The code above uses the GetDateTimeOffset helper that was introduced previously. For reasons that will become
clear later, this code explicitly separates the task of serializing and sending the event. The previous code serializes
the temperature event into a buffer. Then, sendMessage is a helper function (included in simplesample_amqp)
that sends the event to IoT Hub:

static void sendMessage(IOTHUB_CLIENT_HANDLE iotHubClientHandle, const unsigned char* buffer, size_t size)
{
static unsigned int messageTrackingId;
IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromByteArray(buffer, size);
if (messageHandle != NULL)
{
IoTHubClient_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, (void*)
(uintptr_t)messageTrackingId);

IoTHubMessage_Destroy(messageHandle);
}
free((void*)buffer);
}

This code is a subset of the SendAsync helper described in the previous section, so we won’t go over it again here.
When we run the previous code to send the Temperature event, this serialized form of the event is sent to IoT Hub:

{"Temperature":75, "Time":"2015-09-17T18:45:56Z"}

We're sending a temperature which is of type TemperatureEvent and that struct contains a Temperature and
Time member. This is directly reflected in the serialized data.
Similarly, we can send a humidity event with this code:

thermostat->Humidity.Humidity = 45;
thermostat->Humidity.Time = GetDateTimeOffset(now);
if (SERIALIZE(&destination, &destinationSize, thermostat->Humidity) == IOT_AGENT_OK)
{
sendMessage(iotHubClientHandle, destination, destinationSize);
}

The serialized form that’s sent to IoT Hub appears as follows:

{"Humidity":45, "Time":"2015-09-17T18:45:56Z"}

Again, this is as expected.


With this model, you can imagine how additional events can easily be added. You define more structures using
DECLARE_STRUCT, and include the corresponding event in the model using WITH_DATA.
Now, let’s modify the model so that it includes the same data but with a different structure.
Model 2
Consider this alternative model to the one above:

DECLARE_MODEL(Thermostat,
WITH_DATA(int, Temperature),
WITH_DATA(int, Humidity),
WITH_DATA(EDM_DATE_TIME_OFFSET, Time)
);

In this case we've eliminated the DECLARE_STRUCT macros and are simply defining the data items from our
scenario using simple types from the modeling language.
Just for the moment let’s ignore the Time event. With that aside, here’s the code to ingress Temperature:

time_t now;
time(&now);
thermostat->Temperature = 75;

unsigned char* destination;


size_t destinationSize;
if (SERIALIZE(&destination, &destinationSize, thermostat->Temperature) == IOT_AGENT_OK)
{
sendMessage(iotHubClientHandle, destination, destinationSize);
}

This code sends the following serialized event to IoT Hub:

{"Temperature":75}

And the code for sending the Humidity event appears as follows:

thermostat->Humidity = 45;
if (SERIALIZE(&destination, &destinationSize, thermostat->Humidity) == IOT_AGENT_OK)
{
sendMessage(iotHubClientHandle, destination, destinationSize);
}

This code sends this to IoT Hub:

{"Humidity":45}

So far there are still no surprises. Now let's change how we use the SERIALIZE macro.
The SERIALIZE macro can take multiple data events as arguments. This enables us to serialize the Temperature
and Humidity event together and send them to IoT Hub in one call:

if (SERIALIZE(&destination, &destinationSize, thermostat->Temperature, thermostat->Humidity) == IOT_AGENT_OK)


{
sendMessage(iotHubClientHandle, destination, destinationSize);
}
You might guess that the result of this code is that two data events are sent to IoT Hub:
[
{"Temperature":75},
{"Humidity":45}
]
In other words, you might expect that this code is the same as sending Temperature and Humidity separately. It’s
just a convenience to pass both events to SERIALIZE in the same call. However, that’s not the case. Instead, the
code above sends this single data event to IoT Hub:
{"Temperature":75, "Humidity":45}
This may seem strange because our model defines Temperature and Humidity as two separate events:

DECLARE_MODEL(Thermostat,
WITH_DATA(int, Temperature),
WITH_DATA(int, Humidity),
WITH_DATA(EDM_DATE_TIME_OFFSET, Time)
);

More to the point, we didn’t model these events where Temperature and Humidity are in the same structure:

DECLARE_STRUCT(TemperatureAndHumidityEvent,
int, Temperature,
int, Humidity,
);

DECLARE_MODEL(Thermostat,
WITH_DATA(TemperatureAndHumidityEvent, TemperatureAndHumidity),
);

If we used this model, it would be easier to understand how Temperature and Humidity would be sent in the
same serialized message. However it may not be clear why it works that way when you pass both data events to
SERIALIZE using model 2.
This behavior is easier to understand if you know the assumptions that the serializer library is making. To make
sense of this let’s go back to our model:

DECLARE_MODEL(Thermostat,
WITH_DATA(int, Temperature),
WITH_DATA(int, Humidity),
WITH_DATA(EDM_DATE_TIME_OFFSET, Time)
);

Think of this model in object-oriented terms. In this case we’re modeling a physical device (a thermostat) and that
device includes attributes like Temperature and Humidity.
We can send the entire state of our model with code such as the following:

if (SERIALIZE(&destination, &destinationSize, thermostat->Temperature, thermostat->Humidity, thermostat->Time)


== IOT_AGENT_OK)
{
sendMessage(iotHubClientHandle, destination, destinationSize);
}
Assuming the values of Temperature, Humidity and Time are set, we would see an event like this sent to IoT Hub:

{"Temperature":75, "Humidity":45, "Time":"2015-09-17T18:45:56Z"}

Sometimes you may only want to send some properties of the model to the cloud (this is especially true if your
model contains a large number of data events). It’s useful to send only a subset of data events, such as in our earlier
example:

{"Temperature":75, "Time":"2015-09-17T18:45:56Z"}

This generates exactly the same serialized event as if we had defined a TemperatureEvent with a Temperature
and Time member, just as we did with model 1. In this case we were able to generate exactly the same serialized
event by using a different model (model 2) because we called SERIALIZE in a different way.
The important point is that if you pass multiple data events to SERIALIZE, then it assumes each event is a
property in a single JSON object.
The best approach depends on you and how you think about your model. If you’re sending "events" to the cloud
and each event contains a defined set of properties, then the first approach makes a lot of sense. In that case you
would use DECLARE_STRUCT to define the structure of each event and then include them in your model with the
WITH_DATA macro. Then you send each event as we did in the first example above. In this approach you would
only pass a single data event to SERIALIZER.
If you think about your model in an object-oriented fashion, then the second approach may suit you. In this case,
the elements defined using WITH_DATA are the "properties" of your object. You pass whatever subset of events to
SERIALIZE that you like, depending on how much of your "object’s" state you want to send to the cloud.
Nether approach is right or wrong. Just be aware of how the serializer library works, and pick the modeling
approach that best fits your needs.

Message handling
So far this article has only discussed sending events to IoT Hub, and hasn't addressed receiving messages. The
reason for this is that what we need to know about receiving messages has largely been covered in an earlier
article. Recall from that article that you process messages by registering a message callback function:

IoTHubClient_SetMessageCallback(iotHubClientHandle, IoTHubMessage, myWeather)

You then write the callback function that’s invoked when a message is received:
static IOTHUBMESSAGE_DISPOSITION_RESULT IoTHubMessage(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback)
{
IOTHUBMESSAGE_DISPOSITION_RESULT result;
const unsigned char* buffer;
size_t size;
if (IoTHubMessage_GetByteArray(message, &buffer, &size) != IOTHUB_MESSAGE_OK)
{
printf("unable to IoTHubMessage_GetByteArray\r\n");
result = EXECUTE_COMMAND_ERROR;
}
else
{
/*buffer is not zero terminated*/
char* temp = malloc(size + 1);
if (temp == NULL)
{
printf("failed to malloc\r\n");
result = EXECUTE_COMMAND_ERROR;
}
else
{
memcpy(temp, buffer, size);
temp[size] = '\0';
EXECUTE_COMMAND_RESULT executeCommandResult = EXECUTE_COMMAND(userContextCallback, temp);
result =
(executeCommandResult == EXECUTE_COMMAND_ERROR) ? IOTHUBMESSAGE_ABANDONED :
(executeCommandResult == EXECUTE_COMMAND_SUCCESS) ? IOTHUBMESSAGE_ACCEPTED :
IOTHUBMESSAGE_REJECTED;
free(temp);
}
}
return result;
}

This implementation of IoTHubMessage calls the specific function for each action in your model. For example, if
your model defines this action:

WITH_ACTION(SetAirResistance, int, Position)

You must define a function with this signature:

EXECUTE_COMMAND_RESULT SetAirResistance(ContosoAnemometer* device, int Position)


{
(void)device;
(void)printf("Setting Air Resistance Position to %d.\r\n", Position);
return EXECUTE_COMMAND_SUCCESS;
}

SetAirResistance is then called when that message is sent to your device.


What we haven't explained yet is what the serialized version of message looks like. In other words, if you want to
send a SetAirResistance message to your device, what does that look like?
If you're sending a message to a device, you would do so through the Azure IoT service SDK. You still need to know
what string to send to invoke a particular action. The general format for sending a message appears as follows:

{"Name" : "", "Parameters" : "" }

You're sending a serialized JSON object with two properties: Name is the name of the action (message) and
Parameters contains the parameters of that action.
For example, to invoke SetAirResistance you can send this message to a device:

{"Name" : "SetAirResistance", "Parameters" : { "Position" : 5 }}

The action name must exactly match an action defined in your model. The parameter names must match as well.
Also note case sensitivity. Name and Parameters are always uppercase. Make sure to match the case of your
action name and parameters in your model. In this example, the action name is "SetAirResistance" and not
"setairresistance".
The two other actions TurnFanOn and TurnFanOff can be invoked by sending these messages to a device:

{"Name" : "TurnFanOn", "Parameters" : {}}


{"Name" : "TurnFanOff", "Parameters" : {}}

This section described everything you need to know when sending events and receiving messages with the
serializer library. Before moving on, let's cover some parameters you can configure that control how large your
model is.

Macro configuration
If you’re using the Serializer library an important part of the SDK to be aware of is found in the azure-c-shared-
utility library. If you have cloned the Azure-iot-sdk-c repository from GitHub using the --recursive option, then you
will find this shared utility library here:

.\\c-utility

If you have not cloned the library, you can find it here.
Within the shared utility library, you will find the following folder:

azure-c-shared-utility\\macro\_utils\_h\_generator.

This folder contains a Visual Studio solution called macro_utils_h_generator.sln:

The program in this solution generates the macro_utils.h file. There’s a default macro_utils.h file included with the
SDK. This solution allows you to modify some parameters and then recreate the header file based on these
parameters.
The two key parameters to be concerned with are nArithmetic and nMacroParameters which are defined in
these two lines found in macro_utils.tt:
<#int nArithmetic=1024;#>
<#int nMacroParameters=124;/*127 parameters in one macro definition in C99 in chapter 5.2.4.1 Translation
limits*/#>

These values are the default parameters included with the SDK. Each parameter has the following meaning:
nMacroParameters – Controls how many parameters you can have in one DECL ARE_MODEL macro definition.
nArithmetic – Controls the total number of members allowed in a model.
The reason these parameters are important is because they control how large your model can be. For example,
consider this model definition:

DECLARE_MODEL(MyModel,
WITH_DATA(int, MyData)
);

As mentioned previously, DECLARE_MODEL is just a C macro. The names of the model and the WITH_DATA
statement (yet another macro) are parameters of DECLARE_MODEL. nMacroParameters defines how many
parameters can be included in DECLARE_MODEL. Effectively, this defines how many data event and action
declarations you can have. As such, with the default limit of 124 this means that you can define a model with a
combination of about 60 actions and data events. If you try to exceed this limit, you'll receive compiler errors that
look similar to this:

The nArithmetic parameter is more about the internal workings of the macro language than your application. It
controls the total number of members you can have in your model, including DECLARE_STRUCT macros. If you
start seeing compiler errors such as this, then you should try increasing nArithmetic:

If you want to change these parameters, modify the values in the macro_utils.tt file, recompile the
macro_utils_h_generator.sln solution, and run the compiled program. When you do so, a new macro_utils.h file is
generated and placed in the .\common\inc directory.
In order to use the new version of macro_utils.h, remove the serializer NuGet package from your solution and in
its place include the serializer Visual Studio project. This enables your code to compile against the source code of
the serializer library. This includes the updated macro_utils.h. If you want to do this for simplesample_amqp, start
by removing the NuGet package for the serializer library from the solution:
Then add this project to your Visual Studio solution:

.\c\serializer\build\windows\serializer.vcxproj

When you're done, your solution should look like this:

Now when you compile your solution, the updated macro_utils.h is included in your binary.
Note that increasing these values high enough can exceed compiler limits. To this point, the nMacroParameters is
the main parameter with which to be concerned. The C99 spec specifies that a minimum of 127 parameters are
allowed in a macro definition. The Microsoft compiler follows the spec exactly (and has a limit of 127), so you won't
be able to increase nMacroParameters beyond the default. Other compilers might allow you to do so (for
example, the GNU compiler supports a higher limit).
So far we've covered just about everything you need to know about how to write code with the serializer library.
Before concluding, let's revisit some topics from previous articles that you may be wondering about.

The lower-level APIs


The sample application on which this article focused is simplesample_amqp. This sample uses the higher-level
(the non-"LL") APIs to send events and receive messages. If you use these APIs, a background thread runs which
takes care of both sending events and receiving messages. However, you can use the lower-level (LL ) APIs to
eliminate this background thread and take explicit control over when you send events or receive messages from the
cloud.
As described in a previous article, there is a set of functions that consists of the higher-level APIs:
IoTHubClient_CreateFromConnectionString
IoTHubClient_SendEventAsync
IoTHubClient_SetMessageCallback
IoTHubClient_Destroy
These APIs are demonstrated in simplesample_amqp.
There is also an analogous set of lower-level APIs.
IoTHubClient_LL_CreateFromConnectionString
IoTHubClient_LL_SendEventAsync
IoTHubClient_LL_SetMessageCallback
IoTHubClient_LL_Destroy
Note that the lower-level APIs work exactly the same way as described in the previous articles. You can use the first
set of APIs if you want a background thread to handle sending events and receiving messages. You use the second
set of APIs if you want explicit control over when you send and receive data from IoT Hub. Either set of APIs work
equally well with the serializer library.
For an example of how the lower-level APIs are used with the serializer library, see the simplesample_http
application.

Additional topics
A few other topics worth mentioning again are property handling, using alternate device credentials, and
configuration options. These are all topics covered in a previous article. The main point is that all of these features
work in the same way with the serializer library as they do with the IoTHubClient library. For example, if you
want to attach properties to an event from your model, you use IoTHubMessage_Properties and
Map_AddorUpdate, the same way as described previously:

MAP_HANDLE propMap = IoTHubMessage_Properties(message.messageHandle);


sprintf_s(propText, sizeof(propText), "%d", i);
Map_AddOrUpdate(propMap, "SequenceNumber", propText);

Whether the event was generated from the serializer library or created manually using the IoTHubClient library
does not matter.
For the alternate device credentials, using IoTHubClient_LL_Create works just as well as
IoTHubClient_CreateFromConnectionString for allocating an IOTHUB_CLIENT_HANDLE.
Finally, if you're using the serializer library, you can set configuration options with IoTHubClient_LL_SetOption
just as you did when using the IoTHubClient library.
A feature that is unique to the serializer library are the initialization APIs. Before you can start working with the
library, you must call serializer_init:

serializer_init(NULL);
This is done just before you call IoTHubClient_CreateFromConnectionString.
Similarly, when you're done working with the library, the last call you’ll make is to serializer_deinit:

serializer_deinit();

Otherwise, all of the other features listed above work the same in the serializer library as they do in the
IoTHubClient library. For more information about any of these topics, see the previous article in this series.

Next steps
This article describes in detail the unique aspects of the serializer library contained in the Azure IoT device SDK
for C. With the information provided you should have a good understanding of how to use models to send events
and receive messages from IoT Hub.
This also concludes the three-part series on how to develop applications with the Azure IoT device SDK for C.
This should be enough information to not only get you started but give you a thorough understanding of how the
APIs work. For additional information, there are a few samples in the SDK not covered here. Otherwise, the SDK
documentation is a good resource for additional information.
To learn more about developing for IoT Hub, see the Azure IoT SDKs.
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Internet of Things security from the ground up
5/29/2018 • 11 min to read • Edit Online

The Internet of Things (IoT) poses unique security, privacy, and compliance challenges to businesses worldwide.
Unlike traditional cyber technology where these issues revolve around software and how it is implemented, IoT
concerns what happens when the cyber and the physical worlds converge. Protecting IoT solutions requires
ensuring secure provisioning of devices, secure connectivity between these devices and the cloud, and secure data
protection in the cloud during processing and storage. Working against such functionality, however, are resource-
constrained devices, geographic distribution of deployments, and a large number of devices within a solution.
This article explores how the IoT solution accelerators provide a secure and private Internet of Things cloud
solution. The solution accelerators deliver a complete end-to-end solution, with security built into every stage from
the ground up. At Microsoft, developing secure software is part of the software engineering practice, rooted in
Microsoft's decades long experience of developing secure software. To ensure this, Security Development Lifecycle
(SDL ) is the foundational development methodology, coupled with a host of infrastructure-level security services
such as Operational Security Assurance (OSA) and the Microsoft Digital Crimes Unit, Microsoft Security
Response Center, and Microsoft Malware Protection Center.
The solution accelerators offer unique features that make provisioning, connecting to, and storing data from IoT
devices easy and transparent and, most of all, secure. This article examines the Azure IoT solution accelerators
security features and deployment strategies to ensure security, privacy, and compliance challenges are addressed.

Introduction
The Internet of Things (IoT) is the wave of the future, offering businesses immediate and real-world opportunities
to reduce costs, increase revenue, and transform their business. Many businesses, however, are hesitant to deploy
IoT in their organizations due to concerns about security, privacy, and compliance. A major point of concern comes
from the uniqueness of the IoT infrastructure, which merges the cyber and physical worlds together, compounding
individual risks inherent in these two worlds. Security of IoT pertains to ensuring the integrity of code running on
devices, providing device and user authentication, defining clear ownership of devices (as well as data generated
by those devices), and being resilient to cyber and physical attacks.
Then, there’s the issue of privacy. Companies want transparency concerning data collection, as in what’s being
collected and why, who can see it, who controls access, and so on. Finally, there are general safety issues of the
equipment along with the people operating them, and issues of maintaining industry standards of compliance.
Given the security, privacy, transparency, and compliance concerns, choosing the right IoT solution provider
remains a challenge. Stitching together individual pieces of IoT software and services provided by a variety of
vendors introduces gaps in security, privacy, transparency, and compliance, which may be hard to detect, let alone
fix. The choice of the right IoT software and service provider is based on finding providers that have extensive
experience running services, which span across verticals and geographies, but are also able to scale in a secure and
transparent fashion. Similarly, it helps for the selected provider to have decades of experience with developing
secure software running on billions of machines worldwide, and have the ability to appreciate the threat landscape
posed by this new world of the Internet of Things.

Secure infrastructure from the ground up


The Microsoft Cloud infrastructure supports more than one billion customers in 127 countries. Drawing on
Microsoft's decades-long experience building enterprise software and running some of the largest online services
in the world, the Microsoft Cloud provides higher levels of enhanced security, privacy, compliance, and threat
mitigation practices than most customers could achieve on their own.
The Security Development Lifecycle (SDL ) provides a mandatory company-wide development process that
embeds security requirements into the entire software lifecycle. To help ensure that operational activities follow the
same level of security practices, SDL uses rigorous security guidelines laid out in Microsoft's Operational Security
Assurance (OSA) process. Microsoft also works with third-party audit firms for ongoing verification that it meets
its compliance obligations, and Microsoft engages in broad security efforts through the creation of centers of
excellence, including the Microsoft Digital Crimes Unit, Microsoft Security Response Center, and Microsoft
Malware Protection Center.

Microsoft Azure - secure IoT infrastructure for your business


Microsoft Azure offers a complete cloud solution, one that combines a constantly growing collection of integrated
cloud services—analytics, machine learning, storage, security, networking, and web—with an industry-leading
commitment to the protection and privacy of your data. Microsoft's assume breach strategy uses a dedicated red
team of software security experts who simulate attacks, testing the ability of Azure to detect, protect against
emerging threats, and recover from breaches. Microsoft's global incident response team works around the clock to
mitigate the effects of attacks and malicious activity. The team follows established procedures for incident
management, communication, and recovery, and uses discoverable and predictable interfaces with internal and
external partners.
Microsoft's systems provide continuous intrusion detection and prevention, service attack prevention, regular
penetration testing, and forensic tools that help identify and mitigate threats. Multi-factor authentication provides
an extra layer of security for end users to access the network. And for the application and the host provider,
Microsoft offers access control, monitoring, anti-malware, vulnerability scanning, patches, and configuration
management.
The solution accelerators take advantage of the security and privacy built into the Azure platform along with the
SDL and OSA processes for secure development and operation of all Microsoft software. These procedures
provide infrastructure protection, network protection, and identity and management features fundamental to the
security of any solution.
The Azure IoT Hub within the IoT solution accelerators offers a fully-managed service that enables reliable and
secure bi-directional communication between IoT devices and Azure services such as Azure Machine Learning and
Azure Stream Analytics by using per-device security credentials and access control.
To best communicate security and privacy features built into the Azure IoT solution accelerators, this article breaks
down the suite into the three primary security areas.

Secure device provisioning and authentication


The solution accelerators secure devices while they are out in the field by providing a unique identity key for each
device, which can be used by the IoT infrastructure to communicate with the device while it is in operation. The
process is quick and easy to set up. The generated key with a user-selected device ID forms the basis of a token
used in all communication between the device and the Azure IoT Hub.
Device IDs can be associated with a device during manufacturing (that is, flashed in a hardware trust module) or
can use an existing fixed identity as a proxy (for example CPU serial numbers). Since changing this identifying
information in the device is not simple, it is important to introduce logical device IDs in case the underlying device
hardware changes but the logical device remains the same. In some cases, the association of a device identity can
happen at device deployment time (for example, an authenticated field engineer physically configures a new device
while communicating with the solution backend). The Azure IoT Hub identity registry provides secure storage of
device identities and security keys for a solution. Individual or groups of device identities can be added to an allow
list, or a block list, enabling complete control over device access.
Azure IoT Hub access control policies in the cloud enable activation and disabling any device identity, providing a
way to disassociate a device from an IoT deployment when required. This association and disassociation of devices
is based on each device identity.
Additional device security features include:
Devices do not accept unsolicited network connections. They establish all connections and routes in an
outbound-only fashion. For a device to receive a command from the backend, the device must initiate a
connection to check for any pending commands to process. Once a connection between the device and IoT Hub
is securely established, messaging from the cloud to the device and device to the cloud can be sent
transparently.
Devices only connect to or establish routes to well-known services with which they are peered, such as an
Azure IoT Hub.
System-level authorization and authentication use per-device identities, making access credentials and
permissions near-instantly revocable.
Secure connectivity
Durability of messaging is an important feature of any IoT solution. The need to durably deliver commands and/or
receive data from devices is underlined by the fact that IoT devices are connected over the Internet, or other
similar networks that can be unreliable. Azure IoT Hub offers durability of messaging between cloud and devices
through a system of acknowledgments in response to messages. Additional durability for messaging is achieved
by caching messages in the IoT Hub for up to seven days for telemetry and two days for commands.
Efficiency is important to ensure conservation of resources and operation in a resource-constrained environment.
HTTPS (HTTP Secure), the industry-standard secure version of the popular http protocol, is supported by Azure
IoT Hub, enabling efficient communication. Advanced Message Queuing Protocol (AMQP ) and Message Queuing
Telemetry Transport (MQTT), supported by Azure IoT Hub, are designed not only for efficiency in terms of
resource use but also reliable message delivery.
Scalability requires the ability to securely interoperate with a wide range of devices. Azure IoT hub enables secure
connection to both IP -enabled and non-IP -enabled devices. IP -enabled devices are able to directly connect and
communicate with the IoT Hub over a secure connection. Non-IP -enabled devices are resource-constrained and
connect only over short distance communication protocols, such as Zwave, ZigBee, and Bluetooth. A field gateway
is used to aggregate these devices and performs protocol translation to enable secure bi-directional
communication with the cloud.
Additional connection security features include:
The communication path between devices and Azure IoT Hub, or between gateways and Azure IoT Hub, is
secured using industry-standard Transport Layer Security (TLS ) with Azure IoT Hub authenticated using X.509
protocol.
In order to protect devices from unsolicited inbound connections, Azure IoT Hub does not open any connection
to the device. The device initiates all connections.
Azure IoT Hub durably stores messages for devices and waits for the device to connect. These commands are
stored for two days, enabling devices connecting sporadically, due to power or connectivity concerns, to receive
these commands. Azure IoT Hub maintains a per-device queue for each device.
Secure processing and storage in the cloud
From encrypted communications to processing data in the cloud, the solution accelerators help keep data secure.
It provides flexibility to implement additional encryption and management of security keys.
Using Azure Active Directory (AAD ) for user authentication and authorization, Azure IoT solution accelerators can
provide a policy-based authorization model for data in the cloud, enabling easy access management that can be
audited and reviewed. This model also enables near-instant revocation of access to data in the cloud, and of
devices connected to the Azure IoT solution accelerators.
Once data is in the cloud, it can be processed and stored in any user-defined workflow. Access to each part of the
data is controlled with Azure Active Directory, depending on the storage service used.
All keys used by the IoT infrastructure are stored in the cloud in secure storage, with the ability to roll over in case
keys need to be reprovisioned. Data can be stored in Azure Cosmos DB or in SQL databases, enabling definition
of the level of security desired. Additionally, Azure provides a way to monitor and audit all access to your data to
alert you of any intrusion or unauthorized access.

Conclusion
The Internet of Things starts with your things—the things that matter most to businesses. IoT can deliver amazing
value to a business by reducing costs, increasing revenue, and transforming business. Success of this
transformation largely depends on choosing the right IoT software and service provider. That means finding a
provider that not only catalyzes this transformation by understanding business needs and requirements, but also
provides services and software built with security, privacy, transparency, and compliance as major design
considerations. Microsoft has extensive experience with developing and deploying secure software and services
and continues to be a leader in this new age of Internet of Things.
The solution accelerators build in security measures by design, enabling secure monitoring of assets to improve
efficiencies, drive operational performance to enable innovation, and employ advanced data analytics to transform
businesses. With its layered approach towards security, multiple security features, and design patterns, the solution
accelerators help deploy an infrastructure that can be trusted to transform any business.

Additional information
Each solution accelerator creates instances of Azure services, such as:
Azure IoT Hub: Your gateway that connects the cloud to devices. You can scale to millions of connections per
hub and process massive volumes of data with per-device authentication support helping you secure your
solution.
Azure Cosmos DB: A scalable, fully-indexed database service for semi-structured data that manages metadata
for the devices you provision, such as attributes, configuration, and security properties. Azure Cosmos DB
offers high-performance and high-throughput processing, schema-agnostic indexing of data, and a rich SQL
query interface.
Azure Stream Analytics: Real-time stream processing in the cloud that enables you to rapidly develop and
deploy a low -cost analytics solution to uncover real-time insights from devices, sensors, infrastructure, and
applications. The data from this fully-managed service can scale to any volume while still achieving high
throughput, low latency, and resiliency.
Azure App Services: A cloud platform to build powerful web and mobile apps that connect to data anywhere;
in the cloud or on-premises. Build engaging mobile apps for iOS, Android, and Windows. Integrate with your
Software as a Service (SaaS ) and enterprise applications with out-of-the-box connectivity to dozens of cloud-
based services and enterprise applications. Code in your favorite language and IDE —.NET, Node.js, PHP,
Python, or Java—to build web apps and APIs faster than ever.
Logic Apps: The Logic Apps feature of Azure App Service helps integrate your IoT solution to your existing
line-of-business systems and automate workflow processes. Logic Apps enables developers to design
workflows that start from a trigger and then execute a series of steps—rules and actions that use powerful
connectors to integrate with your business processes. Logic Apps offers out-of-the-box connectivity to a vast
ecosystem of SaaS, cloud-based, and on-premises applications.
Azure blob storage: Reliable, economical cloud storage for the data that your devices send to the cloud.

See also
To learn more about securing your IoT solution, see:
IoT Security Best Practices
IoT Security Architecture
Secure your IoT deployment
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Internet of Things security best practices
5/29/2018 • 6 min to read • Edit Online

Securing an Internet of Things (IoT) infrastructure requires a rigorous security-in-depth strategy. This strategy
requires you to secure data in the cloud, protect data integrity while in transit over the public internet, and securely
provision devices. Each layer builds greater security assurance in the overall infrastructure.

Secure an IoT infrastructure


This security-in-depth strategy can be developed and executed with active participation of various players involved
with the manufacturing, development, and deployment of IoT devices and infrastructure. Following is a high-level
description of these players.
IoT hardware manufacturer/integrator: Typically, these players are the manufacturers of IoT hardware
being deployed, integrators assembling hardware from various manufacturers, or suppliers providing hardware
for an IoT deployment manufactured or integrated by other suppliers.
IoT solution developer: The development of an IoT solution is typically done by a solution developer. This
developer may part of an in-house team or a system integrator (SI) specializing in this activity. The IoT solution
developer can develop various components of the IoT solution from scratch, integrate various off-the-shelf or
open-source components, or adopt solution accelerators with minor adaptation.
IoT solution deployer: After an IoT solution is developed, it needs to be deployed in the field. This process
involves deployment of hardware, interconnection of devices, and deployment of solutions in hardware devices
or the cloud.
IoT solution operator: After the IoT solution is deployed, it requires long-term operations, monitoring,
upgrades, and maintenance. These tasks can be done by an in-house team that comprises information
technology specialists, hardware operations and maintenance teams, and domain specialists who monitor the
correct behavior of overall IoT infrastructure.
The sections that follow provide best practices for each of these players to help develop, deploy, and operate a
secure IoT infrastructure.

IoT hardware manufacturer/integrator


The following are the best practices for IoT hardware manufacturers and hardware integrators.
Scope hardware to minimum requirements: The hardware design should include the minimum features
required for operation of the hardware, and nothing more. An example is to include USB ports only if
necessary for the operation of the device. These additional features open the device for unwanted attack vectors
that should be avoided.
Make hardware tamper proof: Build in mechanisms to detect physical tampering, such as opening of the
device cover or removing a part of the device. These tamper signals may be part of the data stream uploaded to
the cloud, which could alert operators of these events.
Build around secure hardware: If COGS permits, build security features such as secure and encrypted
storage, or boot functionality based on Trusted Platform Module (TPM ). These features make devices more
secure and help protect the overall IoT infrastructure.
Make upgrades secure: Firmware upgrades during the lifetime of the device are inevitable. Building devices
with secure paths for upgrades and cryptographic assurance of firmware versions will allow the device to be
secure during and after upgrades.
IoT solution developer
The following are the best practices for IoT solution developers:
Follow secure software development methodology: Development of secure software requires ground-up
thinking about security, from the inception of the project all the way to its implementation, testing, and
deployment. The choices of platforms, languages, and tools are all influenced with this methodology. The
Microsoft Security Development Lifecycle provides a step-by-step approach to building secure software.
Choose open-source software with care: Open-source software provides an opportunity to quickly develop
solutions. When you're choosing open-source software, consider the activity level of the community for each
open-source component. An active community ensures that software is supported and that issues are
discovered and addressed. Alternatively, an obscure and inactive open-source software project might not be
supported and issues are not likely be discovered.
Integrate with care: Many software security flaws exist at the boundary of libraries and APIs. Functionality
that may not be required for the current deployment might still be available via an API layer. To ensure overall
security, make sure to check all interfaces of components being integrated for security flaws.

IoT solution deployer


The following are best practices for IoT solution deployers:
Deploy hardware securely: IoT deployments may require hardware to be deployed in unsecure locations,
such as in public spaces or unsupervised locales. In such situations, ensure that hardware deployment is
tamper-proof to the maximum extent. If USB or other ports are available on the hardware, ensure that they are
covered securely. Many attack vectors can use these as entry points.
Keep authentication keys safe: During deployment, each device requires device IDs and associated
authentication keys generated by the cloud service. Keep these keys physically safe even after the deployment.
Any compromised key can be used by a malicious device to masquerade as an existing device.

IoT solution operator


The following are the best practices for IoT solution operators:
Keep the system up-to-date: Ensure that device operating systems and all device drivers are upgraded to the
latest versions. If you turn on automatic updates in Windows 10 (IoT or other SKUs), Microsoft keeps it up-to-
date, providing a secure operating system for IoT devices. Keeping other operating systems (such as Linux) up-
to-date helps ensure that they are also protected against malicious attacks.
Protect against malicious activity: If the operating system permits, install the latest antivirus and
antimalware capabilities on each device operating system. This practice can help mitigate most external threats.
You can protect most modern operating systems against threats by taking appropriate steps.
Audit frequently: Auditing IoT infrastructure for security-related issues is key when responding to security
incidents. Most operating systems provide built-in event logging that should be reviewed frequently to make
sure no security breach has occurred. Audit information can be sent as a separate telemetry stream to the cloud
service where it can be analyzed.
Physically protect the IoT infrastructure: The worst security attacks against IoT infrastructure are launched
using physical access to devices. One important safety practice is to protect against malicious use of USB ports
and other physical access. One key to uncovering breaches that might have occurred is logging of physical
access, such as USB port use. Again, Windows 10 (IoT and other SKUs) enables detailed logging of these
events.
Protect cloud credentials: Cloud authentication credentials used for configuring and operating an IoT
deployment are possibly the easiest way to gain access and compromise an IoT system. Protect the credentials
by changing the password frequently, and refrain from using these credentials on public machines.
Capabilities of different IoT devices vary. Some devices might be computers running common desktop operating
systems, and some devices might be running very light-weight operating systems. The security best practices
described previously might be applicable to these devices in varying degrees. If provided, additional security and
deployment best practices from the manufacturers of these devices should be followed.
Some legacy and constrained devices might not have been designed specifically for IoT deployment. These devices
might lack the capability to encrypt data, connect with the Internet, or provide advanced auditing. In these cases, a
modern and secure field gateway can aggregate data from legacy devices and provide the security required for
connecting these devices over the Internet. Field gateways can provide secure authentication, negotiation of
encrypted sessions, receipt of commands from the cloud, and many other security features.

See also
To learn more about securing your IoT solution, see:
IoT Security Architecture
Secure your IoT deployment
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Internet of Things security architecture
5/29/2018 • 24 min to read • Edit Online

When designing a system, it is important to understand the potential threats to that system, and add appropriate
defenses accordingly, as the system is designed and architected. It is important to design the product from the
start with security in mind because understanding how an attacker might be able to compromise a system helps
make sure appropriate mitigations are in place from the beginning.

Security starts with a threat model


Microsoft has long used threat models for its products and has made the company’s threat modeling process
publically available. The company experience demonstrates that the modeling has unexpected benefits beyond the
immediate understanding of what threats are the most concerning. For example, it also creates an avenue for an
open discussion with others outside the development team, which can lead to new ideas and improvements in the
product.
The objective of threat modeling is to understand how an attacker might be able to compromise a system and
then make sure appropriate mitigations are in place. Threat modeling forces the design team to consider
mitigations as the system is designed rather than after a system is deployed. This fact is critically important,
because retrofitting security defenses to a myriad of devices in the field is infeasible, error prone and leaves
customers at risk.
Many development teams do an excellent job capturing the functional requirements for the system that benefit
customers. However, identifying non-obvious ways that someone might misuse the system is more challenging.
Threat modeling can help development teams understand what an attacker might do and why. Threat modeling is
a structured process that creates a discussion about the security design decisions in the system, as well as changes
to the design that are made along the way that impact security. While a threat model is simply a document, this
documentation also represents an ideal way to ensure continuity of knowledge, retention of lessons learned, and
help new team onboard rapidly. Finally, an outcome of threat modeling is to enable you to consider other aspects
of security, such as what security commitments you wish to provide to your customers. These commitments in
conjunction with threat modeling inform and drive testing of your Internet of Things (IoT) solution.
When to threat model
Threat modeling offers the greatest value when you incorporate it into the design phase. When you are designing,
you have the greatest flexibility to make changes to eliminate threats. Eliminating threats by design is the desired
outcome. It is much easier than adding mitigations, testing them, and ensuring they remain current and moreover,
such elimination is not always possible. It becomes harder to eliminate threats as a product becomes more mature,
and in turn ultimately requires more work and a lot harder tradeoffs than threat modeling early on in the
development.
What to threat model
You should threat model the solution as a whole and also focus in the following areas:
The security and privacy features
The features whose failures are security relevant
The features that touch a trust boundary
Who threat models
Threat modeling is a process like any other. It is a good idea to treat the threat model document like any other
component of the solution and validate it. Many development teams do an excellent job capturing the functional
requirements for the system that benefit customers. However, identifying non-obvious ways that someone might
misuse the system is more challenging. Threat modeling can help development teams understand what an
attacker might do and why.
How to threat model
The threat modeling process is composed of four steps; the steps are:
Model the application
Enumerate Threats
Mitigate threats
Validate the mitigations
The process steps
Three rules of thumb to keep in mind when building a threat model:
1. Create a diagram out of reference architecture.
2. Start breadth-first. Get an overview, and understand the system as a whole, before deep-diving. This approach
helps ensure that you deep-dive in the right places.
3. Drive the process, don’t let the process drive you. If you find an issue in the modeling phase and want to
explore it, go for it! Don’t feel you need to follow these steps slavishly.
Threats
The four core elements of a threat model are:
Processes such as web services, Win32 services, and *nix daemons. Some complex entities (for example field
gateways and sensors) can be abstracted as a process when a technical drill-down in these areas is not possible.
Data stores (anywhere data is stored, such as a configuration file or database)
Data flow (where data moves between other elements in the application)
External Entities (anything that interacts with the system, but is not under the control of the application,
examples include users and satellite feeds)
All elements in the architectural diagram are subject to various threats; this article the STRIDE mnemonic. Read
Threat Modeling Again, STRIDE to know more about the STRIDE elements.
Different elements of the application diagram are subject to certain STRIDE threats:
Processes are subject to STRIDE
Data flows are subject to TID
Data stores are subject to TID, and sometimes R, when the data stores are log files.
External entities are subject to SRD

Security in IoT
Connected special-purpose devices have a significant number of potential interaction surface areas and interaction
patterns, all of which must be considered to provide a framework for securing digital access to those devices. The
term “digital access” is used here to distinguish from any operations that are carried out through direct device
interaction where access security is provided through physical access control. For example, putting the device into
a room with a lock on the door. While physical access cannot be denied using software and hardware, measures
can be taken to prevent physical access from leading to system interference.
As you explore the interaction patterns, look at “device control” and “device data” with the same level of attention.
“Device control” can be classified as any information that is provided to a device by any party with the goal of
changing or influencing its behavior towards its state or the state of its environment. “Device data” can be
classified as any information that a device emits to any other party about its state and the observed state of its
environment.
In order to optimize security best practices, it is recommended that a typical IoT architecture is divided into several
component/zones as part of the threat modeling exercise. These zones are described fully throughout this section
and include:
Device,
Field Gateway,
Cloud gateways, and
Services.
Zones are broad way to segment a solution; each zone often has its own data and authentication and authorization
requirements. Zones can also be used to isolation damage and restrict the impact of low trust zones on higher
trust zones.
Each zone is separated by a Trust Boundary, which is noted as the dotted red line in the following diagram. It
represents a transition of data/information from one source to another. During this transition, the
data/information could be subject to Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service
and Elevation of Privilege (STRIDE ).

The components depicted within each boundary are also subjected to STRIDE, enabling a full 360 threat modeling
view of the solution. The following sections elaborate on each of the components and specific security concerns
and solutions that should be put into place.
The following sections discuss standard components typically found in these zones.
The Device Zone
The device environment is the immediate physical space around the device where physical access and/or “local
network” peer-to-peer digital access to the device is feasible. A “local network” is assumed to be a network that is
distinct and insulated from – but potentially bridged to – the public Internet, and includes any short-range wireless
radio technology that permits peer-to-peer communication of devices. It does not include any network
virtualization technology creating the illusion of such a local network and it does also not include public operator
networks that require any two devices to communicate across public network space if they were to enter a peer-to-
peer communication relationship.
The Field Gateway Zone
Field gateway is a device/appliance or some general-purpose server computer software that acts as
communication enabler and, potentially, as a device control system and device data processing hub. The field
gateway zone includes the field gateway itself and all devices that are attached to it. As the name implies, field
gateways act outside dedicated data processing facilities, are usually location bound, are potentially subject to
physical intrusion, and has limited operational redundancy. All to say that a field gateway is commonly a thing one
can touch and sabotage while knowing what its function is.
A field gateway is different from a mere traffic router in that it has had an active role in managing access and
information flow, meaning it is an application addressed entity and network connection or session terminal. An
NAT device or firewall, in contrast, does not qualify as field gateways since they are not explicit connection or
session terminals, but rather a route (or block) connections or sessions made through them. The field gateway has
two distinct surface areas. One faces the devices that are attached to it and represents the inside of the zone, and
the other faces all external parties and is the edge of the zone.
The cloud gateway zone
Cloud gateway is a system that enables remote communication from and to devices or field gateways from several
different sites across public network space, typically towards a cloud-based control and data analysis system, a
federation of such systems. In some cases, a cloud gateway may immediately facilitate access to special-purpose
devices from terminals such as tablets or phones. In the context discussed here, “cloud” is meant to refer to a
dedicated data processing system that is not bound to the same site as the attached devices or field gateways. Also
in a Cloud Zone, operational measures prevent targeted physical access and are not necessarily exposed to a
“public cloud” infrastructure.
A cloud gateway may potentially be mapped into a network virtualization overlay to insulate the cloud gateway
and all of its attached devices or field gateways from any other network traffic. The cloud gateway itself is not a
device control system or a processing or storage facility for device data; those facilities interface with the cloud
gateway. The cloud gateway zone includes the cloud gateway itself along with all field gateways and devices
directly or indirectly attached to it. The edge of the zone is a distinct surface area where all external parties
communicate through.
The services zone
A “service” is defined for this context as any software component or module that is interfacing with devices
through a field- or cloud gateway for data collection and analysis, as well as for command and control. Services
are mediators. They act under their identity towards gateways and other subsystems, store and analyze data,
autonomously issue commands to devices based on data insights or schedules and expose information and
control capabilities to authorized end users.
Information-devices versus special-purpose devices
PCs, phones, and tablets are primarily interactive information devices. Phones and tablets are explicitly optimized
around maximizing battery lifetime. They preferably turn off partially when not immediately interacting with a
person, or when not providing services like playing music or guiding their owner to a particular location. From a
systems perspective, these information technology devices are mainly acting as proxies towards people. They are
“people actuators” suggesting actions and “people sensors” collecting input.
Special-purpose devices, from simple temperature sensors to complex factory production lines with thousands of
components inside them, are different. These devices are much more scoped in purpose and even if they provide
some user interface, they are largely scoped to interfacing with or be integrated into assets in the physical world.
They measure and report environmental circumstances, turn valves, control servos, sound alarms, switch lights,
and do many other tasks. They help to do work for which an information device is either too generic, too
expensive, too large, or too brittle. The concrete purpose immediately dictates their technical design as well the
available monetary budget for their production and scheduled lifetime operation. The combination of these two
key factors constrains the available operational energy budget, physical footprint, and thus available storage,
compute, and security capabilities.
If something “goes wrong” with automated or remote controllable devices, for example, physical defects or control
logic defects to willful unauthorized intrusion and manipulation. The production lots may be destroyed, buildings
may be looted or burned down, and people may be injured or even die. This is a whole different class of damage
than someone maxing out a stolen credit card's limit. The security bar for devices that make things move, and also
for sensor data that eventually results in commands that cause things to move, must be higher than in any e-
commerce or banking scenario.
Device control and device data interactions
Connected special-purpose devices have a significant number of potential interaction surface areas and interaction
patterns, all of which must be considered to provide a framework for securing digital access to those devices. The
term “digital access” is used here to distinguish from any operations that are carried out through direct device
interaction where access security is provided through physical access control. For example, putting the device into
a room with a lock on the door. While physical access cannot be denied using software and hardware, measures
can be taken to prevent physical access from leading to system interference.
As you explore the interaction patterns, look at “device control” and “device data” with the same level of attention
while threat modeling. “Device control” can be classified as any information that is provided to a device by any
party with the goal of changing or influencing its behavior towards its state or the state of its environment. “Device
data” can be classified as any information that a device emits to any other party about its state and the observed
state of its environment.

Threat modeling the Azure IoT reference architecture


Microsoft uses the framework outlined previously to do threat modeling for Azure IoT. The following section uses
the concrete example of Azure IoT Reference Architecture to demonstrate how to think about threat modeling for
IoT and how to address the threats identified. This example identifies four main areas of focus:
Devices and Data Sources,
Data Transport,
Device and Event Processing, and
Presentation

The following diagram provides a simplified view of Microsoft’s IoT Architecture using a Data Flow Diagram
model that is used by the Microsoft Threat Modeling Tool:
It is important to note that the architecture separates the device and gateway capabilities. This approach enables
the user to leverage gateway devices that are more secure: they are capable of communicating with the cloud
gateway using secure protocols, which typically requires greater processing overhead that a native device - such as
a thermostat - could provide on its own. In the Azure services zone, assume that the Cloud Gateway is represented
by the Azure IoT Hub service.
Device and data sources/data transport
This section explores the architecture outlined previously through the lens of threat modeling and gives an
overview of how to address some of the inherent concerns. This example focuses on the core elements of a threat
model:
Processes (both under your control and external items)
Communication (also called data flows)
Storage (also called data stores)
Processes
In each of the categories outlined in the Azure IoT architecture, this example tries to mitigate a number of different
threats across the different stages data/information exists in: process, communication, and storage. Following is an
overview of the most common ones for the “process” category, followed by an overview of how these threats
could be best mitigated:
Spoofing (S ): An attacker may extract cryptographic key material from a device, either at the software or
hardware level, and subsequently access the system with a different physical or virtual device under the identity of
the device the key material has been taken from. A good illustration is remote controls that can turn any TV and
that are popular prankster tools.
Denial of Service (D ): A device can be rendered incapable of functioning or communicating by interfering with
radio frequencies or cutting wires. For example, a surveillance camera that had its power or network connection
intentionally knocked out cannot report data, at all.
Tampering (T): An attacker may partially or wholly replace the software running on the device, potentially
allowing the replaced software to leverage the genuine identity of the device if the key material or the
cryptographic facilities holding key materials were available to the illicit program. For example, an attacker may
leverage extracted key material to intercept and suppress data from the device on the communication path and
replace it with false data that is authenticated with the stolen key material.
Information Disclosure (I ): If the device is running manipulated software, such manipulated software could
potentially leak data to unauthorized parties. For example, an attacker may leverage extracted key material to
inject itself into the communication path between the device and a controller or field gateway or cloud gateway to
siphon off information.
Elevation of Privilege (E ): A device that does specific function can be forced to do something else. For example,
a valve that is programmed to open half way can be tricked to open all the way.

COMPONENT THREAT MITIGATION RISK IMPLEMENTATION

Device S Assigning identity to Replacing device or Authenticating the


the device and part of the device device, using
authenticating the with some other Transport Layer
device device. How do you Security (TLS) or
know you are talking IPSec. Infrastructure
to the right device? should support using
pre-shared key (PSK)
on those devices that
cannot handle full
asymmetric
cryptography.
Leverage Azure AD,
OAuth

TRID Apply tamperproof The risk is if someone The most effective


mechanisms to the is tampering the mitigation is a trusted
device, for example, device (physical platform module
by making it hard to interference). How are (TPM) capability that
impossible to extract you sure, that device allows storing keys in
keys and other has not been special on-chip
cryptographic tampered with. circuitry from which
material from the the keys cannot be
device. read, but can only be
used for
cryptographic
operations that use
the key but never
disclose the key.
Memory encryption
of the device. Key
management for the
device. Signing the
code.

E Having access control If the device allows for Having authorization


of the device. individual actions to scheme for the device
Authorization be performed based
scheme. on commands from
an outside source, or
even compromised
sensors, it allows the
attack to perform
operations not
otherwise accessible.

Field Gateway S Authenticating the If someone can spoof TLS RSA/PSK, IPSec,
Field gateway to Field Gateway, then it RFC 4279. All the
Cloud Gateway (such can present itself as same key storage and
as cert based, PSK, or any device. attestation concerns
Claim based.) of devices in general –
best case is use TPM.
6LowPAN extension
for IPSec to support
Wireless Sensor
Networks (WSN).
COMPONENT THREAT MITIGATION RISK IMPLEMENTATION

TRID Protect the Field Spoofing attacks that Memory encryption,


Gateway against trick the cloud TPM’s, authentication.
tampering (TPM?) gateway thinking it is
talking to field
gateway could result
in information
disclosure and data
tampering

E Access control
mechanism for Field
Gateway

Here are some examples of threats in this category:


Spoofing: An attacker may extract cryptographic key material from a device, either at the software or hardware
level, and subsequently access the system with a different physical or virtual device under the identity of the device
the key material has been taken from.
Denial of Service: A device can be rendered incapable of functioning or communicating by interfering with radio
frequencies or cutting wires. For example, a surveillance camera that had its power or network connection
intentionally knocked out cannot report data, at all.
Tampering: An attacker may partially or wholly replace the software running on the device, potentially allowing
the replaced software to leverage the genuine identity of the device if the key material or the cryptographic
facilities holding key materials were available to the illicit program.
Tampering: A surveillance camera that’s showing a visible-spectrum picture of an empty hallway could be aimed
at a photograph of such a hallway. A smoke or fire sensor could be reporting someone holding a lighter under it.
In either case, the device may be technically fully trustworthy towards the system, but it reports manipulated
information.
Tampering: An attacker may leverage extracted key material to intercept and suppress data from the device on
the communication path and replace it with false data that is authenticated with the stolen key material.
Tampering: An attacker may partially or completely replace the software running on the device, potentially
allowing the replaced software to leverage the genuine identity of the device if the key material or the
cryptographic facilities holding key materials were available to the illicit program.
Information Disclosure: If the device is running manipulated software, such manipulated software could
potentially leak data to unauthorized parties.
Information Disclosure: An attacker may leverage extracted key material to inject itself into the communication
path between the device and a controller or field gateway or cloud gateway to siphon off information.
Denial of Service: The device can be turned off or turned into a mode where communication is not possible
(which is intentional in many industrial machines).
Tampering: The device can be reconfigured to operate in a state unknown to the control system (outside of
known calibration parameters) and thus provide data that can be misinterpreted
Elevation of Privilege: A device that does specific function can be forced to do something else. For example, a
valve that is programmed to open half way can be tricked to open all the way.
Denial of Service: The device can be turned into a state where communication is not possible.
Tampering: The device can be reconfigured to operate in a state unknown to the control system (outside of
known calibration parameters) and thus provide data that can be misinterpreted.
Spoofing/Tampering/Repudiation: If not secured (which is rarely the case with consumer remote controls), an
attacker can manipulate the state of a device anonymously. A good illustration is remote controls that can turn any
TV and that are popular prankster tools.
Communication
Threats around communication path between devices, devices and field gateways, and device and cloud gateway.
The following table has some guidance around open sockets on the device/VPN:

COMPONENT THREAT MITIGATION RISK IMPLEMENTATION

Device IoT Hub TID (D)TLS (PSK/RSA) to Eavesdropping or Security on the


encrypt the traffic interfering the protocol level. With
communication custom protocols, you
between the device need to figure out
and the gateway how to protect them.
In most cases, the
communication takes
place from the device
to the IoT Hub (device
initiates the
connection).

Device Device TID (D)TLS (PSK/RSA) to Reading data in Security on the


encrypt the traffic. transit between protocol level
devices. Tampering (MQTT/AMQP/HTTP/
with the data. CoAP. With custom
Overloading the protocols, you need
device with new to figure out how to
connections protect them. The
mitigation for the DoS
threat is to peer
devices through a
cloud or field gateway
and have them only
act as clients towards
the network. The
peering may result in
a direct connection
between the peers
after having been
brokered by the
gateway

External Entity Device TID Strong pairing of the Eavesdropping the Securely pairing the
external entity to the connection to the external entity to the
device device. Interfering the device NFC/Bluetooth
communication with LE. Controlling the
the device operational panel of
the device (Physical)

Field Gateway Cloud TID TLS (PSK/RSA) to Eavesdropping or Security on the


Gateway encrypt the traffic. interfering the protocol level
communication (MQTT/AMQP/HTTP/
between the device CoAP). With custom
and the gateway protocols, you need
to figure out how to
protect them.
COMPONENT THREAT MITIGATION RISK IMPLEMENTATION

Device Cloud TID TLS (PSK/RSA) to Eavesdropping or Security on the


Gateway encrypt the traffic. interfering the protocol level
communication (MQTT/AMQP/HTTP/
between the device CoAP). With custom
and the gateway protocols, you need
to figure out how to
protect them.

Here are some examples of threats in this category:


Denial of Service: Constrained devices are generally under DoS threat when they actively listen for inbound
connections or unsolicited datagrams on a network, because an attacker can open many connections in parallel
and not service them or service them slowly, or the device can be flooded with unsolicited traffic. In both cases, the
device can effectively be rendered inoperable on the network.
Spoofing, Information Disclosure: Constrained devices and special-purpose devices often have one-for-all
security facilities like password or PIN protection, or they wholly rely on trusting the network, meaning they grant
access to information when a device is on the same network, and that network is often only protected by a shared
key. That means that when the shared secret to device or network is disclosed, it is possible to control the device or
observe data emitted from the device.
Spoofing: an attacker may intercept or partially override the broadcast and spoof the originator (man in the
middle)
Tampering: an attacker may intercept or partially override the broadcast and send false information
Information Disclosure: an attacker may eavesdrop on a broadcast and obtain information without
authorization Denial of Service: an attacker may jam the broadcast signal and deny information distribution
Storage
Every device and field gateway has some form of storage (temporary for queuing the data, operating system (OS )
image storage).

COMPONENT THREAT MITIGATION RISK IMPLEMENTATION

Device storage TRID Storage encryption, Reading data from the Encryption, message
signing the logs storage (PII data), authentication code
tampering with (MAC), or digital
telemetry data. signature. Where
Tampering with possible, strong
queued or cached access control
command control through resource
data. Tampering with access control lists
configuration or (ACLs) or permissions.
firmware update
packages while
cached or queued
locally can lead to OS
and/or system
components being
compromised

Device OS image TRID Tampering with OS Read-only OS


/replacing the OS partition, signed OS
components image, Encryption
COMPONENT THREAT MITIGATION RISK IMPLEMENTATION

Field Gateway storage TRID Storage encryption, Reading data from the BitLocker
(queuing the data) signing the logs storage (PII data),
tampering with
telemetry data,
tampering with
queued or cached
command control
data. Tampering with
configuration or
firmware update
packages (destined
for devices or field
gateway) while cached
or queued locally can
lead to OS and/or
system components
being compromised

Field Gateway OS TRID Tampering with OS Read-only OS


image /replacing the OS partition, signed OS
components image, Encryption

Device and event processing/cloud gateway zone


A cloud gateway is system that enables remote communication from and to devices or field gateways from several
different sites across public network space, typically towards a cloud-based control and data analysis system, a
federation of such systems. In some cases, a cloud gateway may immediately facilitate access to special-purpose
devices from terminals such as tablets or phones. In the context discussed here, “cloud” is meant to refer to a
dedicated data processing system that is not bound to the same site as the attached devices or field gateways, and
where operational measures prevent targeted physical access but is not necessarily to a “public cloud”
infrastructure. A cloud gateway may potentially be mapped into a network virtualization overlay to insulate the
cloud gateway and all of its attached devices or field gateways from any other network traffic. The cloud gateway
itself is not a device control system or a processing or storage facility for device data; those facilities interface with
the cloud gateway. The cloud gateway zone includes the cloud gateway itself along with all field gateways and
devices directly or indirectly attached to it.
Cloud gateway is mostly custom built piece of software running as a service with exposed endpoints to which field
gateway and devices connect. As such it must be designed with security in mind. Follow SDL process for
designing and building this service.
Services zone
A control system (or controller) is a software solution that interfaces with a device, or a field gateway, or cloud
gateway for the purpose of controlling one or multiple devices and/or to collect and/or store and/or analyze
device data for presentation, or subsequent control purposes. Control systems are the only entities in the scope of
this discussion that may immediately facilitate interaction with people. The exceptions are intermediate physical
control surfaces on devices, like a switch that allows a person to turn off the device or change other properties, and
for which there is no functional equivalent that can be accessed digitally.
Intermediate physical control surfaces are those where governing logic constrains the function of the physical
control surface such that an equivalent function can be initiated remotely or input conflicts with remote input can
be avoided – such intermediated control surfaces are conceptually attached to a local control system that leverages
the same underlying functionality as any other remote control system that the device may be attached to in
parallel. Top threats to the cloud computing can be read at Cloud Security Alliance (CSA) page.

Additional resources
For more information, see the following articles:
SDL Threat Modeling Tool
Microsoft Azure IoT reference architecture

See also
To learn more about securing your IoT solution see, Secure your IoT deployment
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Secure your IoT deployment
5/29/2018 • 7 min to read • Edit Online

This article provides the next level of detail for securing the Azure IoT-based Internet of Things (IoT)
infrastructure. It links to implementation level details for configuring and deploying each component. It also
provides comparisons and choices between various competing methods.
Securing the Azure IoT deployment can be divided into the following three security areas:
Device Security: Securing the IoT device while it is deployed in the wild.
Connection Security: Ensuring all data transmitted between the IoT device and IoT Hub is confidential and
tamper-proof.
Cloud Security: Providing a means to secure data while it moves through, and is stored in the cloud.

Secure device provisioning and authentication


The IoT solution accelerators secure IoT devices by the following two methods:
By providing a unique identity key (security tokens) for each device, which can be used by the device to
communicate with the IoT Hub.
By using an on-device X.509 certificate and private key as a means to authenticate the device to the IoT Hub.
This authentication method ensures that the private key on the device is not known outside the device at any
time, providing a higher level of security.
The security token method provides authentication for each call made by the device to IoT Hub by associating the
symmetric key to each call. X.509-based authentication allows authentication of an IoT device at the physical layer
as part of the TLS connection establishment. The security-token-based method can be used without the X.509
authentication, which is a less secure pattern. The choice between the two methods is primarily dictated by how
secure the device authentication needs to be, and availability of secure storage on the device (to store the private
key securely).

IoT Hub security tokens


IoT Hub uses security tokens to authenticate devices and services to avoid sending keys on the network.
Additionally, security tokens are limited in time validity and scope. Azure IoT SDKs automatically generate tokens
without requiring any special configuration. Some scenarios, however, require the user to generate and use
security tokens directly. These scenarios include the direct use of the MQTT, AMQP, or HTTP surfaces, or the
implementation of the token service pattern.
More details on the structure of the security token and its usage can be found in the following articles:
Security token structure
Using SAS tokens as a device
Each IoT Hub has an identity registry that can be used to create per-device resources in the service, such as a
queue that contains in-flight cloud-to-device messages, and to allow access to the device-facing endpoints. The
IoT Hub identity registry provides secure storage of device identities and security keys for a solution. Individual or
groups of device identities can be added to an allow list, or a block list, enabling complete control over device
access. The following articles provide more details on the structure of the identity registry and supported
operations.
IoT Hub supports protocols such as MQTT, AMQP, and HTTP. Each of these protocols uses security tokens from
the IoT device to IoT Hub differently:
AMQP: SASL PL AIN and AMQP Claims-based security ( {policyName}@sas.root.{iothubName} with IoT hub-
level tokens; {deviceId} with device-scoped tokens).
MQTT: CONNECT packet uses {deviceId} as the {ClientId} , {IoThubhostname}/{deviceId} in the Username
field and a SAS token in the Password field.
HTTP: Valid token is in the authorization request header.
IoT Hub identity registry can be used to configure per-device security credentials and access control. However, if
an IoT solution already has a significant investment in a custom device identity registry and/or authentication
scheme, it can be integrated into an existing infrastructure with IoT Hub by creating a token service.
X.509 certificate -based device authentication
The use of a device-based X.509 certificate and its associated private and public key pair allows additional
authentication at the physical layer. The private key is stored securely in the device and is not discoverable outside
the device. The X.509 certificate contains information about the device, such as device ID, and other organizational
details. A signature of the certificate is generated by using the private key.
High-level device provisioning flow:
Associate an identifier to a physical device – device identity and/or X.509 certificate associated to the device
during device manufacturing or commissioning.
Create a corresponding identity entry in IoT Hub – device identity and associated device information in the IoT
Hub identity registry.
Securely store X.509 certificate thumbprint in IoT Hub identity registry.
Root certificate on device
While establishing a secure TLS connection with IoT Hub, the IoT device authenticates IoT Hub using a root
certificate that is part of the device SDK. For the C client SDK, the certificate is located under the folder "\c\certs"
under the root of the repo. Though these root certificates are long-lived, they still may expire or be revoked. If
there is no way of updating the certificate on the device, the device may not be able to subsequently connect to the
IoT Hub (or any other cloud service). Having a means to update the root certificate once the IoT device is
deployed effectively mitigates this risk.

Securing the connection


Internet connection between the IoT device and IoT Hub is secured using the Transport Layer Security (TLS )
standard. Azure IoT supports TLS 1.2, TLS 1.1, and TLS 1.0, in this order. Support for TLS 1.0 is provided for
backward compatibility only. If possible, use TLS 1.2 as it provides the most security.

Securing the cloud


Azure IoT Hub allows definition of access control policies for each security key. It uses the following set of
permissions to grant access to each of IoT Hub's endpoints. Permissions limit the access to an IoT Hub based on
functionality.
RegistryRead. Grants read access to the identity registry. For more information, see identity registry.
RegistryReadWrite. Grants read and write access to the identity registry. For more information, see identity
registry.
ServiceConnect. Grants access to cloud service-facing communication and monitoring endpoints. For
example, it grants permission to back-end cloud services to receive device-to-cloud messages, send cloud-to-
device messages, and retrieve the corresponding delivery acknowledgments.
DeviceConnect. Grants access to device-facing endpoints. For example, it grants permission to send device-
to-cloud messages and receive cloud-to-device messages. This permission is used by devices.
There are two ways to obtain DeviceConnect permissions with IoT Hub with security tokens: using a device
identity key, or a shared access key. Moreover, it is important to note that all functionality accessible from devices
is exposed by design on endpoints with prefix /devices/{deviceId} .
Service components can only generate security tokens using shared access policies granting the appropriate
permissions.
Azure IoT Hub and other services that may be part of the solution allow management of users using the Azure
Active Directory.
Data ingested by Azure IoT Hub can be consumed by a variety of services such as Azure Stream Analytics and
Azure blob storage. These services allow management access. Read more about these services and available
options:
Azure Cosmos DB: A scalable, fully-indexed database service for semi-structured data that manages metadata
for the devices you provision, such as attributes, configuration, and security properties. Azure Cosmos DB
offers high-performance and high-throughput processing, schema-agnostic indexing of data, and a rich SQL
query interface.
Azure Stream Analytics: Real-time stream processing in the cloud that enables you to rapidly develop and
deploy a low -cost analytics solution to uncover real-time insights from devices, sensors, infrastructure, and
applications. The data from this fully-managed service can scale to any volume while still achieving high
throughput, low latency, and resiliency.
Azure App Services: A cloud platform to build powerful web and mobile apps that connect to data anywhere; in
the cloud or on-premises. Build engaging mobile apps for iOS, Android, and Windows. Integrate with your
Software as a Service (SaaS ) and enterprise applications with out-of-the-box connectivity to dozens of cloud-
based services and enterprise applications. Code in your favorite language and IDE (.NET, Node.js, PHP,
Python, or Java) to build web apps and APIs faster than ever.
Logic Apps: The Logic Apps feature of Azure App Service helps integrate your IoT solution to your existing
line-of-business systems and automate workflow processes. Logic Apps enables developers to design
workflows that start from a trigger and then execute a series of steps—rules and actions that use powerful
connectors to integrate with your business processes. Logic Apps offers out-of-the-box connectivity to a vast
ecosystem of SaaS, cloud-based, and on-premises applications.
Azure blob storage: Reliable, economical cloud storage for the data that your devices send to the cloud.

Conclusion
This article provides overview of implementation level details for designing and deploying an IoT infrastructure
using Azure IoT. Configuring each component to be secure is key in securing the overall IoT infrastructure. The
design choices available in Azure IoT provide some level of flexibility and choice; however, each choice may have
security implications. It is recommended that each of these choices be evaluated through a risk/cost assessment.

See also
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Device Authentication using X.509 CA Certificates
5/29/2018 • 4 min to read • Edit Online

This article describes how to use X.509 Certificate Authority (CA) certificates to authenticate devices connecting
IoT Hub. In this article you will learn:
How to get an X.509 CA certificate
How to register the X.509 CA certificate to IoT Hub
How to sign devices using X.509 CA certificates
How devices signed with X.509 CA are authenticated

Overview
The X.509 CA feature enables device authentication to IoT Hub using a Certificate Authority (CA). It greatly
simplifies initial device enrollment process, and supply chain logistics during device manufacturing. Learn more in
this scenario article about the value of using X.509 CA certificates for device authentication. We encourage you to
read this scenario article before proceeding as it explains why the steps that follow exist.

Prerequisite
Using the X.509 CA feature requires that you have an IoT Hub account. Learn how to create an IoT Hub instance if
you don't already have one.

How to get an X.509 CA certificate


The X.509 CA certificate is at the top of the chain of certificates for each of your devices. You may purchase or
create one depending on how you intend to use it.
For production environment, we recommend that you purchase an X.509 CA certificate from a public root
certificate authority. Purchasing a CA certificate has the benefit of the root CA acting as a trusted third party to
vouch for the legitimacy of your devices. Consider this option if you intend your devices to be part of an open IoT
network where they are expected to interact with third-party products or services.
You may also create a self-signed X.509 CA for experimentation or for use in closed IoT networks.
Regardless of how you obtain your X.509 CA certificate, make sure to keep it's corresponding private key secret
and protected at all times. This is necessary for trust building trust in the X.509 CA authentication.
Learn how to create a self-signed CA certificate, which you can use for experimentation throughout this feature
description.

Sign devices into the certificate chain of trust


The owner of an X.509 CA certificate can cryptographically sign an intermediate CA who can in turn sign another
intermediate CA, and so on, until the last intermediate CA terminates this process by signing a device. The result is
a cascaded chain of certificates known as a certificate chain of trust. In real life this plays out as delegation of trust
towards signing devices. This delegation is important because it establishes a cryptographically variable chain of
custody and avoids sharing of signing keys.
Learn here how to create a certificate chain as done when signing devices.

How to register the X.509 CA certificate to IoT Hub


Register your X.509 CA certificate to IoT Hub where it will be used to authenticate your devices during registration
and connection. Registering the X.509 CA certificate is a two-step process that comprises certificate file upload and
proof of possession.
The upload process entails uploading a file that contains your certificate. This file should never contain any private
keys.
The proof of possession step involves a cryptographic challenge and response process between you and IoT Hub.
Given that digital certificate contents are public and therefore susceptible to eavesdropping, IoT Hub would like to
ascertain that you really own the CA certificate. It shall do so by generating a random challenge that you must sign
with the CA certificate's corresponding private key. If you kept the private key secret and protected as earlier
advised, then only you will possess the knowledge to complete this step. Secrecy of private keys is the source of
trust in this method. After signing the challenge, complete this step by uploading a file containing the results.
Learn here how to register your CA certificate.

How to create a device on IoT Hub


To preclude device impersonation, IoT Hub requires you to let it know what devices to expect. You do this by
creating a device entry in the IoT Hub's device registry. This process is automated when using IoT Hub Device
Provisioning Service (DPS ).
Learn here how to manually create a device in IoT Hub.

Authenticating devices signed with X.509 CA certificates


With X.509 CA certificate registered and devices signed into a certificate chain of trust, what remains is device
authentication when the device connects, even for the first time. When an X.509 CA signed device connects, it
uploads its certificate chain for validation. The chain includes all intermediate CA and device certificates. With this
information, IoT Hub authenticates the device in a two-step process. IoT Hub cryptographically validates the
certificate chain for internal consistency, and then issues a proof-of-possession challenge to the device. IoT Hub
declares the device authentic on a successful proof-of-possession response from the device. This declaration
assumes that the device's private key is protected and that only the device can successfully respond to this
challenge. We recommend use of secure chips like Hardware Secure Modules (HSM ) in devices to protect private
keys.
A successful device connection to IoT Hub completes the authentication process and is also indicative of a proper
setup.
Learn here how to complete this device connection step.

Next Steps
Learn about the value of X.509 CA authentication in IoT.
Get started with IoT Hub Device Provisioning Service.
Conceptual understanding of X.509 CA certificates in
the IoT industry
5/29/2018 • 11 min to read • Edit Online

This article describes the value of using X.509 certificate authority (CA) certificates in IoT device manufacturing
and authentication to IoT Hub. It includes information about supply chain setup and highlight advantages.
This article describes:
What X.509 CA certificates are and how to get them
How to register your X.509 CA certificate to IoT Hub
How to set up a manufacturing supply chain for X.509 CA-based authentication
How devices signed with X.509 CA connect to IoT Hub

Overview
X.509 Certificate Authority (CA) authentication is an approach for authenticating devices to IoT Hub using a
method that dramatically simplifies device identity creation and life-cycle management in the supply chain.
A distinguishing attribute of the X.509 CA authentication is a one-to-many relationship a CA certificate has with
its downstream devices. This relationship enables registration of any number of devices into IoT Hub by
registering an X.509 CA certificate once, otherwise device unique certificates must be pre-registered for every
device before a device can connect. This one-to-many relationship also simplifies device certificates life-cycle
management operations.
Another important attribute of the X.509 CA authentication is simplification of supply chain logistics. Secure
authentication of devices requires that each device holds a unique secret like a key as basis for trust. In certificates-
based authentication, this secret is a private key. A typical device manufacturing flow involves multiple steps and
custodians. Securely managing device private keys across multiple custodians and maintaining trust is difficult and
expensive. Using certificate authorities solves this problem by signing each custodian into a cryptographic chain of
trust rather than entrusting them with device private keys. Each custodian in turn signs devices at their respective
process step of the manufacturing flow. The overall result is an optimal supply chain with built-in accountability
through use of the cryptographic chain of trust. It is worth noting that this process yields the most security when
devices protect their unique private keys. To this end, we urge the use of Hardware Secure Modules (HSM )
capable of internally generating private keys that will never see the light of day.
This article offers an end-to-end view of using the X.509 CA authentication, from supply chain setup to device
connection, while making use of a real world example to solidify understanding.

Introduction
The X.509 CA certificate is a digital certificate whose holder can sign other certificates. This digital certificate is
X.509 because it conforms to a certificate formatting standard prescribed by IETF's RFC 5280 standard, and is a
certificate authority (CA) because its holder can sign other certificates.
The use of X.509 CA is best understood in relation to a concrete example. Consider Company-X, a maker of
Smart-X-Widgets designed for professional installation. Company-X outsources both manufacturing and
installation. It contracts manufacturer Factory-Y to manufacture the Smart-X-Widgets, and service provider
Technician-Z to install. Company-X desires that Smart-X-Widget directly ships from Factory-Y to Technician-Z for
installation and that it connects directly to Company-X's instance of IoT Hub after installation without further
intervention from Company-X. To make this happen, Company-X need to complete a few one-time setup
operations to prime Smart-X-Widget for automatic connection. With the end-to-end scenario in mind, the rest of
this article is structured as follows:
Acquire the X.509 CA certificate
Register X.509 CA certificate to IoT Hub
Sign devices into a certificate chain of trust
Device connection

Acquire the X.509 CA certificate


Company-X has the option of purchasing an X.509 CA certificate from a public root certificate authority or
creating one through a self-signed process. One option would be optimal over the other depending on the
application scenario. Regardless of the option, the process entails two fundamental steps, generating a
public/private key pair and signing the public key into a certificate.

Details on how to accomplish these steps differ with various service providers.
Purchasing an X.509 CA certificate
Purchasing a CA certificate has the benefit of having a well-known root CA act as a trusted third party to vouch
for the legitimacy of IoT devices when the devices connect. Company-X would choose this option if they intend
Smart-X-Widget to interact with third party products or services after initial connection to IoT Hub.
To purchase an X.509 CA certificate, Company-X would choose a root certificates services provider. An internet
search for the phrase 'Root CA' will yield good leads. The root CA will guide Company-X on how to create the
public/private key pair and how to generate a Certificate Signing Request (CSR ) for their services. A CSR is the
formal process of applying for a certificate from a certificate authority. The outcome of this purchase is a certificate
for use as an authority certificate. Given the ubiquity of X.509 certificates, the certificate is likely to have been
properly formatted to IETF's RFC 5280 standard.
Creating a Self-Signed X.509 CA certificate
The process to create a Self-Signed X.509 CA certificate is similar to purchasing with the exception of involving a
third party signer like the root certificate authority. In our example, Company-X will sign its authority certificate
instead of a root certificate authority. Company-X may choose this option for testing until they're ready to
purchase an authority certificate. Company-X may also use a self-signed X.509 CA certificate in production, if
Smart-X-Widget is not intended to connect to any third party services outside of the IoT Hub.

Register the X.509 certificate to IoT Hub


Company-X needs to register the X.509 CA to IoT Hub where it will serve to authenticate Smart-X-Widgets as
they connect. This is a one-time process that enables the ability to authenticate and manage any number of Smart-
X-Widget devices. This process is one-time because of a one-to-many relationship between authority certificate
and devices and also constitutes one of the main advantages of using the X.509 CA authentication method. The
alternative is to upload individual certificate thumbprints for each and every Smart-X-Widget device thereby
adding to operational costs.
Registering the X.509 CA certificate is a two-step process, the certificate upload and certificate proof-of-
possession.

X.509 CA Certificate Upload


The X.509 CA certificate upload process is just that, upload the CA certificate to IoT Hub. IoT Hub expects the
certificate in a file. Company-X simply uploads the certificate file. The certificate file MUST NOT under any
circumstances contain any private keys. Best practices from standards governing Public Key Infrastructure (PKI)
mandates that knowledge of Company-X's private in this case resides exclusively within Company-X.
Proof-of-Possession of the Certificate
The X.509 CA certificate, just like any digital certificate, is public information that is susceptible to eavesdropping.
As such, an eavesdropper may intercept a certificate and try to upload it as their own. In our example, IoT Hub
would like to make sure that the CA certificate Company-X is uploading really belongs to Company-X. It does so
by challenging Company-X to proof that they in fact possess the certificate through a proof-of-possession (PoP )
flow. The proof-of-possession flow entails IoT Hub generating a random number to be signed by Company-X
using its private key. If Company-X followed PKI best practices and protected their private key then only they
would be in position to correctly respond to the proof-of-possession challenge. IoT Hub proceeds to register the
X.509 CA certificate upon a successful response of the proof-of-possession challenge.
A successful response to the proof-of-possession challenge from IoT Hub completes the X.509 CA registration.
Sign Devices into a Certificate Chain of Trust
IoT requires every device to possess a unique identity. These identities are in the form certificates for certificate-
based authentication schemes. In our example, this means every Smart-X-Widget must possess a unique device
certificate. How does Company-X setup for this in its supply chain?
One way to go about this is to pre-generate certificates for Smart-X-Widgets and entrusting knowledge of
corresponding unique device private keys with supply chain partners. For Company-X, this means entrusting
Factory-Y and Technician-Z. While this is a valid method, it comes with challenges that must be overcome to
ensure trust as follows:
1. Having to share device private keys with supply chain partners, besides ignoring PKI best practices of never
sharing private keys, makes building trust in the supply chain expensive. It means capital systems like
secure rooms to house device private keys, and processes like periodic security audits need to be installed.
Both add cost to the supply chain.
2. Securely accounting for devices in the supply chain and later managing them in deployment becomes a
one-to-one task for every key-to-device pair from the point of device unique certificate (hence private key)
generation to device retirement. This precludes group management of devices unless the concept of groups
is explicitly built into the process somehow. Secure accounting and device life-cycle management, therefore,
becomes a heavy operations burden. In our example, Company-X would bear this burden.
X.509 CA certificate authentication offers elegant solutions to afore listed challenges through the use of certificate
chains. A certificate chain results from a CA signing an intermediate CA that in turn signs another intermediate CA
and so goes on until a final intermediate CA signs a device. In our example, Company-X signs Factory-Y, which in
turn signs Technician-Z that finally signs Smart-X-Widget.

Above cascade of certificates in the chain presents the logical hand-off of authority. Many supply chains follow this
logical hand-off whereby each intermediate CA gets signed into the chain while receiving all upstream CA
certificates, and the last intermediate CA finally signs each device and inject all the authority certificates from the
chain into the device. This is common when the contract manufacturing company with a hierarchy of factories
commissions a particular factory to do the manufacturing. While the hierarchy may be several levels deep (for
example, by geography/product type/manufacturing line), only the factory at the end gets to interact with the
device but the chain is maintained from the top of the hierarchy.
Alternate chains may have different intermediate CA interact with the device in which case the CA interacting with
the device injects certificate chain content at that point. Hybrid models are also possible where only some of the
CA has physical interaction with the device.
In our example, both Factory-Y and Technician-Z interact with the Smart-X-Widget. While Company-X owns
Smart-X-Widget, it actually does not physically interact with it in the entire supply chain. The certificate chain of
trust for Smart-X-Widget therefore comprise Company-X signing Factory-Y which in turn signs Technician-Z that
will then provide final signature to Smart-X-Widget. The manufacture and installation of Smart-X-Widget
comprise Factory-Y and Technician-Z using their respective intermediate CA certificates to sign each and every
Smart-X-Widgets. The end result of this entire process is Smart-X-Widgets with unique device certificates and
certificate chain of trust going up to Company-X CA certificate.
This is a good point to review the value of the X.509 CA method. Instead of pre-generating and handing off
certificates for every Smart-X-Widget into the supply chain, Company-X only hand to sign Factory-Y once. Instead
of having to track every device throughout the devices life-cycle, Company-X may not track and manage devices
through groups that naturally emerge from the supply chain process, for example, devices installed by Technician-
Z after July of some year.
Last but not least, the CA method of authentication infuses secure accountability into the device manufacturing
supply chain. Because of the certificate chain process, the actions of every member in the chain is
cryptographically recorded and verifiable.
This process relies on certain assumptions that must be surfaced for completeness. It requires independent
creation of device unique public/private key pair and that the private key be protected within the device.
Fortunately, secure silicon chips in the form of Hardware Secure Modules (HSM ) capable of internally generating
keys and protecting private keys exist. Company-X only need to add one of such chips into Smart-X-Widget's
component bill of materials.

Device Connection
Previous sections above have been building up to device connection. By simply registering an X.509 CA certificate
to IoT Hub one time, how do potentially millions of devices connect and get authenticated from the first time?
Simple; through the same certificate upload and proof-of-possession flow we earlier encountered with registering
the X.509 CA certificate.
Devices manufactured for X.509 CA authentication are equipped with device unique certificates and a certificate
chain from their respective manufacturing supply chain. Device connection, even for the very first time, happens in
a two-step process: certificate chain upload and proof-of-possession.
During the certificate chain upload, the device uploads its device unique certificate together with the certificate
chain installed within it to IoT Hub. Using the pre-registered X.509 CA certificate, IoT Hub can cryptographically
validate a couple of things, that the uploaded certificate chain is internally consistent, and that the chain was
originated by the valid owner of the X.509 CA certificate. Just was with the X.509 CA registration process, IoT Hub
would initiate a proof-of-possession challenge-response process to ascertain that the chain and hence device
certificate actually belongs to the device uploading it. It does so by generating a random challenge to be signed by
the device using its private key for validation by IoT Hub. A successful response triggers IoT Hub to accept the
device as authentic and grant it connection.
In our example, each Smart-X-Widget would upload its device unique certificate together with Factory-Y and
Technician-Z X.509 CA certificates and then respond to the proof-of-possession challenge from IoT Hub.
Notice that the foundation of trust rests in protecting private keys including device private keys. We therefore
cannot stress enough the importance of secure silicon chips in the form of Hardware Secure Modules (HSM ) for
protecting device private keys, and the overall best practice of never sharing any private keys, like one factory
entrusting another with its private key.
Set up X.509 security in your Azure IoT hub
5/29/2018 • 6 min to read • Edit Online

This tutorial simulates the steps you need to secure your Azure IoT hub using the X.509 Certificate Authentication.
For the purpose of illustration, we will show how to use the open source tool OpenSSL to create certificates locally
on your Windows machine. We recommend that you use this tutorial for test purposes only. For production
environment, you should purchase the certificates from a root certificate authority (CA ).

Prerequisites
This tutorial requires that you have the following resources ready:
You have created an IoT hub with your Azure subscription. See Create an IoT hub through portal for detailed
steps.
You have Visual Studio 2015 or Visual Studio 2017 installed on your machine.

Get X.509 CA certificates


The X.509 certificate-based security in the IoT Hub requires you to start with an X.509 certificate chain, which
includes the root certificate as well as any intermediate certificates up until the leaf certificate.
You may choose either of the following ways to get your certificates:
Purchase X.509 certificates from a root certificate authority (CA ). This is recommended for production
environments. OR,
Create your own X.509 certificates using a third party tool such as OpenSSL. This will be fine for test and
development purposes. The sections titled Create your X.509 certificates and Create X.509 certificate chain in
the article How to use PowerShell to create X.509 certificates walk you through a sample PowerShell script to
create the certificates using OpenSSL and PowerShell. If you prefer to use Bash shell instead of PowerShell,
please refer to the related sections of Managing CA Certificates Sample. The rest of this tutorial will use the
OpenSSL environment set up in this How to guide to walk you through the end-to-end X.509 security in Azure
IoT Hub.

Register X.509 CA certificates to your IoT hub


These steps show you how to add a new Certificate Authority to your IoT hub through the portal.
1. In the Azure portal, navigate to your IoT hub and open the SETTINGS > Certificates menu.
2. Click Add to add a new certificate.
3. Enter a friendly display name to your certificate. Select the root certificate file named RootCA.cer created in the
previous section, from your machine. Click Upload.
4. Once you get a notification that your certificate is successfully uploaded, click Save.
This will show your certificate in the Certificate Explorer list. Note the STATUS of this certificate is
Unverified.
5. Click on the certificate that you added in the previous step.
6. In the Certificate Details blade, click Generate Verification Code.
7. It creates a Verification Code to validate the certificate ownership. Copy the code to your clipboard.
8. Now, you need to sign this Verification Code with the private key associate with your X.509 CA certificate,
which generates a signature. There are tools available to perform this signing process, for example,
OpenSSL. This is known as the Proof of possession. If you have used our sample PowerShell scripts in the
previous section, then run the script mentioned in the section titled Proof of possession of your X.509 CA
certificate.
9. Upload the resulting signature from step 8 above to your IoT hub in the portal. In the Certificate Details
blade on the Azure portal, navigate to the Verification Certificate .pem or .cer file, and select the
signature, for example, VerifyCert4.cer created by the sample PowerShell command using the File Explorer
icon besides it.
10. Once the certificate is successfuly uploaded, click Verify. The STATUS of your certificate changes to
Verified in the Certificates blade. Click Refresh if it does not update automatically.
Create an X.509 device for your IoT hub
1. In the Azure portal, navigate to your IoT hub's Device Explorer.
2. Click Add to add a new device.
3. Give a friendly display name for the Device ID, and select X.509 CA Signed as the Authentication Type.
Click Save.

Authenticate your X.509 device with the X.509 certificates


To authenticate your X.509 device, you need to first sign the device with the CA certificate. Signing of leaf devices
is normally done at the manufacturing plant, where manufacturing tools have been enabled accordingly. As the
device goes from one manufacturer to another, each manufacturer’s signing action is captured as an intermediate
certificate within the chain. The end result is a certificate chain from the CA certificate to the device’s leaf
certificate. If you have been using our PowerShell scripts in the previous sections, then you can run the script
mentioned in the section titled Create leaf X.509 certificate for your device in the article PowerShell scripts to
manage CA-signed X.509 certificates to simulate this process.
Next, we will show you how to create a C# application to simulate the X.509 device registered for your IoT hub.
We will send temperature and humidity values from the simulated device to your hub. Note that in this tutorial, we
will create only the device application. It is left as an exercise to the readers to create the IoT Hub service
application that will send response to the events sent by this simulated device. The C# application assumes that
you have followed the PowerShell scripts mentioned in the article PowerShell scripts to manage CA-signed X.509
certificates
1. In Visual Studio, create a new Visual C# Windows Classic Desktop project by using the Console Application
project template. Name the project SimulateX509Device.

2. In Solution Explorer, right-click the SimulateX509Device project, and then click Manage NuGet
Packages.... In the NuGet Package Manager window, select Browse and search for
microsoft.azure.devices.client. Select Install to install the Microsoft.Azure.Devices.Client package,
and accept the terms of use. This procedure downloads, installs, and adds a reference to the Azure IoT
device SDK NuGet package and its dependencies.
3. Add the following lines of code at the top of the Program.cs file:

using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;
using System.Security.Cryptography.X509Certificates;

4. Add the following lines of code inside the Program class:

private static int MESSAGE_COUNT = 5;


private const int TEMPERATURE_THRESHOLD = 30;
private static String deviceId = "<your-device-id>";
private static float temperature;
private static float humidity;
private static Random rnd = new Random();

Use the friendly device name you used in the preceding section in place of <your_device_id> placeholder.
5. Add the following function to create random numbers for temperature and humidity and send these values
to the hub:
static async Task SendEvent(DeviceClient deviceClient)
{
string dataBuffer;
Console.WriteLine("Device sending {0} messages to IoTHub...\n", MESSAGE_COUNT);

for (int count = 0; count < MESSAGE_COUNT; count++)


{
temperature = rnd.Next(20, 35);
humidity = rnd.Next(60, 80);
dataBuffer = string.Format("{{\"deviceId\":\"{0}\",\"messageId\":{1},\"temperature\":
{2},\"humidity\":{3}}}", deviceId, count, temperature, humidity);
Message eventMessage = new Message(Encoding.UTF8.GetBytes(dataBuffer));
eventMessage.Properties.Add("temperatureAlert", (temperature > TEMPERATURE_THRESHOLD) ? "true" :
"false");
Console.WriteLine("\t{0}> Sending message: {1}, Data: [{2}]", DateTime.Now.ToLocalTime(), count,
dataBuffer);

await deviceClient.SendEventAsync(eventMessage);
}
}

6. Finally, add the following lines of code to the Main function, replacing the placeholders device-id, your-iot-
hub -name and absolute-path-to -your-device-pfx-file as required by your setup.

try
{
var cert = new X509Certificate2(@"<absolute-path-to-your-device-pfx-file>", "123");
var auth = new DeviceAuthenticationWithX509Certificate("<device-id>", cert);
var deviceClient = DeviceClient.Create("<your-iot-hub-name>.azure-devices.net", auth,
TransportType.Amqp_Tcp_Only);

if (deviceClient == null)
{
Console.WriteLine("Failed to create DeviceClient!");
}
else
{
Console.WriteLine("Successfully created DeviceClient!");
SendEvent(deviceClient).Wait();
}

Console.WriteLine("Exiting...\n");
}
catch (Exception ex)
{
Console.WriteLine("Error in sample: {0}", ex.Message);
}

This code connects to your IoT hub by creating the connection string for your X.509 device. Once
successfully connected, it then sends temperature and humidity events to the hub, and waits for its
response.
7. Since this application accesses a .pfx file, you need to execute this in Admin mode. Build the Visual Studio
solution. Open a new command window as an Administrator, and navigate to the folder containing this
solution. Navigate to the bin/Debug path within the solution folder. Run the application
SimulateX509Device.exe from the Admin command window. You should see your device successfully
connecting to the hub and sending the events.
See also
To learn more about securing your IoT solution, see:
IoT Security Best Practices
IoT Security Architecture
Secure your IoT deployment
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
PowerShell scripts to manage CA-signed X.509
certificates
5/29/2018 • 6 min to read • Edit Online

The X.509 certificate-based security in the IoT Hub requires you to start with an X.509 certificate chain, which
includes the root certificate as well as any intermediate certificates up until the leaf certificate. This How to guide
walks you through sample PowerShell scripts that use OpenSSL to create and sign X.509 certificates. We
recommend you to use this guide for experimentation only, since many of these steps will happen during
manufacturing process in the real world. You can use these certificates to simulate security in your Azure IoT hub
using the X.509 Certificate Authentication. The steps in this guide create certificates locally on your Windows
machine.

Prerequisites
This tutorial assumes that you have acquired the OpenSSL binaries. You may either
download the OpenSSL source code and build the binaries on your machine, or
download and install any third-party OpenSSL binaries, for example, from this project on SourceForge.

Create X.509 certificates


The following steps show an example of how to create the X.509 root certificates locally.
1. Open a PowerShell window as an Administrator.
NOTE: You must open this in PowerShell itself, not PowerShell ISE, Visual Studio Code, or other tools that
wrap the underlying PowerShell console. Using a non-console based PowerShell will result in openssl
commands below hanging.
2. Navigate to your working directory. Run the following script to set the global variables.

$openSSLBinSource = "<full_path_to_the_binaries>\OpenSSL\bin"
$errorActionPreference = "stop"

# Note that these values are for test purpose only


$_rootCertCommonName = "Azure IoT Root CA"
$_rootCertSubject = "CN=$_rootCertCommonName"
$_intermediateCertSubject = "Azure IoT Intermediate {0} CA"
$_privateKeyPassword = "123"

$rootCACerFileName = "./RootCA.cer"
$rootCAPemFileName = "./RootCA.pem"
$intermediate1CAPemFileName = "./Intermediate1.pem"
$intermediate2CAPemFileName = "./Intermediate2.pem"
$intermediate3CAPemFileName = "./Intermediate3.pem"

$openSSLBinDir = Join-Path $ENV:TEMP "openssl-bin"

# Whether to use ECC or RSA.


$useEcc = $true

3. Run the following script that copies the OpenSSL binaries to your working directory and sets the
environment variables:
function Initialize-CAOpenSSL()
{
Write-Host ("Beginning copy of openssl binaries to {0} (and setting up env variables...)" -f
$openSSLBinDir)
if (-not (Test-Path $openSSLBinDir))
{
mkdir $openSSLBinDir | Out-Null
}

robocopy $openSSLBinSource $openSSLBinDir * /s


robocopy $openSSLBinSource . * /s

Write-Host "Setting up PATH and other environment variables."


$ENV:PATH += "; $openSSLBinDir"
$ENV:OPENSSL_CONF = Join-Path $openSSLBinDir "openssl.cnf"

Write-Host "Success"
}
Initialize-CAOpenSSL

4. Next, run the following script that searches whether a certificate by the specified Subject Name is already
installed, and whether OpenSSL is configured correctly on your machine:

function Get-CACertBySubjectName([string]$subjectName)
{
$certificates = gci -Recurse Cert:\LocalMachine\ |? { $_.gettype().name -eq "X509Certificate2" }
$cert = $certificates |? { $_.subject -eq $subjectName -and $_.PSParentPath -eq
"Microsoft.PowerShell.Security\Certificate::LocalMachine\My" }
if ($NULL -eq $cert)
{
throw ("Unable to find certificate with subjectName {0}" -f $subjectName)
}

write $cert
}
function Test-CAPrerequisites()
{
$certInstalled = $null
try
{
$certInstalled = Get-CACertBySubjectName $_rootCertSubject
}
catch {}

if ($NULL -ne $certInstalled)


{
throw ("Certificate {0} already installed. Cleanup CA certs 1st" -f $_rootCertSubject)
}

if ($NULL -eq $ENV:OPENSSL_CONF)


{
throw ("OpenSSL not configured on this system. Run 'Initialize-CAOpenSSL' (even if you've
already done so) to set everything up.")
}
Write-Host "Success"
}
Test-CAPrerequisites

If everything is configured correctly, you should see "Success" message.

Create X.509 certificate chain


Create a certificate chain with a root CA, for example, "CN=Azure IoT Root CA" that this sample uses, by running
the following PowerShell script. This script also updates your Windows OS certificate store, as well creates
certificate files in your working directory.
1. The following script creates a PowerShell function to create a self signed certificate, for a given Subject
Name and signing authority.

function New-CASelfsignedCertificate([string]$commonName, [object]$signingCert, [bool]$isASigner=$true)


{
# Build up argument list
$selfSignedArgs =@{"-DnsName"=$commonName;
"-CertStoreLocation"="cert:\LocalMachine\My";
"-NotAfter"=(get-date).AddDays(30);
}

if ($isASigner -eq $true)


{
$selfSignedArgs += @{"-KeyUsage"="CertSign"; }
$selfSignedArgs += @{"-TextExtension"= @(("2.5.29.19={text}ca=TRUE&pathlength=12")); }
}
else
{
$selfSignedArgs += @{"-TextExtension"= @("2.5.29.37={text}1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.1",
"2.5.29.19={text}ca=FALSE&pathlength=0") }
}

if ($signingCert -ne $null)


{
$selfSignedArgs += @{"-Signer"=$signingCert }
}

if ($useEcc -eq $true)


{
$selfSignedArgs += @{"-KeyAlgorithm"="ECDSA_nistP256";
"-CurveExport"="CurveName" }
}

# Now use splatting to process this


Write-Host ("Generating certificate {0} which is for prototyping, NOT PRODUCTION. It will expire in
30 days." -f $subjectName)
write (New-SelfSignedCertificate @selfSignedArgs)
}

2. The following PowerShell function creates intermediate X.509 certificates using the preceding function as
well as the OpenSSL binaries.

function New-CAIntermediateCert([string]$commonName,
[Microsoft.CertificateServices.Commands.Certificate]$signingCert, [string]$pemFileName)
{
$certFileName = ($commonName + ".cer")
$newCert = New-CASelfsignedCertificate $commonName $signingCert
Export-Certificate -Cert $newCert -FilePath $certFileName -Type CERT | Out-Null
Import-Certificate -CertStoreLocation "cert:\LocalMachine\CA" -FilePath $certFileName | Out-Null

# Store public PEM for later chaining


openssl x509 -inform deer -in $certFileName -out $pemFileName

del $certFileName

write $newCert
}

3. The following PowerShell function creates the X.509 certificate chain. Read Certificate chains for more
information.
function New-CACertChain()
{
Write-Host "Beginning to install certificate chain to your LocalMachine\My store"
$rootCACert = New-CASelfsignedCertificate $_rootCertSubject $null

Export-Certificate -Cert $rootCACert -FilePath $rootCACerFileName -Type CERT


Import-Certificate -CertStoreLocation "cert:\LocalMachine\Root" -FilePath $rootCACerFileName

openssl x509 -inform der -in $rootCACerFileName -out $rootCAPemFileName

$intermediateCert1 = New-CAIntermediateCert ($_intermediateCertSubject -f "1") $rootCACert


$intermediate1CAPemFileName
$intermediateCert2 = New-CAIntermediateCert ($_intermediateCertSubject -f "2") $intermediateCert1
$intermediate2CAPemFileName
$intermediateCert3 = New-CAIntermediateCert ($_intermediateCertSubject -f "3") $intermediateCert2
$intermediate3CAPemFileName
Write-Host "Success"
}

This script creates a file named RootCA.cer in your working directory.


4. Finally, use the PowerShell functions above to create the X.509 certificate chain, by running the command
New-CACertChain in your PowerShell window.

Proof of possession of your X.509 CA certificate


This script performs the Proof of Possession flow for your X.509 certificate.
In the PowerShell window on your desktop, run the following code:

function New-CAVerificationCert([string]$requestedSubjectName)
{
$verifyRequestedFileName = ".\verifyCert4.cer"
$rootCACert = Get-CACertBySubjectName $_rootCertSubject
Write-Host "Using Signing Cert:::"
Write-Host $rootCACert

$verifyCert = New-CASelfsignedCertificate $requestedSubjectName $rootCACert $false

Export-Certificate -cert $verifyCert -filePath $verifyRequestedFileName -Type Cert


if (-not (Test-Path $verifyRequestedFileName))
{
throw ("Error: CERT file {0} doesn't exist" -f $verifyRequestedFileName)
}

Write-Host ("Certificate with subject {0} has been output to {1}" -f $requestedSubjectName, (Join-Path
(get-location).path $verifyRequestedFileName))
}
New-CAVerificationCert "<your verification code>"

This code creates a certificate with the given subject name, signed by the CA, as a file named VerifyCert4.cer in
your working directory. This certificate file will help validate with your IoT hub that you have the signing
permission (that is, the private key) of this CA.

Create leaf X.509 certificate for your device


This section shows you can use a PowerShell script that creates a leaf device certificate and the corresponding
certificate chain.
In the PowerShell window on your local machine, run the following script to create a CA-signed X.509 certificate
for this device:
function New-CADevice([string]$deviceName, [string]$signingCertSubject=$_rootCertSubject)
{
$newDevicePfxFileName = ("./{0}.pfx" -f $deviceName)
$newDevicePemAllFileName = ("./{0}-all.pem" -f $deviceName)
$newDevicePemPrivateFileName = ("./{0}-private.pem" -f $deviceName)
$newDevicePemPublicFileName = ("./{0}-public.pem" -f $deviceName)

$signingCert = Get-CACertBySubjectName $signingCertSubject ## "CN=Azure IoT CA Intermediate 1 CA"

$newDeviceCertPfx = New-CASelfSignedCertificate $deviceName $signingCert $false

$certSecureStringPwd = ConvertTo-SecureString -String $_privateKeyPassword -Force -AsPlainText

# Export the PFX of the cert we've just created. The PFX is a format that contains both public and
private keys.
Export-PFXCertificate -cert $newDeviceCertPfx -filePath $newDevicePfxFileName -password
$certSecureStringPwd
if (-not (Test-Path $newDevicePfxFileName))
{
throw ("Error: CERT file {0} doesn't exist" -f $newDevicePfxFileName)
}

# Begin the massaging. First, turn the PFX into a PEM file which contains public key, private key, and
other attributes.
Write-Host ("When prompted for password by openssl, enter the password as {0}" -f $_privateKeyPassword)
openssl pkcs12 -in $newDevicePfxFileName -out $newDevicePemAllFileName -nodes

# Convert the PEM to get formats we can process


if ($useEcc -eq $true)
{
openssl ec -in $newDevicePemAllFileName -out $newDevicePemPrivateFileName
}
else
{
openssl rsa -in $newDevicePemAllFileName -out $newDevicePemPrivateFileName
}
openssl x509 -in $newDevicePemAllFileName -out $newDevicePemPublicFileName

Write-Host ("Certificate with subject {0} has been output to {1}" -f $cnNewDeviceSubjectName, (Join-Path
(get-location).path $newDevicePemPublicFileName))
}

Then run New-CADevice "<yourTestDevice>" in your PowerShell window, using the friendly name that you used to
create your device. When prompted for the password for the CA's private key, enter "123". This creates a .pfx file in
your working directory.

Clean up certificates
In your start bar or Settings app, search for and select Manage computer certificates. Remove any certificates
issued by Azure IoT CA TestOnly*. These certificates should exist in the following three locations:
Certificates - Local Computer > Personal > Certificates
Certificates - Local Computer > Trusted Root Certification Authorities > Certificates
Certificates - Local Computer > Intermediate Certificate Authorities > Certificates
Use iothub-explorer to send and receive messages
between your device and IoT Hub
5/29/2018 • 2 min to read • Edit Online

NOTE
Before you start this tutorial, set up your device. In the article, you set up your Azure IoT device and IoT hub, and you
deploy a sample application to run on your device. The application sends collected sensor data to your IoT hub.

iothub-explorer has a handful of commands that makes IoT Hub management easier. This tutorial focuses on
how to use iothub-explorer to send and receive messages between your device and your IoT hub.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are
only available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to
choose the right IoT Hub tier.

What you will learn


You learn how to use iothub-explorer to monitor device-to-cloud messages and to send cloud-to-device
messages. Device-to-cloud messages could be sensor data that your device collects and then sends to your IoT
hub. Cloud-to-device messages could be commands that your IoT hub sends to your device to blink an LED that
is connected to your device.

What you will do


Use iothub-explorer to monitor device-to-cloud messages.
Use iothub-explorer to send cloud-to-device messages.

What you need


Tutorial Setup your device completed which covers the following requirements:
An active Azure subscription.
An Azure IoT hub under your subscription.
A client application that sends messages to your Azure IoT hub.
iothub-explorer. (Install iothub-explorer)
Monitor device-to-cloud messages
To monitor messages that are sent from your device to your IoT hub, follow these steps:
1. Open a console window.
2. Run the following command:

iothub-explorer monitor-events <device-id> --login "<IoTHubConnectionString>"

NOTE
Get <device-id> and <IoTHubConnectionString> from your IoT hub. Make sure you've finished the previous
tutorial. Or you can try to use
iothub-explorer monitor-events <device-id> --login "HostName=<my-hub>.azure-
devices.net;SharedAccessKeyName=<my-policy>;SharedAccessKey=<my-policy-key>"
if you have HostName , SharedAccessKeyName and SharedAccessKey .

Send cloud-to-device messages


To send a message from your IoT hub to your device, follow these steps:
1. Open a console window.
2. Start a session on your IoT hub by running the following command:

iothub-explorer login `<IoTHubConnectionString>`

3. Send a message to your device by running the following command:

iothub-explorer send <device-id> <message>

The command blinks the LED that is connected to your device and sends the message to your device.

NOTE
There is no need for the device to send a separate ack command back to your IoT hub upon receiving the message.

Next steps
You’ve learned how to monitor device-to-cloud messages and send cloud-to-device messages between your IoT
device and Azure IoT Hub.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Save IoT hub messages that contain sensor data to
your Azure blob storage
5/29/2018 • 3 min to read • Edit Online

NOTE
Before you start this tutorial, set up your device. In the article, you set up your Azure IoT device and IoT hub, and you
deploy a sample application to run on your device. The application sends collected sensor data to your IoT hub.

What you learn


You learn how to create an Azure storage account and an Azure function app to store IoT hub messages in your
blob storage.

What you do
Create an Azure storage account.
Prepare your IoT hub to route messages to storage.

What you need


Set up your device to cover the following requirements:
An active Azure subscription
An IoT hub under your subscription
A running application that sends messages to your IoT hub

Create an Azure storage account


1. In the Azure portal, click Create a resource > Storage > Storage account > Create.
2. Enter the necessary information for the storage account:
Name: The name of the storage account. The name must be globally unique.
Resource group: Use the same resource group that your IoT hub uses.
Pin to dashboard: Select this option for easy access to your IoT hub from the dashboard.
3. Click Create.

Prepare your IoT hub to route messages to storage


IoT Hub natively supports routing messages to Azure storage as blobs. To know more about the Azure IoT Hub
custom endpoints, you can refer to List of built-in IoT Hub endpoints.
Add storage as a custom endpoint
Navigate to your IoT hub in the Azure portal. Click Endpoints > Add. Name the endpoint and select Azure
Storage Container as the endpoint type. Use the picker to select the storage account you created in the
previous section. Create a storage container and select it, then click OK.
Add a route to route data to storage
Click Routes > Add and enter a name for the route. Select Device Messages as the data source, and select the
storage endpoint you just created as the endpoint in the route. Enter true as the query string, then click Save.
Add a route for hot path telemetry (optional)
By default, IoT Hub routes all messages which do not match any other routes to the built-in endpoint. Since all
telemetry messages now match the rule which routes the messages to storage, you need to add another route
for messages to be written to the built-in endpoint. There is no additional charge to route messages to multiple
endpoints.

NOTE
You can skip this step if you are not doing additional processing on your telemetry messages.

Click Add from the Routes pane and enter a name for the route. Select Device Messages as the data source
and events as the endpoint. Enter true as the query string, then click Save.
Verify your message in your storage container
1. Run the sample application on your device to send messages to your IoT hub.
2. Download and install Azure Storage Explorer.
3. Open Storage Explorer, click Add an Azure Account > Sign in, and then sign in to your Azure account.
4. Click your Azure subscription > Storage Accounts > your storage account > Blob Containers > your
container.
You should see messages sent from your device to your IoT hub logged in the blob container.

Next steps
You’ve successfully created your Azure storage account and routed messages from IoT Hub to a blob container
in that storage account.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Visualize real-time sensor data from Azure IoT Hub
using Power BI
5/29/2018 • 4 min to read • Edit Online

NOTE
Before you start this tutorial, set up your device. In the article, you set up your Azure IoT device and IoT hub, and you
deploy a sample application to run on your device. The application sends collected sensor data to your IoT hub.

What you learn


You learn how to visualize real-time sensor data that your Azure IoT hub receives by Power BI. If you want to try
visualize the data in your IoT hub with Web Apps, please see Use Azure Web Apps to visualize real-time sensor
data from Azure IoT Hub.

What you do
Get your IoT hub ready for data access by adding a consumer group.
Create, configure and run a Stream Analytics job for data transfer from your IoT hub to your Power BI
account.
Create and publish a Power BI report to visualize the data.

What you need


Tutorial Setup your device completed which covers the following requirements:
An active Azure subscription.
An Azure IoT hub under your subscription.
A client application that sends messages to your Azure IoT hub.
A Power BI account. (Try Power BI for free)

Add a consumer group to your IoT hub


Consumer groups are used by applications to pull data from Azure IoT Hub. In this tutorial, you create a
consumer group to be used by a coming Azure service to read data from your IoT hub.
To add a consumer group to your IoT hub, follow these steps:
1. In the Azure portal, open your IoT hub.
2. In the left pane, click Endpoints, select Events on the middle pane, enter a name under Consumer
groups on the right pane, and then click Save.

Create, configure, and run a Stream Analytics job


Create a Stream Analytics job
1. In the Azure portal, click Create a resource > Internet of Things > Stream Analytics job.
2. Enter the following information for the job.
Job name: The name of the job. The name must be globally unique.
Resource group: Use the same resource group that your IoT hub uses.
Location: Use the same location as your resource group.
Pin to dashboard: Check this option for easy access to your IoT hub from the dashboard.

3. Click Create.
Add an input to the Stream Analytics job
1. Open the Stream Analytics job.
2. Under Job Topology, click Inputs.
3. In the Inputs pane, click Add, and then enter the following information:
Input alias: The unique alias for the input.
Source: Select IoT hub.
Consumer group: Select the consumer group you just created.
4. Click Create.

Add an output to the Stream Analytics job


1. Under Job Topology, click Outputs.
2. In the Outputs pane, click Add, and then enter the following information:
Output alias: The unique alias for the output.
Sink: Select Power BI.
3. Click Authorize, and then sign into your Power BI account.
4. Once authorized, enter the following information:
Group Workspace: Select your target group workspace.
Dataset Name: Enter a dataset name.
Table Name: Enter a table name.
5. Click Create.
Configure the query of the Stream Analytics job
1. Under Job Topology, click Query.
2. Replace [YourInputAlias] with the input alias of the job.
3. Replace [YourOutputAlias] with the output alias of the job.
4. Click Save.

Run the Stream Analytics job


In the Stream Analytics job, click Start > Now > Start. Once the job successfully starts, the job status changes
from Stopped to Running.
Create and publish a Power BI report to visualize the data
1. Ensure the sample application is running on your device. If not, you can refer to the tutorials under Setup
your device.
2. Sign in to your Power BI account.
3. Go to the group workspace that you set when you created the output for the Stream Analytics job.
4. Click Streaming datasets.
You should see the listed dataset that you specified when you created the output for the Stream Analytics
job.
5. Under ACTIONS, click the first icon to create a report.

6. Create a line chart to show real-time temperature over time.


a. On the report creation page, add a line chart.
b. On the Fields pane, expand the table that you specified when you created the output for the Stream
Analytics job.
c. Drag EventEnqueuedUtcTime to Axis on the Visualizations pane.
d. Drag temperature to Values.
Now a line chart is created. The x-axis displays date and time in the UTC time zone. The y-axis
displays temperature from the sensor.

7. Create another line chart to show real-time humidity over time. To do this, follow the same steps above
and place EventEnqueuedUtcTime on the x-axis and humidity on the y-axis.

8. Click Save to save the report.


9. Click File > Publish to web.
10. Click Create embed code, and then click Publish.
You're provided the report link that you can share with anyone for report access and a code snippet to integrate
the report into your blog or website.
Microsoft also offers the Power BI mobile apps for viewing and interacting with your Power BI dashboards and
reports on your mobile device.

Next steps
You’ve successfully used Power BI to visualize real-time sensor data from your Azure IoT hub. There is an
alternate way to visualize data from Azure IoT Hub. See Use Azure Web Apps to visualize real-time sensor data
from Azure IoT Hub.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Visualize real-time sensor data from your Azure IoT
hub by using the Web Apps feature of Azure App
Service
5/29/2018 • 4 min to read • Edit Online

NOTE
Before you start this tutorial, set up your device. In the article, you set up your Azure IoT device and IoT hub, and you
deploy a sample application to run on your device. The application sends collected sensor data to your IoT hub.

What you learn


In this tutorial, you learn how to visualize real-time sensor data that your IoT hub receives by running a web
application that is hosted on a web app. If you want to try to visualize the data in your IoT hub by using Power
BI, see Use Power BI to visualize real-time sensor data from Azure IoT Hub.

What you do
Create a web app in the Azure portal.
Get your IoT hub ready for data access by adding a consumer group.
Configure the web app to read sensor data from your IoT hub.
Upload a web application to be hosted by the web app.
Open the web app to see real-time temperature and humidity data from your IoT hub.

What you need


Set up your device, which covers the following requirements:
An active Azure subscription
An Iot hub under your subscription
A client application that sends messages to your Iot hub
Download Git

Create a web app


1. In the Azure portal, click Create a resource > Web + Mobile > Web App.
2. Enter a unique job name, verify the subscription, specify a resource group and a location, select Pin to
dashboard, and then click Create.
We recommend that you select the same location as that of your resource group. Doing so assists with
processing speed and reduces the cost of data transfer.

Add a consumer group to your IoT hub


Consumer groups are used by applications to pull data from Azure IoT Hub. In this tutorial, you create a
consumer group to be used by a coming Azure service to read data from your IoT hub.
To add a consumer group to your IoT hub, follow these steps:
1. In the Azure portal, open your IoT hub.
2. In the left pane, click Endpoints, select Events on the middle pane, enter a name under Consumer
groups on the right pane, and then click Save.

Configure the web app to read data from your IoT hub
1. Open the web app you’ve just provisioned.
2. Click Application settings, and then, under App settings, add the following key/value pairs:
KEY VALUE

Azure.IoT.IoTHub.ConnectionString Obtained from iothub-explorer

Azure.IoT.IoTHub.ConsumerGroup The name of the consumer group that you add to your
IoT hub

3. Click Application settings, under General settings, toggle the Web sockets option, and then click
Save.

Upload a web application to be hosted by the web app


On GitHub, we've made available a web application that displays real-time sensor data from your IoT hub. All
you need to do is configure the web app to work with a Git repository, download the web application from
GitHub, and then upload it to Azure for the web app to host.
1. In the web app, click Deployment Options > Choose Source > Local Git Repository, and then click
OK.
2. Click Deployment Credentials, create a user name and password to use to connect to the Git
repository in Azure, and then click Save.
3. Click Overview, and note the value of Git clone url.

4. Open a command or terminal window on your local computer.


5. Download the web app from GitHub, and upload it to Azure for the web app to host. To do so, run the
following commands:

git clone https://github.com/Azure-Samples/web-apps-node-iot-hub-data-visualization.git


cd web-apps-node-iot-hub-data-visualization
git remote add webapp <Git clone URL>
git push webapp master:master

NOTE
<Git clone URL> is the URL of the Git repository found on the Overview page of the web app.
Open the web app to see real-time temperature and humidity data
from your IoT hub
On the Overview page of your web app, click the URL to open the web app.

You should see the real-time temperature and humidity data from your IoT hub.

NOTE
Ensure the sample application is running on your device. If not, you will get a blank chart, you can refer to the tutorials
under Setup your device.

Next steps
You've successfully used your web app to visualize real-time sensor data from your IoT hub.
For an alternative way to visualize data from Azure IoT Hub, see Use Power BI to visualize real-time sensor data
from your IoT hub.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Weather forecast using the sensor data from your
IoT hub in Azure Machine Learning
5/29/2018 • 5 min to read • Edit Online

NOTE
Before you start this tutorial, set up your device. In the article, you set up your Azure IoT device and IoT hub, and you
deploy a sample application to run on your device. The application sends collected sensor data to your IoT hub.

Machine learning is a technique of data science that helps computers learn from existing data to forecast future
behaviors, outcomes, and trends. Azure Machine Learning is a cloud predictive analytics service that makes it
possible to quickly create and deploy predictive models as analytics solutions.

What you learn


You learn how to use Azure Machine Learning to do weather forecast (chance of rain) using the temperature and
humidity data from your Azure IoT hub. The chance of rain is the output of a prepared weather prediction
model. The model is built upon historic data to forecast chance of rain based on temperature and humidity.

What you do
Deploy the weather prediction model as a web service.
Get your IoT hub ready for data access by adding a consumer group.
Create a Stream Analytics job and configure the job to:
Read temperature and humidity data from your IoT hub.
Call the web service to get the rain chance.
Save the result to an Azure blob storage.
Use Microsoft Azure Storage Explorer to view the weather forecast.

What you need


Tutorial Setup your device completed which covers the following requirements:
An active Azure subscription.
An Azure IoT hub under your subscription.
A client application that sends messages to your Azure IoT hub.
An Azure Machine Learning Studio account. (Try Machine Learning Studio for free).
Deploy the weather prediction model as a web service
1. Go to the weather prediction model page.
2. Click Open in Studio in Microsoft Azure Machine Learning Studio.

3. Click Run to validate the steps in the model. This step might take 2 minutes to complete.

4. Click SET UP WEB SERVICE > Predictive Web Service.


5. In the diagram, drag the Web service input module somewhere near the Score Model module.
6. Connect the Web service input module to the Score Model module.

7. Click RUN to validate the steps in the model.


8. Click DEPLOY WEB SERVICE to deploy the model as a web service.
9. On the dashboard of the model, download the Excel 2010 or earlier workbook for
REQUEST/RESPONSE.

NOTE
Ensure that you download the Excel 2010 or earlier workbook even if you are running a later version of Excel
on your computer.
10. Open the Excel workbook, make a note of the WEB SERVICE URL and ACCESS KEY.

Add a consumer group to your IoT hub


Consumer groups are used by applications to pull data from Azure IoT Hub. In this tutorial, you create a
consumer group to be used by a coming Azure service to read data from your IoT hub.
To add a consumer group to your IoT hub, follow these steps:
1. In the Azure portal, open your IoT hub.
2. In the left pane, click Endpoints, select Events on the middle pane, enter a name under Consumer
groups on the right pane, and then click Save.

Create, configure, and run a Stream Analytics job


Create a Stream Analytics job
1. In the Azure portal, click Create a resource > Internet of Things > Stream Analytics job.
2. Enter the following information for the job.
Job name: The name of the job. The name must be globally unique.
Resource group: Use the same resource group that your IoT hub uses.
Location: Use the same location as your resource group.
Pin to dashboard: Check this option for easy access to your IoT hub from the dashboard.

3. Click Create.
Add an input to the Stream Analytics job
1. Open the Stream Analytics job.
2. Under Job Topology, click Inputs.
3. In the Inputs pane, click Add, and then enter the following information:
Input alias: The unique alias for the input.
Source: Select IoT hub.
Consumer group: Select the consumer group you created.
4. Click Create.
Add an output to the Stream Analytics job
1. Under Job Topology, click Outputs.
2. In the Outputs pane, click Add, and then enter the following information:
Output alias: The unique alias for the output.
Sink: Select Blob Storage.
Storage account: The storage account for your blob storage. You can create a storage account or use an
existing one.
Container: The container where the blob is saved. You can create a container or use an existing one.
Event serialization format: Select CSV.

3. Click Create.
Add a function to the Stream Analytics job to call the web service you deployed
1. Under Job Topology, click Functions > Add.
2. Enter the following information:
Function Alias: Enter machinelearning .
Function Type: Select Azure ML.
Import option: Select Import from a different subscription.
URL: Enter the WEB SERVICE URL that you noted down from the Excel workbook.
Key: Enter the ACCESS KEY that you noted down from the Excel workbook.

3. Click Create.
Configure the query of the Stream Analytics job
1. Under Job Topology, click Query.
2. Replace the existing code with the following code:

WITH machinelearning AS (
SELECT EventEnqueuedUtcTime, temperature, humidity, machinelearning(temperature, humidity) as
result from [YourInputAlias]
)
Select System.Timestamp time, CAST (result.[temperature] AS FLOAT) AS temperature, CAST (result.
[humidity] AS FLOAT) AS humidity, CAST (result.[Scored Probabilities] AS FLOAT ) AS 'probabalities of
rain'
Into [YourOutputAlias]
From machinelearning

Replace [YourInputAlias] with the input alias of the job.


Replace [YourOutputAlias] with the output alias of the job.
3. Click Save.
Run the Stream Analytics job
In the Stream Analytics job, click Start > Now > Start. Once the job successfully starts, the job status changes
from Stopped to Running.
Use Microsoft Azure Storage Explorer to view the weather forecast
Run the client application to start collecting and sending temperature and humidity data to your IoT hub. For
each message that your IoT hub receives, the Stream Analytics job calls the weather forecast web service to
produce the chance of rain. The result is then saved to your Azure blob storage. Azure Storage Explorer is a tool
that you can use to view the result.
1. Download and install Microsoft Azure Storage Explorer.
2. Open Azure Storage Explorer.
3. Sign in to your Azure account.
4. Select your subscription.
5. Click your subscription > Storage Accounts > your storage account > Blob Containers > your container.
6. Open a .csv file to see the result. The last column records the chance of rain.
Summary
You’ve successfully used Azure Machine Learning to produce the chance of rain based on the temperature and
humidity data that your IoT hub receives.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Use iothub-explorer for Azure IoT Hub device
management
5/29/2018 • 3 min to read • Edit Online

NOTE
Before you start this tutorial, set up your device. In the article, you set up your Azure IoT device and IoT hub, and you deploy
a sample application to run on your device. The application sends collected sensor data to your IoT hub.

iothub-explorer is a CLI tool that you run on a host computer to manage device identities in your IoT hub registry.
It comes with management options that you can use to perform various tasks.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

MANAGEMENT OPTION TASK

Direct methods Make a device act such as starting or stopping sending


messages or rebooting the device.

Twin desired properties Put a device into certain states, such as setting an LED to
green or setting the telemetry send interval to 30 minutes.

Twin reported properties Get the reported state of a device. For example, the device
reports the LED is blinking now.

Twin tags Store device-specific metadata in the cloud. For example, the
deployment location of a vending machine.

Cloud-to-device messages Send notifications to a device. For example, "It is very likely to
rain today. Don't forget to bring an umbrella."

Device twin queries Query all device twins to retrieve those with arbitrary
conditions, such as identifying the devices that are available for
use.

For more detailed explanation on the differences and guidance on using these options, see Device-to-cloud
communication guidance and Cloud-to-device communication guidance.
Device twins are JSON documents that store device state information (metadata, configurations, and conditions).
IoT Hub persists a device twin for each device that connects to it. For more information about device twins, see Get
started with device twins.

What you learn


You learn using iothub-explorer with various management options on your development machine.

What you do
Run iothub-explorer with various management options.

What you need


Tutorial Setup your device completed which covers the following requirements:
An active Azure subscription.
An Azure IoT hub under your subscription.
A client application that sends messages to your Azure IoT hub.
Make sure your device is running with the client application during this tutorial.
iothub-explorer, Install iothub-explorer on your development machine.

Connect to your IoT hub


Connect to your IoT hub by running the following command:

iothub-explorer login <your IoT hub connection string>

Use iothub-explorer with direct methods


Invoke the start method in the device app to send messages to your IoT hub by running the following command:

iothub-explorer device-method <your device Id> start

Invoke the stop method in the device app to stop sending messages to your IoT hub by running the following
command:

iothub-explorer device-method <your device Id> stop

Use iothub-explorer with twin's desired properties


Set a desired property interval = 3000 by running the following command:

iothub-explorer update-twin <your device id> {\"properties\":{\"desired\":{\"interval\":3000}}}

This property can be read by your device.

Use iothub-explorer with twin's reported properties


Get the reported properties of the device by running the following command:

iothub-explorer get-twin <your device id>

One of the properties is $metadata.$lastUpdated which shows the last time this device sends or receives a
message.

Use iothub-explorer with twin's tags


Display the tags and properties of the device by running the following command:

iothub-explorer get-twin <your device id>

Add a field role = temperature&humidity to the device by running the following command:

iothub-explorer update-twin <your device id> "{\"tags\":{\"role\":\"temperature&humidity\"}}"

Use iothub-explorer with Cloud-to-device messages


Send a "Hello World" message to the device by running the following command:

iothub-explorer send <device-id> "Hello World"

See Use iothub-explorer to send and receive messages between your device and IoT Hub for a real scenario of
using this command.

Use iothub-explorer with device twins queries


Query devices with a tag of role = 'temperature&humidity' by running the following command:

iothub-explorer query-twin "SELECT * FROM devices WHERE tags.role = 'temperature&humidity'"

Query all devices except those with a tag of role = 'temperature&humidity' by running the following command:

iothub-explorer query-twin "SELECT * FROM devices WHERE tags.role != 'temperature&humidity'"

Next steps
You've learned how to use iothub-explorer with various management options.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Use the IoT extension for Azure CLI 2.0 for Azure
IoT Hub device management
5/29/2018 • 4 min to read • Edit Online

NOTE
Before you start this tutorial, set up your device. In the article, you set up your Azure IoT device and IoT hub, and you
deploy a sample application to run on your device. The application sends collected sensor data to your IoT hub.

The IoT extension for Azure CLI 2.0 is a new open source IoT extension that adds to the capabilities of Azure
CLI 2.0. Azure CLI 2.0 includes commands for interacting with Azure resource manager and management
endpoints. For example, you can use Azure CLI 2.0 to create an Azure VM or an IoT hub. A CLI extension
enables an Azure service to augment the Azure CLI giving you access to additional service-specific capabilities.
The IoT extension gives IoT developers command line access to all IoT Hub, IoT Edge, and IoT Hub Device
Provisioning Service capabilities.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

MANAGEMENT OPTION TASK

Direct methods Make a device act such as starting or stopping sending


messages or rebooting the device.

Twin desired properties Put a device into certain states, such as setting an LED to
green or setting the telemetry send interval to 30 minutes.

Twin reported properties Get the reported state of a device. For example, the device
reports the LED is blinking now.

Twin tags Store device-specific metadata in the cloud. For example, the
deployment location of a vending machine.

Device twin queries Query all device twins to retrieve those with arbitrary
conditions, such as identifying the devices that are available
for use.
For more detailed explanation on the differences and guidance on using these options, see Device-to-cloud
communication guidance and Cloud-to-device communication guidance.
Device twins are JSON documents that store device state information (metadata, configurations, and
conditions). IoT Hub persists a device twin for each device that connects to it. For more information about
device twins, see Get started with device twins.

What you learn


You learn using the IoT extension for Azure CLI 2.0 with various management options on your development
machine.

What you do
Run Azure CLI 2.0 and the IoT extension for Azure CLI 2.0 with various management options.

What you need


Tutorial Setup your device completed which covers the following requirements:
An active Azure subscription.
An Azure IoT hub under your subscription.
A client application that sends messages to your Azure IoT hub.
Make sure your device is running with the client application during this tutorial.
Python 2.7x or Python 3.x
Install Azure CLI 2.0. One simple way to install on Windows is to download and install the MSI. You can
also follow the installation instructions on Microsoft Docs to setup Azure CLI 2.0 in your environment. At
a minimum, your Azure CLI 2.0 version must be 2.0.24 or above. Use az –version to validate.
Install the IoT extension. The simplest way is to run az extension add --name azure-cli-iot-ext . The IoT
extension readme describes several ways to install the extension.

Log in to your Azure account


Log in to your Azure account by running the following command:

az login

Direct methods
az iot hub invoke-device-method --device-id <your device id> --hub-name <your hub name> --method-name <the
method name> --method-payload <the method payload>

Device twin desired properties


Set a desired property interval = 3000 by running the following command:

az iot hub device-twin update -n <your hub name> -d <your device id> --set properties.desired.interval =
3000

This property can be read from your device.


Device twin reported properties
Get the reported properties of the device by running the following command:

az iot hub device-twin show -n <your hub name> -d <your device id>

One of the twin reported properties is $metadata.$lastUpdated which shows the last time the device app
updated its reported property set.

Device twin tags


Display the tags and properties of the device by running the following command:

az iot hub device-twin show --hub-name <your hub name> --device-id <your device id>

Add a field role = temperature&humidity to the device by running the following command:

az iot hub device-twin update --hub-name <your hub name> --device-id <your device id> --set tags =
'{"role":"temperature&humidity"}}'

Device twin queries


Query devices with a tag of role = 'temperature&humidity' by running the following command:

az iot hub query --hub-name <your hub name> --query-command "SELECT * FROM devices WHERE tags.role =
'temperature&humidity'"

Query all devices except those with a tag of role = 'temperature&humidity' by running the following command:

az iot hub query --hub-name <your hub name> --query-command "SELECT * FROM devices WHERE tags.role !=
'temperature&humidity'"

Next steps
You’ve learned how to monitor device-to-cloud messages and send cloud-to-device messages between your IoT
device and Azure IoT Hub.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
IoT remote monitoring and notifications with Azure
Logic Apps connecting your IoT hub and mailbox
5/29/2018 • 4 min to read • Edit Online

NOTE
Before you start this tutorial, set up your device. In the article, you set up your Azure IoT device and IoT hub, and you
deploy a sample application to run on your device. The application sends collected sensor data to your IoT hub.

Azure Logic Apps provides a way to automate processes as a series of steps. A logic app can connect across
various services and protocols. It begins with a trigger such as 'When an account is added', and followed by a
combination of actions, one like 'sending a push notification'. This feature makes Logic Apps a perfect IoT
solution for IoT monitoring, such as staying alert for anomalies, among other usage scenarios.

What you learn


You learn how to create a logic app that connects your IoT hub and your mailbox for temperature monitoring
and notifications. When the temperature is above 30 C, the client application marks temperatureAlert = "true"
in the message it sends to your IoT hub. The message triggers the logic app to send you an email notification.

What you do
Create a service bus namespace and add a queue to it.
Add an endpoint and a routing rule to your IoT hub.
Create, configure, and test a logic app.

What you need


Tutorial Setup your device completed which covers the following requirements:
An active Azure subscription.
An Azure IoT hub under your subscription.
A client application that sends messages to your Azure IoT hub.

Create service bus namespace and add a queue to it


Create a service bus namespace
1. On the Azure portal, click Create a resource > Enterprise Integration > Service Bus.
2. Provide the following information:
2. Provide the following information:
Name: The name of the service bus.
Pricing tier: Click Basic > Select. The Basic tier is sufficient for this tutorial.
Resource group: Use the same resource group that your IoT hub uses.
Location: Use the same location that your IoT hub uses.
3. Click Create.

Add a service bus queue


1. Open the service bus namespace, and then click + Queue.
2. Enter a name for the queue and then click Create.
3. Open the service bus queue, and then click Shared access policies > + Add.
4. Enter a name for the policy, check Manage, and then click Create.
Add an endpoint and a routing rule to your IoT hub
Add an endpoint
1. Open your IoT hub, click Endpoints > + Add.
2. Enter the following information:
Name: The name of the endpoint.
Endpoint type: Select Service Bus Queue.
Service Bus namespace: Select the namespace you created.
Service Bus queue: Select the queue you created.
3. Click OK.

Add a routing rule


1. In your IoT hub, click Routes > + Add.
2. Enter the following information:
Name: The name of the routing rule.
Data source: Select DeviceMessages.
Endpoint: Select the endpoint you created.
Query string: Enter temperatureAlert = "true" .
3. Click Save.
Create and configure a logic app
Create a logic app
1. In the Azure portal, click Create a resource > Enterprise Integration > Logic App.
2. Enter the following information:
Name: The name of the logic app.
Resource group: Use the same resource group that your IoT hub uses.
Location: Use the same location that your IoT hub uses.
3. Click Create.
Configure the logic app
1. Open the logic app that opens into the Logic Apps Designer.
2. In the Logic Apps Designer, click Blank Logic App.
3. Click Service Bus.

4. Click Service Bus – When one or more messages arrive in a queue (auto-complete).
5. Create a service bus connection.
a. Enter a connection name.
b. Click the service bus namespace > the service bus policy > Create.
c. Click Continue after the service bus connection is created.
d. Select the queue that you created and enter 175 for Maximum message count

e. Click "Save" button to save the changes.


6. Create an SMTP service connection.
a. Click New step > Add an action.
b. Type SMTP , click the SMTP service in the search result, and then click SMTP - Send Email.
c. Enter the SMTP information of your mailbox, and then click Create.
Get the SMTP information for Hotmail/Outlook.com, Gmail, and Yahoo Mail.
d. Enter your email address for From and To, and High temperature detected for Subject and Body.
e. Click Save.
The logic app is in working order when you save it.

Test the logic app


1. Start the client application that you deploy to your device in Connect ESP8266 to Azure IoT Hub.
2. Increase the environment temperature around the SensorTag to be above 30 C. For example, light a candle
around your SensorTag.
3. You should receive an email notification sent by the logic app.

NOTE
Your email service provider may need to verify the sender identity to make sure it is you who sends the email.

Next steps
You have successfully created a logic app that connects your IoT hub and your mailbox for temperature
monitoring and notifications.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Use IoT DevKit AZ3166 with Azure Function and
Cognitive Services to make a language translator
5/29/2018 • 3 min to read • Edit Online

In this article, you learn how to make IoT DevKit as a language translator by using Azure Cognitive Services. It
records your voice and translates it to English text shown on the DevKit screen.
The MXChip IoT DevKit is an all-in-one Arduino compatible board with rich peripherals and sensors. You can
develop for it using Visual Studio Code extension for Arduino. And it comes with a growing projects catalog to
guide you prototype Internet of Things (IoT) solutions that take advantage of Microsoft Azure services.

What you need


Finish the Getting Started Guide to:
Have your DevKit connected to Wi-Fi
Prepare the development environment
An active Azure subscription. If you do not have one, you can register via one of these two methods:
Activate a free 30-day trial Microsoft Azure account
Claim your Azure credit if you are MSDN or Visual Studio subscriber

Step 1. Open the project folder


A. Start VS Code
Make sure your DevKit is not connected to your PC.
Start VS Code
Connect the DevKit to your computer.
B. Open the Arduino Examples folder
Expand left side ARDUINO EXAMPLES > Examples for MXCHIP AZ3166 > AzureIoT, and select
DevKitTranslator. It opens a new VS Code window with the DEVKITTRANSL ATOR project folder in it.
NOTE
You can also open example from command palette. Use Ctrl+Shift+P (macOS: Cmd+Shift+P ) to open the command
palette, type Arduino, and then find and select Arduino: Examples.

Step 2. Provision Azure services


In the solution window, type Ctrl+P (macOS: Cmd+P ) and enter task cloud-provision .
In the VS Code terminal, an interactive command line will guide you to provision all necessary Azure services:
Step 3. Deploy Azure Functions
Use Ctrl+P (macOS: Cmd+P ) to run task cloud-deploy to deploy the Azure Functions code. This process usually
takes 2 to 5 minutes to complete:

After Azure Function deploys successfully, fill in the azure_config.h file with function app name. You can navigate to
Azure portal to find it:

NOTE
If the Azure Function does not work properly, check this FAQs section to resolve it.

Step 4. Build and upload the device code


1. Use Ctrl+P (macOS: Cmd+P ) to run task config-device-connection .
2. The terminal will ask you whether you want to use connection string that retrieves from
task cloud-provision step. You can also input your own device connection string by selecting 'Create
New...'
3. The terminal prompts you to enter configuration mode. To do so, hold down button A, then push and release
the reset button. The screen displays the DevKit ID and 'Configuration'.

4. After task config-device-connection finished, click F1 to load VS Code commands and select
Arduino: Upload , then VS Code starts verifying and uploading the Arduino sketch:

The DevKit reboots and starts running the code.


Test the project
After app initialization, follow the instructions on the DevKit screen. The default source language is Chinese.
To select another language for translation:
1. Press button A to enter setup mode.
2. Press button B to scroll all supported source languages.
3. Press button A to confirm your choice of source language.
4. Press and hold button B while speaking, then release button B to initiate the translation.
5. The translated text in English shows on the screen.
On the translation result screen, you can:
Press button A and B to scroll and select the source language.
Press button B to talk, release to send the voice and get the translation text

How it works
The Arduino sketch records your voice then posts an HTTP request to trigger Azure Functions. Azure Functions
calls the cognitive service speech translator API to do the translation. After Azure Functions gets the translation
text, it sends a C2D message to the device. Then the translation is displayed on the screen.

Change device ID
The default device ID registered in Azure IoT Hub is AZ3166. If you want to modify it, follow instructions here.

Problems and feedback


If you encounter problems, refer to FAQs or reach out to us from the following channels:
Gitter.im
Stackoverflow

Next Steps
Now you make the IoT DevKit as a translator by using Azure Function and Cognitive Services. In this tutorial, you
learned how to:
Use Visual Studio Code task to automate cloud provisions
Configure Azure IoT device connection string
Deploy Azure Function
Test the voice message translation
Advance to the other tutorials to learn:
Connect IoT DevKit AZ3166 to Azure IoT Remote Monitoring solution accelerator
Shake, Shake for a Tweet -- Retrieve a Twitter
message with Azure Functions!
5/29/2018 • 5 min to read • Edit Online

In this project, you learn how to use the motion sensor to trigger an event using Azure Functions. The app retrieves
a random tweet with a #hashtag you configure in your Arduino sketch. The tweet displays on the DevKit screen.

What you need


Finish the Getting Started Guide to:
Have your DevKit connected to Wi-Fi.
Prepare the development environment.
An active Azure subscription. If you don't have one, you can register via one of these methods:
Activate a free 30-day trial Microsoft Azure account
Claim your Azure credit if you are MSDN or Visual Studio subscriber

Open the project folder


Start VS Code
Make sure your DevKit is not connected to your computer.
Start VS Code.
Connect the DevKit to your computer.

NOTE
When launching VS Code, you may receive an error message that the Arduino IDE or related board package can't be found. If
this error occurs, close VS Code and launch the Arduino IDE again. VS Code should now locate the Arduino IDE path correctly.

Open Arduino Examples folder


Expand left side ARDUINO EXAMPLES section, browse to Examples for MXCHIP AZ3166 > AzureIoT, and
select ShakeShake. A new VS Code window with a project folder in it opens.
NOTE
You can also open example from command palette. Use Ctrl+Shift+P (macOS: Cmd+Shift+P ) to open the command
palette, type Arduino, and then find and select Arduino: Examples.

Provision Azure services


In the solution window, run your task through Ctrl+P (macOS: Cmd+P ) by entering task cloud-provision .
In the VS Code terminal, an interactive command line guides you through provisioning the required Azure services:
NOTE
If the page hangs in the loading status when trying to sign in to Azure, refer to this FAQ step.

Modify the #hashtag


Open ShakeShake.ino and look for this line of code:

static const char* iot_event = "{\"topic\":\"iot\"}";

Replace the string iot within the curly braces with your preferred hashtag. DevKit later retrieves a random tweet
that includes the hashtag you specify in this step.

Deploy Azure Functions


Use Ctrl+P (macOS: Cmd+P ) to run task cloud-deploy to start deploying the Azure Functions code:

NOTE
Occasionally, the Azure Function may not work properly. To resolve this issue when it occurs, check this FAQ step.

Build and upload the device code


Windows
1. Use Ctrl+P to run task device-upload .
2. The terminal prompts you to enter configuration mode. To do so:
Hold down button A
Push and release the reset button.
3. The screen displays the DevKit ID and 'Configuration'.
4. This sets the connection string that is retrieved from the task cloud-provision step.
5. VS Code then starts verifying and uploading the Arduino sketch to your DevKit:

6. The DevKit reboots and starts running the code.

NOTE
You may get an "Error: AZ3166: Unknown package" error message. This error occurs when the board package index isn't
refreshed correctly. To resolve this issue, check this FAQ step.

macOS
1. Put the DevKit into configuration mode: Hold down button A, then push and release the reset button. The
screen displays 'Configuration'.
2. Use Cmd+P to run task device-upload to set the connection string that is retrieved from the
task cloud-provision step.
3. VS Code then starts verifying and uploading the Arduino sketch to your DevKit:
4. The DevKit reboots and starts running the code.

NOTE
You may get an "Error: AZ3166: Unknown package" error message. This error occurs when the board package index isn't
refreshed correctly. To resolve this issue, check this FAQ step.

Test the project


After app initialization, click and release button A, then gently shake the DevKit board. This action retrieves a
random tweet, which contains the hashtag you specified earlier. Within a few seconds, a tweet displays on your
DevKit screen:
Arduino application initializing...
Press A to shake...

Ready to shake...
Processing...

Press B to read...
Display a random tweet...

Press button A again, then shake for a new tweet.


Press button B to scroll through the rest of the tweet.

How it works
The Arduino sketch sends an event to the Azure IoT Hub. This event triggers the Azure Functions app. Azure
Functions app contains the logic to connect to Twitter's API and retrieve a tweet. It then wraps the tweet text into a
C2D (Cloud-to-device) message and sends it back to the device.

Optional: Use your own Twitter bearer token


For testing purposes, this sample project uses a pre-configured Twitter bearer token. However, there is a rate limit
for every Twitter account. If you want to consider using your own token, follow these steps:
1. Go to Twitter Developer portal to register a new Twitter app.
2. Get Consumer Key and Consumer Secrets of your app.
3. Use some utility to generate a Twitter bearer token from these two keys.
4. In the Azure portal{:target="_blank"}, get into the Resource Group and find the Azure Function (Type: App
Service) for your "Shake, Shake" project. The name always contains 'shake...' string.

5. Update the code for run.csx within Functions > shakeshake-cs with your own token:

...
string authHeader = "Bearer " + "[your own token]";
...

6. Save the file and click Run.


Problems and feedback
The screen displays 'No Tweets' while every step has run successfully
This condition normally happens for the first time you deploy and run the sample because the function app
requires anywhere from a couple of seconds to as much as one minute to cold start the app. Or, when running the
code, there are some blips that cause a restarting of the app. When this condition happens, the device app can get a
timeout for fetching the tweet. In this case, you may try one or both of these methods to solve this issue:
1. Click the reset button on the DevKit to run the device app again.
2. In the Azure portal, find the Azure Functions app you created and restart it:

Feedback
If you experience other problems, refer to FAQs or contact us from the following channels:
Gitter.im
Stackoverflow

Next steps
Now that you have learned how to connect a DevKit device to your Azure IoT Remote Monitoring solution
accelerator and retrieve a tweet, here are the suggested next steps:
Azure IoT Remote Monitoring solution accelerator overview
Send messages to an MQTT server
5/29/2018 • 2 min to read • Edit Online

Internet of Things (IoT) systems often deal with intermittent, poor quality, or slow internet connections. MQTT is a
machine-to-machine (M2M ) connectivity protocol, which was developed with such challenges in mind.
The MQTT client library used here is part of the Eclipse Paho project, which provides APIs for using MQTT over
multiple means of transport.

What you learn


In this project, you learn:
How to use the MQTT Client library to send messages to an MQTT broker.
How to configure your MXChip Iot DevKit as an MQTT client.

What you need


Finish the Getting Started Guide to:
Have your DevKit connected to Wi-Fi
Prepare the development environment

Open the project folder


1. Disconnect the DevKit from your computer, if it is already connected.
2. Start VS Code.
3. Connect the DevKit to your computer.

Open the MQTTClient Sample


Expand left side ARDUINO EXAMPLES section, browse to Examples for MXCHIP AZ3166 > MQTT, and select
MQTTClient. A new VS Code window opens with a project folder in it.

NOTE
You can also open example from command palette. Use Ctrl+Shift+P (macOS: Cmd+Shift+P ) to open the command
palette, type Arduino, and then find and select Arduino: Examples.

Build and upload the Arduino sketch to the DevKit


Type Ctrl+P (macOS: Cmd+P ) to run task device-upload . Once the upload is completed, DevKit restarts and runs
the sketch.
NOTE
You may receive an "Error: AZ3166: Unknown package" error message. This error occurs when the board package index is not
refreshed correctly. To resolve this error, refer to this FAQ.

Test the project


In VS Code, follow this procedure to open and set up the Serial Monitor:
1. Click the COM[X] word on the status bar to set the right COM port with STMicroelectronics :

2. Click the power plug icon on the status bar to open the Serial Monitor:

3. On the status bar, click the number that represents the Baud Rate and set it to 115200 :
The Serial Monitor displays all the messages sent by the sample sketch. The sketch connects the DevKit to Wi-Fi.
Once the Wi-Fi connection is successful, the sketch sends a message to the MQTT broker. After that, the sample
repeatedly sends two "iot.eclipse.org" messages using QoS 0 and QoS 1, respectively.

Problems and feedback


If you encounter problems, refer to FAQs or connect using the following channels:
Gitter.im
Stackoverflow
See also
[Connect IoT DevKit AZ3166 to Azure IoT Hub in the cloud]({{"/docs/getting-started/" | absolute_url }})
[Shake, Shake for a Tweet]({{"/docs/projects/shake-shake/" | absolute_url }})

Next steps
Now that you have learned how to configure your MXChip Iot DevKit as an MQTT client and use the MQTT Client
library to send messages to an MQTT broker, here are the suggested next steps:
Azure IoT Remote Monitoring solution accelerator overview
Connect an MXChip IoT DevKit device to your Azure IoT Central application
Door Monitor
5/29/2018 • 5 min to read • Edit Online

The MXChip IoT DevKit contains a built-in magnetic sensor. In this project, you detect the presence or absence of a
nearby strong magnetic field--in this case, coming from a small. permanent magnet.

What you learn


In this project, you learn:
How to use the MXChip IoT DevKit's magnetic sensor to detect the movement of a nearby magnet.
How to use the SendGrid service to send a notification to your email address.

NOTE
For a practical use of this project:
Mount a magnet to the edge of a door.
Mount the DevKit on the door jamb close to the magnet. Opening or closing the door will trigger the sensor, resulting in
your receiving an email notification of the event.

What you need


Finish the [Getting Started Guide]({{"/docs/get-started/" | absolute_url }}) to:
Have your DevKit connected to Wi-Fi
Prepare the development environment
An active Azure subscription. If you do not have one, you can register via one of these methods:
Activate a free 30-day trial Microsoft Azure account.
Claim your Azure credit if you are an MSDN or Visual Studio subscriber.

Deploy SendGrid service in Azure


SendGrid is a cloud-based email delivery platform. This service will be used to send email notifications.

NOTE
If you have already deployed a SendGrid service, you may proceed directly to Deploy IoT Hub in Azure.

SendGrid Deployment
To provision Azure services, use the Deploy to Azure button. This button enables quick and easy deployment of
your open-source projects to Microsoft Azure.
Click the Deploy to Azure button, below.

You then see the following page.


NOTE
If you do not see the following page, you may need to first sign in to your Azure account.

Complete the sign-up form:


Resource group: Create a resource group to host the SendGrid service, or use an existing one. See Using
resource groups to manage your Azure resources.
Name: The name for your SendGrid service. Choose a unique name, differing from other services you may
have.
Password: The service requires a password, which will not be for anything in this project.
Email: The SendGrid service will send verification to this email address.

NOTE
Check the Pin to dashboard option to make this application easier to find in the future.

SendGrid API Key creation


After the deployment succeeds, click it and then click the Manage button. You are taken to your SendGrid page,
and need to verify your email address.
On the SendGrid page, click Settings > API Keys > Create API Key. Input the API Key Name and click Create
& View.
Your API key is displayed only one time. Be sure to copy and store it safely, as it is used in the next step.

Deploy IoT Hub in Azure


The following steps will provision other Azure IoT related services and deploy Azure Functions for this project.
Click the Deploy to Azure button, below.

You then see the following page.

NOTE
If you don't see the following page, you may need to first sign in to your Azure account.

Complete the sign-up form:


Resource group: Create a resource group to host the SendGrid service, or use an existing one. See Using
resource groups to manage your Azure resources.
Iot Hub Name: The name for your IoT hub. Choose a unique name, differing from other services you may
have.
Iot Hub Sku: F1 (limited one per subscription) is free. You can see more pricing information at pricing and
scale tier.
From Email: This should be the same email address you used when setting up the SendGrid service.

NOTE
Check the Pin to dashboard option to make this application easier to find in the future.
Build and upload the code
Start VS Code
Make sure your DevKit is not connected to your computer.
Start VS Code.
Connect the DevKit to your computer.

NOTE
When you launch VS Code, you may receive an error message stating that it cannot find the Arduino IDE or related board
package. If you receive this error, close VS Code, launch the Arduino IDE again, and VS Code should locate the Arduino IDE
path correctly.

Open Arduino Examples folder


Expand the left side ARDUINO EXAMPLES section, browse to Examples for MXCHIP AZ3166 > AzureIoT,
and select DoorMonitor. This action opens a new VS Code window with a project folder in it.
NOTE
You can also open example from command palette. Use Ctrl+Shift+P (macOS: Cmd+Shift+P ) to open the command
palette, type Arduino, and then find and select Arduino: Examples.

Provision Azure services


In the solution window, run the cloud provisioning task:
Type Ctrl+P (macOS: Cmd+P ).
Enter task cloud-provision in the provided text box.

In the VS Code terminal, an interactive command line guides you through provisioning the required Azure services.
Select all of the same items from the prompted list that you previously provisioned in Deploy IoT Hub in Azure.
NOTE
If the page hangs in the loading status when trying to sign in to Azure, refer to FAQ to resolve this issue.

Build and upload the device code


Windows
1. Use Ctrl+P to run task device-upload .
2. The terminal prompts you to enter configuration mode. To do so, hold down button A, then push and release the
reset button. The screen displays the DevKit identification number and the word Configuration.
This procedure sets the connection string that is retrieved from the Provision Azure services step.
VS Code then starts verifying and uploading the Arduino sketch to the DevKit:
The DevKit reboots and starts running the code.

NOTE
Occasionally, you may receive an "Error: AZ3166: Unknown package" error message. This error occurs when the board
package index is not refreshed correctly. To resolve this error, refer to this FAQ.

macOS
1. Put the DevKit into configuration mode: Hold down button A, then push and release the reset button. The
screen displays 'Configuration'.
2. Use Cmd+P to run task device-upload .
This procedure sets the connection string that is retrieved from the Provision Azure services step.
VS Code then starts verifying and uploading the Arduino sketch to the DevKit:
The DevKit reboots and starts running the code.

NOTE
Occasionally, you may receive an "Error: AZ3166: Unknown package" error message. This error occurs when the board
package index is not refreshed correctly. To resolve this error, refer to this FAQ.

Test the project


The program first initializes when the DevKit is in the presence of a stable magnetic field.
After initialization, Door closed is displayed on the screen. When there is a change in the magnetic field, the state
changes to Door opened . Each time the door state changes, you receive an email notification. (These email
messages may take up to five minutes to be received.)
Problems and feedback
If you encounter problems, refer to FAQs or connect using the following channels:
Gitter.im
Stackoverflow
Next steps
You have learned how to connect a DevKit device to your Azure IoT Remote Monitoring solution accelerator and
use the SendGrid service to send an email. Here are the suggested next steps:
Azure IoT Remote Monitoring solution accelerator overview
Connect an MXChip IoT DevKit device to your Azure IoT Central application
Connecting IoT Devices to Azure: IoT Hub and
Event Hubs
5/29/2018 • 2 min to read • Edit Online

Azure provides services specifically developed for diverse types of connectivity and communication to help you
connect your data to the power of the cloud. Both Azure IoT Hub and Azure Event Hubs are cloud services that
can ingest large amounts of data and process or store that data for business insights. The two services are similar
in that they both support ingestion of data with low latency and high reliability, but they are designed for
different purposes. IoT Hub was developed specifically to address the unique requirements of connecting IoT
devices, at-scale, to the Azure Cloud while Event Hubs was designed for big data streaming. This is why Microsoft
recommends using Azure IoT Hub to connect IoT devices to Azure
Azure IoT Hub is the cloud gateway that connects IoT devices to gather data to drive business insights and
automation. In addition, IoT Hub includes features that enrich the relationship between your devices and your
backend systems. Bi-directional communication capabilities mean that while you receive data from devices you
can also send commands and policies back to devices, for example, to update properties or invoke device
management actions. This cloud-to-device connectivity also powers the important capability of delivering cloud
intelligence to your edge devices with Azure IoT Edge. The unique device-level identity provided by IoT Hub
helps better secure your IoT solution from potential attacks.
Azure Event Hubs is the big data streaming service of Azure. It is designed for high throughput data streaming
scenarios where customers may send billions of requests per day. Event Hubs uses a partitioned consumer
model to scale out your stream and is integrated into the big data and analytics services of Azure including
Databricks, Stream Analytics, ADLS, and HDInsight. With features like Event Hubs Capture and Auto-Inflate, this
service is designed to support your big data apps and solutions. Additionally, IoT Hub leverages Event Hubs for
its telemetry flow path, so your IoT solution also benefits from the tremendous power of Event Hubs.
To summarize, while both solutions are designed for data ingestion at a massive scale, only IoT Hub provides the
rich IoT-specific capabilities that are designed for you to maximize the business value of connecting your IoT
devices to the Azure cloud. If your IoT journey is just beginning, starting with IoT Hub to support your data
ingestion scenarios will assure that you have instant access to the full-featured IoT capabilities once your
business and technical needs require them.
The following table provides details about how the two tiers of IoT Hub compare to Event Hubs when you're
evaluating them for IoT capabilities. For more information about the standard and basic tiers of IoT Hub, see
How to choose the right IoT Hub tier.

IOT CAPABILITY IOT HUB STANDARD TIER IOT HUB BASIC TIER EVENT HUBS

Device-to-cloud messaging

Protocols: HTTPS, AMQP,


AMQP over webSockets

Protocols: MQTT, MQTT


over webSockets

Per-device identity
IOT CAPABILITY IOT HUB STANDARD TIER IOT HUB BASIC TIER EVENT HUBS

File upload from devices

Device Provisioning Service

Cloud-to-device messaging

Device twin and device


management

IoT Edge

Even if the only use case is device-to-cloud data ingestion, we highly recommend using IoT Hub as it provides a
service that is designed for IoT device connectivity.
Next steps
To further explore the capabilities of IoT Hub, see the IoT Hub developer guide
Choose the right IoT Hub tier for your
solution
5/29/2018 • 4 min to read • Edit Online

Every IoT solution is different, so Azure IoT Hub offers several options based on pricing and
scale. This article is meant to help you evaluate your IoT Hub needs. For pricing information
about IoT Hub tiers refer to IoT Hub pricing.
To decide which IoT Hub tier is right for your solution, ask yourself two questions:
What features do I plan to use? Azure IoT Hub offers two tiers, basic and standard, that differ
in the number of features they support. If your IoT solution is based around collecting data from
devices and analyzing it centrally then the basic tier is probably right for you. If you want to use
more advanced configurations to control IoT devices remotely or distribute some of your
workloads onto the devices themselves then you should consider the standard tier. For a
detailed breakdown of which features are included in each tier continue to Basic and standard
tiers.
How much data do I plan to move daily? Each IoT Hub tier is available in three sizes, based
around how much data throughput they can handle in any given day. These sizes are
numerically identified as 1, 2, and 3. For example, each unit of a level 1 IoT hub can handle 400
thousand messages a day, while a level 3 unit can handle 300 million. For more details about
the data guidelines, continue to Message throughput.

Basic and standard tiers


The standard tier of IoT Hub enables all features, and is required for any IoT solutions that want
to make use of the bi-directional communication capabilities. The basic tier enables a subset of
the features and is intended for IoT solutions that only need uni-directional communication
from devices to the cloud. Both tiers offer the same security and authentication features.
Once you create your IoT hub you can upgrade from the basic tier to the standard tier without
interrupting your existing operations. For more information, see How to upgrade your IoT hub.

CAPABILITY BASIC TIER STANDARD TIER

Device-to-cloud telemetry Yes Yes

Per-device identity Yes Yes

Message routing and Event Grid Yes Yes


integration

HTTP, AMQP, and MQTT Yes Yes


protocols

Device Provisioning Service Yes Yes

Monitoring and diagnostics Yes Yes


CAPABILITY BASIC TIER STANDARD TIER

Cloud-to-device messaging Yes

Device twins, Module twins and Yes


Device management

Azure IoT Edge Yes

IoT Hub also offers a free tier that is meant for testing and evaluation. It has all the capabilities
of the standard tier, but limited messaging allowances. You cannot upgrade from the free tier to
either basic or standard.
IoT Hub REST APIs
The difference in supported capabilities between the basic and standard tiers of IoT Hub means
that some API calls do not work with basic tier hubs. The following table shows which APIs are
available:

API BASIC TIER STANDARD TIER

Delete device Yes Yes

Get device Yes Yes

Delete module Yes Yes

Get module Yes Yes

Get registry statistics Yes Yes

Get services statistics Yes Yes

Put device Yes Yes

Put module Yes Yes

Query devices Yes Yes

Query modules Yes Yes

Create file upload SAS URI Yes Yes

Receive device bound notification Yes Yes

Send device event Yes Yes

Send module event Yes Yes

Update file upload status Yes Yes

Bulk device operation Yes, except for IoT Edge Yes


capabilites
API BASIC TIER STANDARD TIER

Purge command queue Yes

Get device twin Yes

Get module twin Yes

Invoke device method Yes

Update device twin Yes

Update module twin Yes

Abandon device bound Yes


notification

Complete device bound Yes


notification

Cancel job Yes

Create job Yes

Get job Yes

Query jobs Yes

Message throughput
The best way to size an IoT Hub solution is to evaluate the traffic on a per-unit basis. In
particular, consider the required peak throughput for the following categories of operations:
Device-to-cloud messages
Cloud-to-device messages
Identity registry operations
Traffic is measured on a per-unit basis, not per hub. A level 1 or 2 IoT Hub instance can have as
many as 200 units associated with it. A level 3 IoT Hub instance can have up to 10 units. Once
you create your IoT hub you can change the number of units or move between the 1, 2, and 3
sizes within a specific tier without interrupting your existing operations. For more information,
see How to upgrade your IoT Hub.
As an example of each tier's traffic capabilities, device-to-cloud messages follow these sustained
throughput guidelines:

TIER SUSTAINED THROUGHPUT SUSTAINED SEND RATE

B1, S1 Up to 1111 KB/minute per unit Average of 278


(1.5 GB/day/unit) messages/minute per unit
(400,000 messages/day per unit)
TIER SUSTAINED THROUGHPUT SUSTAINED SEND RATE

B2, S2 Up to 16 MB/minute per unit Average of 4,167


(22.8 GB/day/unit) messages/minute per unit
(6 million messages/day per unit)

B3, S3 Up to 814 MB/minute per unit Average of 208,333


(1144.4 GB/day/unit) messages/minute per unit
(300 million messages/day per
unit)

In addition to this throughput information, see IoT Hub quotas and throttles and design your
solution accordingly.
Identity registry operation throughput
IoT Hub identity registry operations are not supposed to be run-time operations, as they are
mostly related to device provisioning.
For specific burst performance numbers, see IoT Hub quotas and throttles.

Sharding
While a single IoT hub can scale to millions of devices, sometimes your solution requires
specific performance characteristics that a single IoT hub cannot guarantee. In that case you can
partition your devices across multiple IoT hubs. Multiple IoT hubs smooth traffic bursts and
obtain the required throughput or operation rates that are required.

Next steps
For additional information about IoT Hub capabilities and performance details, see [IoT Hub
pricing][link-pricing] or IoT Hub quotas and throttles.
To change your IoT Hub tier, follow the steps in Upgrade your IoT hub.
IoT Hub high availability and disaster recovery
5/29/2018 • 3 min to read • Edit Online

As an Azure service, IoT Hub provides high availability (HA) using redundancies at the Azure region level, without
any additional work required by the solution. The Microsoft Azure platform also includes features to help you build
solutions with disaster recovery (DR ) capabilities or cross-region availability. If you want to provide global, cross-
region high availability for devices or users, take advantage of these Azure DR features. The article Azure Business
Continuity Technical Guidance describes the built-in features in Azure for business continuity and DR. The Disaster
recovery and high availability for Azure applications paper provides architecture guidance on strategies for Azure
applications to achieve HA and DR.

Azure IoT Hub DR


In addition to intra-region HA, IoT Hub implements failover mechanisms for disaster recovery that require no
intervention from the user. IoT Hub DR is self-initiated and has a recovery time objective (RTO ) of 2-26 hours, and
the following recovery point objectives (RPOs):

FUNCTIONALITY RPO

Service availability for registry and communication operations Possible CName loss

Identity data in identity registry 0-5 mins data loss

Device-to-cloud messages All unread messages are lost

Operations monitoring messages All unread messages are lost

Cloud-to-device messages 0-5 mins data loss

Cloud-to-device feedback queue All unread messages are lost

Device twin data 0-5 mins data loss

Parent and device jobs 0-5 mins data loss

Regional failover with IoT Hub


A complete treatment of deployment topologies in IoT solutions is outside the scope of this article. The article
discusses the regional failover deployment model for the purpose of high availability and disaster recovery.
In a regional failover model, the solution back end runs primarily in one datacenter location. A secondary IoT hub
and back end are deployed in another datacenter location. If the IoT hub in the primary datacenter suffers an
outage or the network connectivity from the device to the primary datacenter is interrupted, devices use a
secondary service endpoint. You can improve the solution availability by implementing a cross-region failover
model instead of staying within a single region.
At a high level, to implement a regional failover model with IoT Hub, you need the following:
A secondary IoT hub and device routing logic: If service in your primary region is disrupted, devices must
start connecting to your secondary region. Given the state-aware nature of most services involved, it is
common for solution administrators to trigger the inter-region failover process. The best way to communicate
the new endpoint to devices, while maintaining control of the process, is to have them regularly check a
concierge service for the current active endpoint. The concierge service can be a web application that is
replicated and kept reachable using DNS -redirection techniques (for example, using Azure Traffic Manager).
Identity registry replication: To be usable, the secondary IoT hub must contain all device identities that can
connect to the solution. The solution should keep geo-replicated backups of device identities, and upload them
to the secondary IoT hub before switching the active endpoint for the devices. The device identity export
functionality of IoT Hub is useful in this context. For more information, see IoT Hub developer guide - identity
registry.
Merging logic: When the primary region becomes available again, all the state and data that have been
created in the secondary site must be migrated back to the primary region. This state and data mostly relate to
device identities and application metadata, which must be merged with the primary IoT hub and any other
application-specific stores in the primary region. To simplify this step, you should use idempotent operations.
Idempotent operations minimize the side-effects from the eventual consistent distribution of events, and from
duplicates or out-of-order delivery of events. In addition, the application logic should be designed to tolerate
potential inconsistencies or "slightly" out-of-date state. This situation can occur due to the additional time it
takes for the system to "heal" based on recovery point objectives (RPO ).

Next steps
Follow these links to learn more about Azure IoT Hub:
Get started with IoT Hubs (Tutorial)
What is Azure IoT Hub?
Support additional protocols for IoT Hub
5/29/2018 • 1 min to read • Edit Online

Azure IoT Hub natively supports communication over the MQTT, AMQP, and HTTPS protocols. In some cases,
devices or field gateways might not be able to use one of these standard protocols and require protocol
adaptation. In such cases, you can use a custom gateway. A custom gateway enables protocol adaptation for IoT
Hub endpoints by bridging the traffic to and from IoT Hub. You can use the Azure IoT protocol gateway as a
custom gateway to enable protocol adaptation for IoT Hub.

Azure IoT protocol gateway


The Azure IoT protocol gateway is a framework for protocol adaptation that is designed for high-scale,
bidirectional device communication with IoT Hub. The protocol gateway is a pass-through component that
accepts device connections over a specific protocol. It bridges the traffic to IoT Hub over AMQP 1.0.
You can deploy the protocol gateway in Azure in a highly scalable way by using Azure Service Fabric, Azure
Cloud Services worker roles, or Windows Virtual Machines. In addition, the protocol gateway can be deployed in
on-premises environments, such as field gateways.
The Azure IoT protocol gateway includes an MQTT protocol adapter that enables you to customize the MQTT
protocol behavior if necessary. Since IoT Hub provides built-in support for the MQTT v3.1.1 protocol, you should
only consider using the MQTT protocol adapter if protocol customizations or specific requirements for additional
functionality are required.
The MQTT adapter also demonstrates the programming model for building protocol adapters for other protocols.
In addition, the Azure IoT protocol gateway programming model allows you to plug in custom components for
specialized processing such as custom authentication, message transformations, compression/decompression, or
encryption/decryption of traffic between the devices and IoT Hub.
For flexibility, the Azure IoT protocol gateway and MQTT implementation are provided in an open-source
software project. You can use the open-source project to add support for various protocols and protocol versions,
or customize the implementation for your scenario.

Next steps
To learn more about the Azure IoT protocol gateway and how to use and deploy it as part of your IoT solution,
see:
Azure IoT protocol gateway repository on GitHub
Azure IoT protocol gateway developer guide
To learn more about planning your IoT Hub deployment, see:
Compare with Event Hubs
Scaling, high availability, and disaster recovery
IoT Hub developer guide
Compare message routing and Event Grid for IoT
Hub
5/29/2018 • 4 min to read • Edit Online

Azure IoT Hub provides the capability to stream data from your connected devices, and integrate that data into
your business applications. IoT Hub offers two methods for integrating IoT events into other Azure services or
business applications. This article discusses the two features that provide this capability, so that you can choose
which option is best for your scenario.
IoT Hub message routing: This IoT Hub feature enables users to route device-to-cloud messages to service
endpoints like Azure Storage containers, Event Hubs, Service Bus queues, and Service Bus topics. Routing rules
provide the flexibility to perform query-based routes. They also enable critical alerts that trigger actions
through queries, and can be based on the message headers and body.
IoT Hub integration with Event Grid: Azure Event Grid is a fully managed event routing service that uses a
publish-subscribe model. IoT Hub and Event Grid work together to integrate IoT Hub events into Azure and
non-Azure services, in near-real time.

Similarities and differences


While both message routing and Event Grid enable alert configuration, there are some key differences between
the two. Refer to the following table for details:

FEATURE IOT HUB MESSAGE ROUTING IOT HUB INTEGRATION WITH EVENT GRID

Device messages Yes, message routing can be used for No, Event Grid can only be used for
telemetry data. non-telemetry IoT Hub events.

Event type Yes, message routing can report twin Yes, Event Grid can report when devices
changes and device lifecycle events. are registered to an IoT Hub, and when
devices are deleted.

Ordering Yes, ordering of events is maintained. No, order of events is not guaranteed.

Maximum message size 256 KB, device-to-cloud 64 KB

Filtering Rich filtering through SQL-like language Filtering based on suffix/prefix of device
supports filtering on message headers IDs, which works well for hierarchical
and bodies. For examples, see IoT Hub services like storage.
query language.
FEATURE IOT HUB MESSAGE ROUTING IOT HUB INTEGRATION WITH EVENT GRID

Endpoints Event Hub Azure Functions


Storage blob Azure Automation
Service Bus queue Event Hub
Service Bus topics Logic Apps
Microsoft Flow
Third-party services through
Paid IoT Hub SKUs (S1, S2, and S3) are
WebHooks
limited to 10 custom endpoints. 100
routes can be created per IoT Hub.
For the most up-to-date list of
endpoints, see Event Grid event
handlers.

Cost There is no separate charge for There is no charge from IoT Hub. Event
message routing. Only ingress of Grid offers the first 100,000 operations
telemetry into IoT Hub is charged. For per month for free, and then $0.60 per
example, if you have a message routed million operations after that.
to three different endpoints, you are
billed for only one message.

IoT Hub message routing and Event Grid have similarities too, some of which are detailed in the following table:

FEATURE IOT HUB MESSAGE ROUTING IOT HUB INTEGRATION WITH EVENT GRID

Reliability High: Delivers each message to the High: Delivers each message to the
endpoint at least once for each route. webhook at least once for each
Expires all messages that are not subscription. Expires all events that are
delivered within one hour. not delivered within 24 hours.

Scalability High: Optimized to support millions of High: Capable of routing 10,000,000


simultaneously connected devices events per second per region.
sending billions of messages.

Latency Low: Near-real time. Low: Near-real time.

Send to multiple endpoints Yes, send a single message to multiple Yes, send a single message to multiple
endpoints. endpoints.

Security Iot Hub provides per-device identity Event Grid provides validation at three
and revocable access control. For more points: event subscriptions, event
information, see the IoT Hub access publishing, and webhook event delivery.
control. For more information, see Event Grid
security and authentication.

How to choose
IoT Hub message routing and the IoT Hub integration with Event Grid perform different actions to achieve similar
results. They both take information from your IoT Hub solution and pass it on so that other services can react. So
how do you decide which one to use? In addition to the data from the previous section, use the following
questions to help guide your decision:
What kind of data are you sending to the endpoints?
Use IoT Hub message routing when you have to send telemetry data to other services. Message routing
also enables querying message headers and message bodies.
The IoT Hub integration with Event Grid works with events that occur in the IoT Hub service. These IoT
Hub events include device creation and deletion.
What endpoints need to receive this information?
IoT Hub message routing supports limited endpoints, but you can build connectors to reroute the data and
events to additional endpoints. For a complete list of supported endpoints, see the table in the previous
section.
The IoT Hub integration with Event Grid supports more endpoints. It also works with webhooks to extend
routing outside of the Azure service ecosystem and into third-party business applications.
Does it matter if your data arrives in order?
IoT Hub message routing maintains the order in which messages are sent, so that they arrive in the same
way.
Event Grid does not guarantee that endpoints will receive events in the same order that they occurred.
However, the event schema does include a timestamp that can be used to identify the order after the events
arrive at the endpoint.

Next steps
Learn more about IoT Hub message routing and the IoT Hub endpoints.
Learn more about Azure Event Grid
Try out the Event Grid integration by Sending email notifications about Azure IoT Hub events using Logic
Apps
1 min to read •
Edit Online
Azure IoT Hub developer guide
5/29/2018 • 3 min to read • Edit Online

Azure IoT Hub is a fully managed service that helps enable reliable and secure bi-directional communications
between millions of devices and a solution back end.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management,
are only available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see
How to choose the right IoT Hub tier.

Azure IoT Hub provides you with:


Secure communications by using per-device security credentials and access control.
Multiple device-to-cloud and cloud-to-device hyper-scale communication options.
Queryable storage of per-device state information and meta-data.
Easy device connectivity with device libraries for the most popular languages and platforms.
This IoT Hub developer guide includes the following articles:
Device-to-cloud communication guidance helps you choose between device-to-cloud messages, device
twin's reported properties, and file upload.
Cloud-to-device communication guidance helps you choose between direct methods, device twin's desired
properties, and cloud-to-device messages.
Device-to-cloud and cloud-to-device messaging with IoT Hub describes the messaging features (device-
to-cloud and cloud-to-device) that IoT Hub exposes.
Send device-to-cloud messages to IoT Hub.
Read device-to-cloud messages from the built-in endpoint.
Use custom endpoints and routing rules for device-to-cloud messages.
Send cloud-to-device messages from IoT Hub.
Create and read IoT Hub messages.
Upload files from a device describes how you can upload files from a device. The article also includes
information about topics such as the notifications the upload process can send.
Manage device identities in IoT Hub describes what information each IoT hub's identity registry stores.
The article also describes how you can access and modify it.
Control access to IoT Hub describes the security model used to grant access to IoT Hub functionality for
both devices and cloud components. The article includes information about using tokens and X.509
certificates, and details of the permissions you can grant.
Use device twins to synchronize state and configurations describes the device twin concept. The article
also descibes the functionality device twins expose, such as synchronizing a device with its device twin.
The article includes information about the data stored in a device twin.
Invoke a direct method on a device describes the lifecycle of a direct method. The article describes how to
invoke methods on a device from your back-end app and handle the direct method on your device.
Schedule jobs on multiple devices describes how you can schedule jobs on multiple devices. The article
describes how to submit jobs that perform tasks as executing a direct method, updating a device using a
device twin. It also describes how to query the status of a job.
Reference - choose a communication protocol describes the communication protocols that IoT Hub
supports for device communication and lists the ports that should be open.
Reference - IoT Hub endpoints describes the various endpoints that each IoT hub exposes for runtime and
management operations. The article also describes how you can create additional endpoints in your IoT
hub, and how to use a field gateway to enable connectivity to your IoT Hub endpoints in non-standard
scenarios.
Reference - IoT Hub query language for device twins, jobs, and message routing describes that IoT Hub
query language that enables you to retrieve information from your hub about your device twins and jobs.
Reference - quotas and throttling summarizes the quotas set in the IoT Hub service and the throttling that
occurs when you exceed a quota.
Reference - pricing provides general information on different SKUs and pricing for IoT Hub and details on
how the various IoT Hub functionalities are metered as messages by IoT Hub.
Reference - Device and service SDKs lists the Azure IoT SDKs for developing device and service apps that
interact with your IoT hub. The article includes links to online API documentation.
Reference - IoT Hub MQTT support provides detailed information about how IoT Hub supports the
MQTT protocol. The article describes the support for the MQTT protocol built-in to the Azure IoT SDKs
and provides information about using the MQTT protocol directly.
Glossary a list of common IoT Hub-related terms.
Device-to-cloud communications guidance
5/29/2018 • 1 min to read • Edit Online

When sending information from the device app to the solution back end, IoT Hub exposes three options:
Device-to-cloud messages for time series telemetry and alerts.
Device twin's reported properties for reporting device state information such as available capabilities,
conditions, or the state of long-running workflows. For example, configuration and software updates.
File uploads for media files and large telemetry batches uploaded by intermittently connected devices or
compressed to save bandwidth.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are
only available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How
to choose the right IoT Hub tier.

Here is a detailed comparison of the various device-to-cloud communication options.

DEVICE TWIN'S REPORTED


DEVICE-TO-CLOUD MESSAGES PROPERTIES FILE UPLOADS

Scenario Telemetry time series and Available capabilities and Media files. Large (typically
alerts. For example, 256-KB conditions. For example, the compressed) telemetry
sensor data batches sent current device connectivity batches.
every 5 minutes. mode such as cellular or
WiFi. Synchronizing long-
running workflows, such as
configuration and software
updates.

Storage and retrieval Temporarily stored by IoT Stored by IoT Hub in the Stored in user-provided
Hub, up to 7 days. Only device twin. Retrievable Azure Storage account.
sequential reading. using the IoT Hub query
language.

Size Up to 256-KB messages. Maximum reported Maximum file size


properties size is 8 KB. supported by Azure Blob
Storage.

Frequency High. For more information, Medium. For more Low. For more information,
see IoT Hub limits. information, see IoT Hub see IoT Hub limits.
limits.

Protocol Available on all protocols. Available using MQTT or Available when using any
AMQP. protocol, but requires
HTTPS on the device.

An application may need to send information both as a telemetry time series or alert and make it available in
the device twin. In this scenario, you can choose one of the following options:
The device app sends a device-to-cloud message and reports a property change.
The solution back end can store the information in the device twin's tags when it receives the message.
Since device-to-cloud messages enable a much higher throughput than device twin updates, it is sometimes
desirable to avoid updating the device twin for every device-to-cloud message.
Cloud-to-device communications guidance
5/29/2018 • 1 min to read • Edit Online

IoT Hub provides three options for device apps to expose functionality to a back-end app:
Direct methods for communications that require immediate confirmation of the result. Direct methods are
often used for interactive control of devices such as turning on a fan.
Twin's desired properties for long-running commands intended to put the device into a certain desired state.
For example, set the telemetry send interval to 30 minutes.
Cloud-to-device messages for one-way notifications to the device app.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Here is a detailed comparison of the various cloud-to-device communication options.

DIRECT METHODS TWIN'S DESIRED PROPERTIES CLOUD-TO-DEVICE MESSAGES

Scenario Commands that require Long-running commands One-way notifications to


immediate confirmation, intended to put the device the device app.
such as turning on a fan. into a certain desired state.
For example, set the
telemetry send interval to
30 minutes.

Data flow Two-way. The device app One-way. The device app One-way. The device app
can respond to the method receives a notification with receives the message
right away. The solution the property change.
back end receives the
outcome contextually to
the request.

Durability Disconnected devices are Property values are Messages can be retained
not contacted. The solution preserved in the device by IoT Hub for up to 48
back end is notified that the twin. Device will read it at hours.
device is not connected. next reconnection. Property
values are retrievable with
the IoT Hub query
language.

Targets Single device using Single device using Single device by deviceId.
deviceId, or multiple deviceId, or multiple
devices using jobs. devices using jobs.

Size Maximum direct method Maximum desired Up to 64 KB messages.


payload size is 128 KB. properties size is 8 KB.

Frequency High. For more information, Medium. For more Low. For more information,
see IoT Hub limits. information, see IoT Hub see IoT Hub limits.
limits.
DIRECT METHODS TWIN'S DESIRED PROPERTIES CLOUD-TO-DEVICE MESSAGES

Protocol Available using MQTT or Available using MQTT or Available on all protocols.
AMQP. AMQP. Device must poll when
using HTTPS.

Learn how to use direct methods, desired properties, and cloud-to-device messages in the following tutorials:
Use direct methods, for direct methods;
Use desired properties to configure devices, for device twin's desired properties;
Send cloud-to-device messages, for cloud-to-device messages.
Device-to-cloud and cloud-to-device messaging
with IoT Hub
5/29/2018 • 1 min to read • Edit Online

Use IoT Hub messaging to communicate with your devices by:


Sending device-to-cloud messages from your devices to your solution back end.
Sending cloud-to-device messages from the solution back end to your devices.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device
management, are only available in the standard tier of IoT hub. For more information about the basic and standard
IoT Hub tiers, see How to choose the right IoT Hub tier.

Core properties of IoT Hub messaging functionality are the reliability and durability of messages. These
properties enable resilience to intermittent connectivity on the device side, and to load spikes in event
processing on the cloud side. IoT Hub implements at least once delivery guarantees for both device-to-
cloud and cloud-to-device messaging.
For an introduction to the capabilities of IoT Hub, see the Overview of the Azure IoT Hub service.

When to use IoT Hub messaging


Use device-to-cloud messages for sending time series telemetry and alerts from your device app, and
cloud-to-device messages for one-way notifications to your device app.
Refer to Device-to-cloud communication guidance if in doubt between using device-to-cloud messages,
reported properties, or file upload.
Refer to Cloud-to-device communication guidance if in doubt between using cloud-to-device
messages, desired properties, or direct methods.

Next steps
Learn about IoT Hub device-to-cloud messaging.
Learn about IoT Hub cloud-to-device messaging.
Send device-to-cloud messages to IoT Hub
6/6/2018 • 3 min to read • Edit Online

To send time-series telemetry and alerts from your devices to your solution back end, send device-to-cloud
messages from your device to your IoT hub. For a discussion of other device-to-cloud options supported by
IoT Hub, see Device-to-cloud communications guidance.
You send device-to-cloud messages through a device-facing endpoint
(/devices/{deviceId}/messages/events). Routing rules then route your messages to one of the service-
facing endpoints on your IoT hub. Routing rules use the headers and body of the device-to-cloud messages to
determine where to route them. By default, messages are routed to the built-in service-facing endpoint
(messages/events), that is compatible with Event Hubs. Therefore, you can use standard Event Hubs
integration and SDKs to receive device-to-cloud messages in your solution back end.
IoT Hub implements device-to-cloud messaging using a streaming messaging pattern. IoT Hub's device-to-
cloud messages are more like Event Hubs events than Service Bus messages in that there is a high volume of
events passing through the service that can be read by multiple readers.
Device-to-cloud messaging with IoT Hub has the following characteristics:
Device-to-cloud messages are durable and retained in an IoT hub's default messages/events endpoint for
up to seven days.
Device-to-cloud messages can be at most 256 KB, and can be grouped in batches to optimize sends.
Batches can be at most 256 KB.
As explained in the Control access to IoT Hub section, IoT Hub enables per-device authentication and
access control.
IoT Hub allows you to create up to 10 custom endpoints. Messages are delivered to the endpoints based
on routes configured on your IoT hub. For more information, see Routing rules.
IoT Hub enables millions of simultaneously connected devices (see Quotas and throttling).
IoT Hub does not allow arbitrary partitioning. Device-to-cloud messages are partitioned based on their
originating deviceId.
For more information about the differences between IoT Hub and Event Hubs, see Comparison of Azure IoT
Hub and Azure Event Hubs.

Send non-telemetry traffic


Often, in addition to telemetry, devices send messages and requests that require separate execution and
handling in the solution back end. For example, critical alerts that must trigger a specific action in the back
end. You can write a routing rule to send these types of messages to an endpoint dedicated to their processing
based on either a header on the message or a value in the message body.
For more information about the best way to process this kind of message, see the Tutorial: How to process IoT
Hub device-to-cloud messages tutorial.

Route device-to-cloud messages


You have two options for routing device-to-cloud messages to your back-end apps:
Use the built-in Event Hub-compatible endpoint to enable back-end apps to read the device-to-cloud
messages received by the hub. To learn about the built-in Event Hub-compatible endpoint, see Read
device-to-cloud messages from the built-in endpoint.
Use routing rules to send messages to custom endpoints in your IoT hub. Custom endpoints enable your
back-end apps to read device-to-cloud messages using Event Hubs, Service Bus queues, or Service Bus
topics. To learn about routing and custom endpoints, see Use custom endpoints and routing rules for
device-to-cloud messages.

Anti-spoofing properties
To avoid device spoofing in device-to-cloud messages, IoT Hub stamps all messages with the following
properties:
ConnectionDeviceId
ConnectionDeviceGenerationId
ConnectionAuthMethod
The first two contain the deviceId and generationId of the originating device, as per Device identity
properties.
The ConnectionAuthMethod property contains a JSON serialized object, with the following properties:

{
"scope": "{ hub | device }",
"type": "{ symkey | sas | x509 }",
"issuer": "iothub"
}

Next steps
For information about the SDKs you can use to send device-to-cloud messages, see Azure IoT SDKs.
The Get Started tutorials show you how to send device-to-cloud messages from both simulated and physical
devices. For more detail, see the Process IoT Hub device-to-cloud messages using routes tutorial.
Read device-to-cloud messages from the built-in
endpoint
6/6/2018 • 2 min to read • Edit Online

By default, messages are routed to the built-in service-facing endpoint (messages/events) that is compatible
with Event Hubs. This endpoint is currently only exposed using the AMQP protocol on port 5671. An IoT hub
exposes the following properties to enable you to control the built-in Event Hub-compatible messaging endpoint
messages/events.

PROPERTY DESCRIPTION

Partition count Set this property at creation to define the number of


partitions for device-to-cloud event ingestion.

Retention time This property specifies how long in days messages are
retained by IoT Hub. The default is one day, but it can be
increased to seven days.

IoT Hub also enables you to manage consumer groups on the built-in device-to-cloud receive endpoint.
By default, all messages that do not explicitly match a message routing rule are written to the built-in endpoint. If
you disable this fallback route, messages that do not explicitly match any message routing rules are dropped.
You can modify the retention time, either programmatically using the IoT Hub resource provider REST APIs, or
with the Azure portal.
IoT Hub exposes the messages/events built-in endpoint for your back-end services to read the device-to-cloud
messages received by your hub. This endpoint is Event Hub-compatible, which enables you to use any of the
mechanisms the Event Hubs service supports for reading messages.

Read from the built-in endpoint


When you use the Azure Service Bus SDK for .NET or the Event Hubs - Event Processor Host, you can use any
IoT Hub connection strings with the correct permissions. Then use messages/events as the Event Hub name.
When you use SDKs (or product integrations) that are unaware of IoT Hub, you must retrieve an Event Hub-
compatible endpoint and Event Hub-compatible name:
1. Sign in to the Azure portal and navigate to your IoT hub.
2. Click Endpoints.
3. In the Built-in endpoints section, click Events.
4. A properties page opens, which contains the following values: Event Hub-compatible endpoint, Event
Hub-compatible name, Partitions, Retention time, and Consumer groups.
The IoT Hub SDK requires the IoT Hub endpoint name, which is messages/events as shown under Endpoints.
If the SDK you are using requires a Hostname or Namespace value, remove the scheme from the Event Hub-
compatible endpoint. For example, if your Event Hub-compatible endpoint is sb://iothub-ns-myiothub-
1234.servicebus.windows.net/, the Hostname would be iothub-ns-myiothub-
1234.servicebus.windows.net. The Namespace would be iothub-ns-myiothub-1234.
You can then use any shared access policy that has the ServiceConnect permissions to connect to the specified
Event Hub.
If you need to build an Event Hub connection string by using the previous information, use the following pattern:
Endpoint={Event Hub-compatible endpoint};SharedAccessKeyName={iot hub policy name};SharedAccessKey={iot hub
policy key}

The SDKs and integrations that you can use with Event Hub-compatible endpoints that IoT Hub exposes
includes the items in the following list:
Java Event Hubs client.
Apache Storm spout. You can view the spout source on GitHub.
Apache Spark integration.

Next steps
For more information about IoT Hub endpoints, see IoT Hub endpoints.
The Get Started tutorials show you how to send device-to-cloud messages from simulated devices and read the
messages from the built-in endpoint. For more detail, see the Process IoT Hub device-to-cloud messages using
routes tutorial.
If you want to route your device-to-cloud messages to custom endpoints, see Use message routes and custom
endpoints for device-to-cloud messages.
React to IoT Hub events by using Event Grid to
trigger actions - Preview
5/29/2018 • 2 min to read • Edit Online

Azure IoT Hub integrates with Azure Event Grid so that you can send event notifications to other services and
trigger downstream processes. Configure your business applications to listen for IoT Hub events so that you can
react to critical events in a reliable, scalable, and secure manner. For example, build an application to perform
multiple actions like updating a database, creating a ticket, and delivering an email notification every time a new
IoT device is registered to your IoT hub.
Azure Event Grid is a fully managed event routing service that uses a publish-subscribe model. Event Grid has
built-in support for Azure services like Azure Functions and Azure Logic Apps, and can deliver event alerts to non-
Azure services using webhooks. For a complete list of the event handlers that Event Grid supports, see An
introduction to Azure Event Grid.

Regional availability
The Event Grid integration is available for IoT hubs located in the regions where Event Grid is supported. For the
latest list of regions, see An introduction to Azure Event Grid.

Event types
IoT Hub publishes the following event types:

EVENT TYPE DESCRIPTION

Microsoft.Devices.DeviceCreated Published when a device is registered to an IoT hub.

Microsoft.Devices.DeviceDeleted Published when a device is deleted from an IoT hub.


Use either the Azure portal or Azure CLI to configure which events to publish from each IoT hub. For an example,
try the tutorial Send email notifications about Azure IoT Hub events using Logic Apps.

Event schema
IoT Hub events contain all the information you need to respond to changes in your device lifecycle. You can
identify an IoT Hub event by checking that the eventType property starts with Microsoft.Devices. For more
information about how to use Event Grid event properties, see the Event Grid event schema.
Device created schema
The following example shows the schema of a device created event:

[{
"id": "56afc886-767b-d359-d59e-0da7877166b2",
"topic": "/SUBSCRIPTIONS/<subscription ID>/RESOURCEGROUPS/<resource group
name>/PROVIDERS/MICROSOFT.DEVICES/IOTHUBS/<hub name>",
"subject": "devices/LogicAppTestDevice",
"eventType": "Microsoft.Devices.DeviceCreated",
"eventTime": "2018-01-02T19:17:44.4383997Z",
"data": {
"twin": {
"deviceId": "LogicAppTestDevice",
"etag": "AAAAAAAAAAE=",
"status": "enabled",
"statusUpdateTime": "0001-01-01T00:00:00",
"connectionState": "Disconnected",
"lastActivityTime": "0001-01-01T00:00:00",
"cloudToDeviceMessageCount": 0,
"authenticationType": "sas",
"x509Thumbprint": {
"primaryThumbprint": null,
"secondaryThumbprint": null
},
"version": 2,
"properties": {
"desired": {
"$metadata": {
"$lastUpdated": "2018-01-02T19:17:44.4383997Z"
},
"$version": 1
},
"reported": {
"$metadata": {
"$lastUpdated": "2018-01-02T19:17:44.4383997Z"
},
"$version": 1
}
}
},
"hubName": "egtesthub1",
"deviceId": "LogicAppTestDevice",
"operationTimestamp": "2018-01-02T19:17:44.4383997Z",
"opType": "DeviceCreated"
},
"dataVersion": "",
"metadataVersion": "1"
}]

For a detailed description of each property, see Azure Event Grid event schema for IoT Hub

Filter events
IoT Hub event subscriptions can filter events based on event type and device name. Subject filters in Event Grid
work based on prefix and suffix matches. The filter uses an AND operator, so events with a subject that match
both the prefix and suffix are delivered to the subscriber.
The subject of IoT Events uses the format:

devices/{deviceId}

Tips for consuming events


Applications that handle IoT Hub events should follow these suggested practices:
Multiple subscriptions can be configured to route events to the same event handler, so it's important not to
assume that events are from a particular source. Always check the message topic to ensure that it comes from
the IoT hub that you expect.
Don't assume that all events you receive are the types that you expect. Always check the eventType before
processing the message.
Messages can arrive out of order or after a delay. Use the etag field to understand if your information about
objects is up-to-date.

Next steps
Try the IoT Hub events tutorial
Learn more about Event Grid
Compare the differences between routing IoT Hub events and messages
Use message routes and custom endpoints for
device-to-cloud messages
6/6/2018 • 2 min to read • Edit Online

IoT Hub enables you to route device-to-cloud messages to IoT Hub service-facing endpoints based on
message properties. Routing rules give you the flexibility to send messages where they need to go without the
need for additional services or custom code. Each routing rule you configure has the following properties:

PROPERTY DESCRIPTION

Name The unique name that identifies the rule.

Source The origin of the data stream to be acted upon. For


example, device telemetry.

Condition The query expression for the routing rule that is run against
the message's headers and body and determines if it is a
match for the endpoint. For more information about
constructing a route condition, see the Reference - query
language for device twins and jobs.

Endpoint The name of the endpoint where IoT Hub sends messages
that match the condition. Endpoints should be in the same
region as the IoT hub, otherwise you may be charged for
cross-region writes.

A single message may match the condition on multiple routing rules, in which case IoT Hub delivers the
message to the endpoint associated with each matched rule. IoT Hub also automatically deduplicates message
delivery, so if a message matches multiple rules that have the same destination, it is only written once to that
destination.

Endpoints and routing


An IoT hub has a default built-in endpoint. You can create custom endpoints to route messages to by linking
other services in your subscription to the hub. IoT Hub currently supports Azure Storage containers, Event
Hubs, Service Bus queues, and Service Bus topics as custom endpoints.
When you use routing and custom endpoints, messages are only delivered to the built-in endpoint if they don't
match any rules. To deliver messages to the built-in endpoint as well as to a custom endpoint, add a route that
sends messages to the events endpoint.

NOTE
IoT Hub only supports writing data to Azure Storage containers as blobs.

WARNING
Service Bus queues and topics with Sessions or Duplicate Detection enabled are not supported as custom endpoints.
For more information about creating custom endpoints in IoT Hub, see IoT Hub endpoints.
For more information about reading from custom endpoints, see:
Reading from Azure Storage containers.
Reading from Event Hubs.
Reading from Service Bus queues.
Reading from Service Bus topics.

Latency
When you route device-to-cloud telemetry messages using built-in endpoints, there is a slight increase in the
end-to-end latency after the creation of the first route.
In most cases, the average increase in latency is less than one second. You can monitor the latency using
d2c.endpoints.latency.builtIn.events IoT Hub metric. Creating or deleting any route after the first one does
not impact the end-to-end latency.
Next steps
For more information about IoT Hub endpoints, see IoT Hub endpoints.
For more information about the query language you use to define routing rules, see IoT Hub query language
for device twins, jobs, and message routing.
The Process IoT Hub device-to-cloud messages using routes tutorial shows you how to use routing rules and
custom endpoints.
Send cloud-to-device messages from IoT Hub
5/29/2018 • 5 min to read • Edit Online

To send one-way notifications to the device app from your solution back end, send cloud-to-devices messages
from your IoT hub to your device. For a discussion of other cloud-to-devices options supported by IoT Hub,
see Cloud-to-device communications guidance.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

You send cloud-to-device messages through a service-facing endpoint (/messages/devicebound). A device


then receives the messages through a device-specific endpoint
(/devices/{deviceId}/messages/devicebound).
To target each cloud-to-device message at a single device, IoT Hub sets the to property to
/devices/{deviceId}/messages/devicebound.
Each device queue holds at most 50 cloud-to-device messages. Trying to send more messages to the same
device results in an error.

The cloud-to-device message lifecycle


To guarantee at-least-once message delivery, IoT Hub persists cloud-to-device messages in per-device queues.
Devices must explicitly acknowledge completion for IoT Hub to remove them from the queue. This approach
guarantees resiliency against connectivity and device failures.
The following diagram shows the lifecycle state graph for a cloud-to-device message in IoT Hub.

When the IoT Hub service sends a message to a device, the service sets the message state to Enqueued.
When a device wants to receive a message, IoT Hub locks the message (by setting the state to Invisible), which
allows other threads on the device to start receiving other messages. When a device thread completes the
processing of a message, it notifies IoT Hub by completing the message. IoT Hub then sets the state to
Completed.
A device can also choose to:
Reject the message, which causes IoT Hub to set it to the Dead lettered state. Devices that connect over the
MQTT protocol cannot reject cloud-to-device messages.
Abandon the message, which causes IoT Hub to put the message back in the queue, with the state set to
Enqueued. Devices that connect over the MQTT protocol cannot abandon cloud-to-device messages.
A thread could fail to process a message without notifying IoT Hub. In this case, messages automatically
transition from the Invisible state back to the Enqueued state after a visibility (or lock) timeout. The default
value of this timeout is one minute.
The max delivery count property on IoT Hub determines the maximum number of times a message can
transition between the Enqueued and Invisible states. After that number of transitions, IoT Hub sets the state
of the message to Dead lettered. Similarly, IoT Hub sets the state of a message to Dead lettered after its
expiration time (see Time to live).
The How to send cloud-to-device messages with IoT Hub shows you how to send cloud-to-device messages
from the cloud and receive them on a device.
Typically, a device completes a cloud-to-device message when the loss of the message does not affect the
application logic. For example, when the device has persisted the message content locally or has successfully
executed an operation. The message could also carry transient information, whose loss would not impact the
functionality of the application. Sometimes, for long-running tasks, you can:
Complete the cloud-to-device message after persisting the task description in local storage.
Notify the solution back end with one or more device-to-cloud messages at various stages of progress of
the task.

Message expiration (time to live)


Every cloud-to-device message has an expiration time. This time is set by one of:
The ExpiryTimeUtc property in the service.
IoT Hub using the default time to live specified as an IoT Hub property.
See Cloud-to-device configuration options.
A common way to take advantage of message expiration and avoid sending messages to disconnected devices,
is to set short time to live values. This approach achieves the same result as maintaining the device connection
state, while being more efficient. When you request message acknowledgements, IoT Hub notifies you which
devices are:
Able to receive messages.
Are not online or have failed.

Message feedback
When you send a cloud-to-device message, the service can request the delivery of per-message feedback
regarding the final state of that message.

ACK PROPERTY BEHAVIOR

positive If the cloud-to-device message reaches the Completed


state, IoT Hub generates a feedback message.
ACK PROPERTY BEHAVIOR

negative If the cloud-to-device message reaches the Dead lettered


state, IoT Hub generates a feedback message.

full IoT Hub generates a feedback message in either case.

If Ack is full, and you don't receive a feedback message, it means that the feedback message expired. The
service can't know what happened to the original message. In practice, a service should ensure that it can
process the feedback before it expires. The maximum expiry time is two days, which leaves time to get the
service running again if a failure occurs.
As explained in Endpoints, IoT Hub delivers feedback through a service-facing endpoint
(/messages/servicebound/feedback) as messages. The semantics for receiving feedback are the same as for
cloud-to-device messages. Whenever possible, message feedback is batched in a single message, with the
following format:

PROPERTY DESCRIPTION

EnqueuedTime Timestamp indicating when the feedback message was


received by the hub.

UserId {iot hub name}

ContentType application/vnd.microsoft.iothub.feedback.json

The body is a JSON -serialized array of records, each with the following properties:

PROPERTY DESCRIPTION

EnqueuedTimeUtc Timestamp indicating when the outcome of the message


happened. For example, the hub received the feedback
message or the original message expired.

OriginalMessageId MessageId of the cloud-to-device message to which this


feedback information relates.

StatusCode Required string. Used in feedback messages generated by


IoT Hub.
'Success'
'Expired'
'DeliveryCountExceeded'
'Rejected'
'Purged'

Description String values for StatusCode.

DeviceId DeviceId of the target device of the cloud-to-device


message to which this piece of feedback relates.

DeviceGenerationId DeviceGenerationId of the target device of the cloud-to-


device message to which this piece of feedback relates.

The service must specify a MessageId for the cloud-to-device message to be able to correlate its feedback
with the original message.
The following example shows the body of a feedback message.

[
{
"OriginalMessageId": "0987654321",
"EnqueuedTimeUtc": "2015-07-28T16:24:48.789Z",
"StatusCode": 0,
"Description": "Success",
"DeviceId": "123",
"DeviceGenerationId": "abcdefghijklmnopqrstuvwxyz"
},
{
...
},
...
]

Cloud-to-device configuration options


Each IoT hub exposes the following configuration options for cloud-to-device messaging:

PROPERTY DESCRIPTION RANGE AND DEFAULT

defaultTtlAsIso8601 Default TTL for cloud-to-device ISO_8601 interval up to 2D (minimum


messages. 1 minute). Default: 1 hour.

maxDeliveryCount Maximum delivery count for cloud-to- 1 to 100. Default: 10.


device per-device queues.

feedback.ttlAsIso8601 Retention for service-bound feedback ISO_8601 interval up to 2D (minimum


messages. 1 minute). Default: 1 hour.

feedback.maxDeliveryCount Maximum delivery count for feedback 1 to 100. Default: 100.


queue.

For more information about how to set these configuration options, see Create IoT hubs.

Next steps
For information about the SDKs you can use to receive cloud-to-device messages, see Azure IoT SDKs.
To try out receiving cloud-to-device messages, see the Send cloud-to-device tutorial.
Create and read IoT Hub messages
5/29/2018 • 3 min to read • Edit Online

To support seamless interoperability across protocols, IoT Hub defines a common message format for all device-
facing protocols. This message format is used for both device-to-cloud and cloud-to-device messages.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are
only available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to
choose the right IoT Hub tier.

An IoT Hub message consists of:


A set of system properties. Properties that IoT Hub interprets or sets. This set is predetermined.
A set of application properties. A dictionary of string properties that the application can define and access,
without needing to deserialize the message body. IoT Hub never modifies these properties.
An opaque binary body.
Property names and values can only contain ASCII alphanumeric characters, plus
{'!', '#', '$', '%, '&', "'", '*', '+', '-', '.', '^', '_', '`', '|', '~'} when you:

Send device-to-cloud messages using the HTTPS protocol.


Send cloud-to-device messages.
For more information about how to encode and decode messages sent using different protocols, see Azure IoT
SDKs.
The following table lists the set of system properties in IoT Hub messages.

PROPERTY DESCRIPTION

MessageId A user-settable identifier for the message used for request-


reply patterns. Format: A case-sensitive string (up to 128
characters long) of ASCII 7-bit alphanumeric characters +
{'-', ':',’.', '+', '%', '_', '#', '*', '?', '!',
'(', ')', ',', '=', '@', ';', '$', '''}
.

Sequence number A number (unique per device-queue) assigned by IoT Hub to


each cloud-to-device message.

To A destination specified in Cloud-to-Device messages.

ExpiryTimeUtc Date and time of message expiration.

EnqueuedTime Date and time the Cloud-to-Device message was received by


IoT Hub.

CorrelationId A string property in a response message that typically


contains the MessageId of the request, in request-reply
patterns.
PROPERTY DESCRIPTION

UserId An ID used to specify the origin of messages. When messages


are generated by IoT Hub, it is set to {iot hub name} .

Ack A feedback message generator. This property is used in cloud-


to-device messages to request IoT Hub to generate feedback
messages as a result of the consumption of the message by
the device. Possible values: none (default): no feedback
message is generated, positive: receive a feedback message if
the message was completed, negative: receive a feedback
message if the message expired (or maximum delivery count
was reached) without being completed by the device, or full:
both positive and negative. For more information, see
Message feedback.

ConnectionDeviceId An ID set by IoT Hub on device-to-cloud messages. It


contains the deviceId of the device that sent the message.

ConnectionDeviceGenerationId An ID set by IoT Hub on device-to-cloud messages. It


contains the generationId (as per Device identity properties)
of the device that sent the message.

ConnectionAuthMethod An authentication method set by IoT Hub on device-to-cloud


messages. This property contains information about the
authentication method used to authenticate the device
sending the message. For more information, see Device to
cloud anti-spoofing.

CreationTimeUtc Date and time the message was created on a device. A device
must set this value explicitly.

Message size
IoT Hub measures message size in a protocol-agnostic way, considering only the actual payload. The size in bytes
is calculated as the sum of the following:
The body size in bytes.
The size in bytes of all the values of the message system properties.
The size in bytes of all user property names and values.
Property names and values are limited to ASCII characters, so the length of the strings equals the size in bytes.

Next steps
For information about message size limits in IoT Hub, see IoT Hub quotas and throttling.
To learn how to create and read IoT Hub messages in various programming languages, see the Get started
tutorials.
Reference - choose a communication protocol
5/29/2018 • 2 min to read • Edit Online

IoT Hub allows devices to use the following protocols for device-side communications:
MQTT
MQTT over WebSockets
AMQP
AMQP over WebSockets
HTTPS
For information about how these protocols support specific IoT Hub features, see Device-to-cloud
communications guidance and Cloud-to-device communications guidance.
The following table provides the high-level recommendations for your choice of protocol:

PROTOCOL WHEN YOU SHOULD CHOOSE THIS PROTOCOL

MQTT Use on all devices that do not require to connect multiple


MQTT over WebSocket devices (each with its own per-device credentials) over the
same TLS connection.

AMQP Use on field and cloud gateways to take advantage of


AMQP over WebSocket connection multiplexing across devices.

HTTPS Use for devices that cannot support other protocols.

Consider the following points when you choose your protocol for device-side communications:
Cloud-to-device pattern. HTTPS does not have an efficient way to implement server push. As such, when
you are using HTTPS, devices poll IoT Hub for cloud-to-device messages. This approach is inefficient for both
the device and IoT Hub. Under current HTTPS guidelines, each device should poll for messages every 25
minutes or more. MQTT and AMQP support server push when receiving cloud-to-device messages. They
enable immediate pushes of messages from IoT Hub to the device. If delivery latency is a concern, MQTT or
AMQP are the best protocols to use. For rarely connected devices, HTTPS works as well.
Field gateways. When using MQTT and HTTPS, you cannot connect multiple devices (each with its own per-
device credentials) using the same TLS connection. For Field gateway scenarios that require one TLS
connection between the field gateway and IoT Hub for each connected device, these protocols are suboptimal.
Low resource devices. The MQTT and HTTPS libraries have a smaller footprint than the AMQP libraries. As
such, if the device has limited resources (for example, less than 1-MB RAM ), these protocols might be the only
protocol implementation available.
Network traversal. The standard AMQP protocol uses port 5671, and MQTT listens on port 8883. USe of
these ports could cause problems in networks that are closed to non-HTTPS protocols. Use MQTT over
WebSockets, AMQP over WebSockets, or HTTPS in this scenario.
Payload size. MQTT and AMQP are binary protocols, which result in more compact payloads than HTTPS.
WARNING
When using HTTPS, each device should poll for cloud-to-device messages every 25 minutes or more. However, during
development, it is acceptable to poll more frequently than every 25 minutes.

Port numbers
Devices can communicate with IoT Hub in Azure using various protocols. Typically, the choice of protocol is driven
by the specific requirements of the solution. The following table lists the outbound ports that must be open for a
device to be able to use a specific protocol:

PROTOCOL PORT

MQTT 8883

MQTT over WebSockets 443

AMQP 5671

AMQP over WebSockets 443

HTTPS 443

Once you have created an IoT hub in an Azure region, the IoT hub keeps the same IP address for the lifetime of
that IoT hub. However, if Microsoft moves the IoT hub to a different scale unit to maintain quality of service, then
it is assigned a new IP address.

Next steps
To learn more about how IoT Hub implements the MQTT protocol, see Communicate with your IoT hub using the
MQTT protocol.
Upload files with IoT Hub
5/29/2018 • 5 min to read • Edit Online

As detailed in the IoT Hub endpoints article, a device can initiate a file upload by sending a notification through
a device-facing endpoint (/devices/{deviceId}/files). When a device notifies IoT Hub that an upload is
complete, IoT Hub sends a file upload notification message through the
/messages/servicebound/filenotifications service-facing endpoint.
Instead of brokering messages through IoT Hub itself, IoT Hub instead acts as a dispatcher to an associated
Azure Storage account. A device requests a storage token from IoT Hub that is specific to the file the device
wishes to upload. The device uses the SAS URI to upload the file to storage, and when the upload is complete
the device sends a notification of completion to IoT Hub. IoT Hub checks the file upload is complete and then
adds a file upload notification message to the service-facing file notification endpoint.
Before you upload a file to IoT Hub from a device, you must configure your hub by associating an Azure
Storage account to it.
Your device can then initialize an upload and then notify IoT hub when the upload completes. Optionally, when
a device notifies IoT Hub that the upload is complete, the service can generate a notification message.
When to use
Use file upload to send media files and large telemetry batches uploaded by intermittently connected devices or
compressed to save bandwidth.
Refer to Device-to-cloud communication guidance if in doubt between using reported properties, device-to-
cloud messages, or file upload.

Associate an Azure Storage account with IoT Hub


To use the file upload functionality, you must first link an Azure Storage account to the IoT Hub. You can
complete this task either through the Azure portal, or programmatically through the IoT Hub resource provider
REST APIs. Once you have associated an Azure Storage account with your IoT Hub, the service returns a SAS
URI to a device when the device initiates a file upload request.

NOTE
The Azure IoT SDKs automatically handle retrieving the SAS URI, uploading the file, and notifying IoT Hub of a completed
upload.

Initialize a file upload


IoT Hub has an endpoint specifically for devices to request a SAS URI for storage to upload a file. To initiate the
file upload process, the device sends a POST request to {iot hub}.azure-devices.net/devices/{deviceId}/files
with the following JSON body:

{
"blobName": "{name of the file for which a SAS URI will be generated}"
}

IoT Hub returns the following data, which the device uses to upload the file:
{
"correlationId": "somecorrelationid",
"hostName": "contoso.azure-devices.net",
"containerName": "testcontainer",
"blobName": "test-device1/image.jpg",
"sasToken": "1234asdfSAStoken"
}

Deprecated: initialize a file upload with a GET

NOTE
This section describes deprecated functionality for how to receive a SAS URI from IoT Hub. Use the POST method
described previously.

IoT Hub has two REST endpoints to support file upload, one to get the SAS URI for storage and the other to
notify the IoT hub of a completed upload. The device initiates the file upload process by sending a GET to the
IoT hub at {iot hub}.azure-devices.net/devices/{deviceId}/files/{filename} . The IoT hub returns:
A SAS URI specific to the file to be uploaded.
A correlation ID to be used once the upload is completed.

Notify IoT Hub of a completed file upload


The device is responsible for uploading the file to storage using the Azure Storage SDKs. When the upload is
complete, the device sends a POST request to
{iot hub}.azure-devices.net/devices/{deviceId}/files/notifications with the following JSON body:

{
"correlationId": "{correlation ID received from the initial request}",
"isSuccess": bool,
"statusCode": XXX,
"statusDescription": "Description of status"
}

The value of isSuccess is a Boolean representing whether the file was uploaded successfully. The status code
for statusCode is the status for the upload of the file to storage, and the statusDescription corresponds to the
statusCode .

Reference topics:
The following reference topics provide you with more information about uploading files from a device.

File upload notifications


Optionally, when a device notifies IoT Hub that an upload is complete, IoT Hub generates a notification
message that contains the name and storage location of the file.
As explained in Endpoints, IoT Hub delivers file upload notifications through a service-facing endpoint
(/messages/servicebound/fileuploadnotifications) as messages. The receive semantics for file upload
notifications are the same as for cloud-to-device messages and have the same message lifecycle. Each message
retrieved from the file upload notification endpoint is a JSON record with the following properties:
PROPERTY DESCRIPTION

EnqueuedTimeUtc Timestamp indicating when the notification was created.

DeviceId DeviceId of the device which uploaded the file.

BlobUri URI of the uploaded file.

BlobName Name of the uploaded file.

LastUpdatedTime Timestamp indicating when the file was last updated.

BlobSizeInBytes Size of the uploaded file.

Example. This example shows the body of a file upload notification message.

{
"deviceId":"mydevice",
"blobUri":"https://{storage account}.blob.core.windows.net/{container name}/mydevice/myfile.jpg",
"blobName":"mydevice/myfile.jpg",
"lastUpdatedTime":"2016-06-01T21:22:41+00:00",
"blobSizeInBytes":1234,
"enqueuedTimeUtc":"2016-06-01T21:22:43.7996883Z"
}

File upload notification configuration options


Each IoT hub exposes the following configuration options for file upload notifications:

PROPERTY DESCRIPTION RANGE AND DEFAULT

enableFileUploadNotifications Controls whether file upload Bool. Default: True.


notifications are written to the file
notifications endpoint.

fileNotifications.ttlAsIso8601 Default TTL for file upload notifications. ISO_8601 interval up to 48H
(minimum 1 minute). Default: 1 hour.

fileNotifications.lockDuration Lock duration for the file upload 5 to 300 seconds (minimum 5
notifications queue. seconds). Default: 60 seconds.

fileNotifications.maxDeliveryCount Maximum delivery count for the file 1 to 100. Default: 100.
upload notification queue.

Additional reference material


Other reference topics in the IoT Hub developer guide include:
IoT Hub endpoints describes the various endpoints that each IoT hub exposes for run-time and management
operations.
Throttling and quotas describes the quotas and throttling behaviors that apply to the IoT Hub service.
Azure IoT device and service SDKs lists the various language SDKs you can use when you develop both
device and service apps that interact with IoT Hub.
IoT Hub query language describes the query language you can use to retrieve information from IoT Hub
about your device twins and jobs.
IoT Hub MQTT support provides more information about IoT Hub support for the MQTT protocol.

Next steps
Now you have learned how to upload files from devices using IoT Hub, you may be interested in the following
IoT Hub developer guide topics:
Manage device identities in IoT Hub
Control access to IoT Hub
Use device twins to synchronize state and configurations
Invoke a direct method on a device
Schedule jobs on multiple devices
To try out some of the concepts described in this article, see the following IoT Hub tutorial:
How to upload files from devices to the cloud with IoT Hub
Understand the identity registry in your IoT
hub
5/29/2018 • 10 min to read • Edit Online

Every IoT hub has an identity registry that stores information about the devices and modules
permitted to connect to the IoT hub. Before a device or module can connect to an IoT hub, there
must be an entry for that device or module in the IoT hub's identity registry. A device or module
must also authenticate with the IoT hub based on credentials stored in the identity registry.
The device or module ID stored in the identity registry is case-sensitive.
At a high level, the identity registry is a REST-capable collection of device or module identity
resources. When you add an entry in the identity registry, IoT Hub creates a set of per-device
resources such as the queue that contains in-flight cloud-to-device messages.
Use the identity registry when you need to:
Provision devices or modules that connect to your IoT hub.
Control per-device/per-module access to your hub's device or module-facing endpoints.

NOTE
The identity registry does not contain any application-specific metadata.

Identity registry operations


The IoT Hub identity registry exposes the following operations:
Create device or module identity
Update device or module identity
Retrieve device or module identity by ID
Delete device or module identity
List up to 1000 identities > Module identity and module twin is in public preview. Below feature
will be supported on module identity when it's general available.
Export device identities to Azure blob storage
Import device identities from Azure blob storage
All these operations can use optimistic concurrency, as specified in RFC7232.

IMPORTANT
The only way to retrieve all identities in an IoT hub's identity registry is to use the Export functionality.

An IoT Hub identity registry:


Does not contain any application metadata.
Can be accessed like a dictionary, by using the deviceId or moduleId as the key.
Does not support expressive queries.
An IoT solution typically has a separate solution-specific store that contains application-specific
metadata. For example, the solution-specific store in a smart building solution would record the
room in which a temperature sensor is deployed.

IMPORTANT
Only use the identity registry for device management and provisioning operations. High throughput
operations at run time should not depend on performing operations in the identity registry. For example,
checking the connection state of a device before sending a command is not a supported pattern. Make sure
to check the throttling rates for the identity registry, and the device heartbeat pattern.

Disable devices
You can disable devices by updating the status property of an identity in the identity registry.
Typically, you use this property in two scenarios:
During a provisioning orchestration process. For more information, see Device Provisioning.
If, for any reason, you think a device is compromised or has become unauthorized.
This feature is not availble for modules.

Import and export device identities


Use asynchronous operations on the IoT Hub resource provider endpoint to export device identities
in bulk from an IoT hub's identity registry. Exports are long-running jobs that use a customer-
supplied blob container to save device identity data read from the identity registry.
Use asynchronous operations on the IoT Hub resource provider endpoint to import device identities
in bulk to an IoT hub's identity registry. Imports are long-running jobs that use data in a customer-
supplied blob container to write device identity data into the identity registry.
For more information about the import and export APIs, see IoT Hub resource provider REST APIs.
To learn more about running import and export jobs, see Bulk management of IoT Hub device
identities.

Device provisioning
The device data that a given IoT solution stores depends on the specific requirements of that
solution. But, as a minimum, a solution must store device identities and authentication keys. Azure
IoT Hub includes an identity registry that can store values for each device such as IDs, authentication
keys, and status codes. A solution can use other Azure services such as table storage, blob storage,
or Cosmos DB to store any additional device data.
Device provisioning is the process of adding the initial device data to the stores in your solution. To
enable a new device to connect to your hub, you must add a device ID and keys to the IoT Hub
identity registry. As part of the provisioning process, you might need to initialize device-specific data
in other solution stores. You can also use the Azure IoT Hub Device Provisioning Service to enable
zero-touch, just-in-time provisioning to one or more IoT hubs without requiring human intervention.
To learn more, see the provisioning service documentation.

Device heartbeat
The IoT Hub identity registry contains a field called connectionState. Only use the
connectionState field during development and debugging. IoT solutions should not query the field
at run time. For example, do not query the connectionState field to check if a device is connected
before you send a cloud-to-device message or an SMS.
If your IoT solution needs to know if a device is connected, you should implement the heartbeat
pattern.
In the heartbeat pattern, the device sends device-to-cloud messages at least once every fixed
amount of time (for example, at least once every hour). Therefore, even if a device does not have any
data to send, it still sends an empty device-to-cloud message (usually with a property that identifies
it as a heartbeat). On the service side, the solution maintains a map with the last heartbeat received
for each device. If the solution does not receive a heartbeat message within the expected time from
the device, it assumes that there is a problem with the device.
A more complex implementation could include the information from operations monitoring to
identify devices that are trying to connect or communicate but failing. When you implement the
heartbeat pattern, make sure to check IoT Hub Quotas and Throttles.

NOTE
If an IoT solution uses the connection state solely to determine whether to send cloud-to-device messages,
and messages are not broadcast to large sets of devices, consider using the simpler short expiry time
pattern. This pattern achieves the same result as maintaining a device connection state registry using the
heartbeat pattern, while being more efficient. If you request message acknowledgements, IoT Hub can notify
you about which devices are able to receive messages and which are not.

Device and module lifecycle notifications


IoT Hub can notify your IoT solution when an identity is created or deleted by sending lifecycle
notifications. To do so, your IoT solution needs to create a route and to set the Data Source equal to
DeviceLifecycleEvents or ModuleLifecycleEvents. By default, no lifecycle notifications are sent, that is,
no such routes pre-exist. The notification message includes properties, and body.
Properties: Message system properties are prefixed with the '$' symbol.
Notification message for device:

NAME VALUE

$content-type application/json

$iothub-enqueuedtime Time when the notification was sent

$iothub-message-source deviceLifecycleEvents

$content-encoding utf-8

opType createDeviceIdentity or deleteDeviceIdentity

hubName Name of IoT Hub

deviceId ID of the device

operationTimestamp ISO8601 timestamp of operation


NAME VALUE

iothub-message-schema deviceLifecycleNotification

Body: This section is in JSON format and represents the twin of the created device identity. For
example,

{
"deviceId":"11576-ailn-test-0-67333793211",
"etag":"AAAAAAAAAAE=",
"properties": {
"desired": {
"$metadata": {
"$lastUpdated": "2016-02-30T16:24:48.789Z"
},
"$version": 1
},
"reported": {
"$metadata": {
"$lastUpdated": "2016-02-30T16:24:48.789Z"
},
"$version": 1
}
}
}

Notification message for module:

NAME VALUE

$content-type application/json

$iothub-enqueuedtime Time when the notification was sent

$iothub-message-source moduleLifecycleEvents

$content-encoding utf-8

opType createModuleIdentity or deleteModuleIdentity

hubName Name of IoT Hub

moduleId ID of the module

operationTimestamp ISO8601 timestamp of operation

iothub-message-schema moduleLifecycleNotification

Body: This section is in JSON format and represents the twin of the created module identity. For
example,
{
"deviceId":"11576-ailn-test-0-67333793211",
"moduleId":"tempSensor",
"etag":"AAAAAAAAAAE=",
"properties": {
"desired": {
"$metadata": {
"$lastUpdated": "2016-02-30T16:24:48.789Z"
},
"$version": 1
},
"reported": {
"$metadata": {
"$lastUpdated": "2016-02-30T16:24:48.789Z"
},
"$version": 1
}
}
}

Device identity properties


Device identities are represented as JSON documents with the following properties:

PROPERTY OPTIONS DESCRIPTION

deviceId required, read-only on updates A case-sensitive string (up to 128


characters long) of ASCII 7-bit
alphanumeric characters plus
certain special characters:
- . + % _ # * ? ! ( ) , = @
$ '
.

generationId required, read-only An IoT hub-generated, case-


sensitive string up to 128
characters long. This value is used
to distinguish devices with the
same deviceId, when they have
been deleted and re-created.

etag required, read-only A string representing a weak ETag


for the device identity, as per
RFC7232.

auth optional A composite object containing


authentication information and
security materials.

auth.symkey optional A composite object containing a


primary and a secondary key,
stored in base64 format.

status required An access indicator. Can be


Enabled or Disabled. If Enabled,
the device is allowed to connect. If
Disabled, this device cannot
access any device-facing endpoint.
PROPERTY OPTIONS DESCRIPTION

statusReason optional A 128 character-long string that


stores the reason for the device
identity status. All UTF-8
characters are allowed.

statusUpdateTime read-only A temporal indicator, showing the


date and time of the last status
update.

connectionState read-only A field indicating connection


status: either Connected or
Disconnected. This field
represents the IoT Hub view of the
device connection status.
Important: This field should be
used only for
development/debugging
purposes. The connection state is
updated only for devices using
MQTT or AMQP. Also, it is based
on protocol-level pings (MQTT
pings, or AMQP pings), and it can
have a maximum delay of only 5
minutes. For these reasons, there
can be false positives, such as
devices reported as connected but
that are disconnected.

connectionStateUpdatedTime read-only A temporal indicator, showing the


date and last time the connection
state was updated.

lastActivityTime read-only A temporal indicator, showing the


date and last time the device
connected, received, or sent a
message.

NOTE
Connection state can only represent the IoT Hub view of the status of the connection. Updates to this state
may be delayed, depending on network conditions and configurations.

Module identity properties


Module identities are represented as JSON documents with the following properties:

PROPERTY OPTIONS DESCRIPTION

deviceId required, read-only on updates A case-sensitive string (up to 128


characters long) of ASCII 7-bit
alphanumeric characters plus
certain special characters:
- . + % _ # * ? ! ( ) , = @
$ '
.
PROPERTY OPTIONS DESCRIPTION

moduleId required, read-only on updates A case-sensitive string (up to 128


characters long) of ASCII 7-bit
alphanumeric characters plus
certain special characters:
- . + % _ # * ? ! ( ) , = @
$ '
.

generationId required, read-only An IoT hub-generated, case-


sensitive string up to 128
characters long. This value is used
to distinguish devices with the
same deviceId, when they have
been deleted and re-created.

etag required, read-only A string representing a weak ETag


for the device identity, as per
RFC7232.

auth optional A composite object containing


authentication information and
security materials.

auth.symkey optional A composite object containing a


primary and a secondary key,
stored in base64 format.

status required An access indicator. Can be


Enabled or Disabled. If Enabled,
the device is allowed to connect. If
Disabled, this device cannot
access any device-facing endpoint.

statusReason optional A 128 character-long string that


stores the reason for the device
identity status. All UTF-8
characters are allowed.

statusUpdateTime read-only A temporal indicator, showing the


date and time of the last status
update.
PROPERTY OPTIONS DESCRIPTION

connectionState read-only A field indicating connection


status: either Connected or
Disconnected. This field
represents the IoT Hub view of the
device connection status.
Important: This field should be
used only for
development/debugging
purposes. The connection state is
updated only for devices using
MQTT or AMQP. Also, it is based
on protocol-level pings (MQTT
pings, or AMQP pings), and it can
have a maximum delay of only 5
minutes. For these reasons, there
can be false positives, such as
devices reported as connected but
that are disconnected.

connectionStateUpdatedTime read-only A temporal indicator, showing the


date and last time the connection
state was updated.

lastActivityTime read-only A temporal indicator, showing the


date and last time the device
connected, received, or sent a
message.

Additional reference material


Other reference topics in the IoT Hub developer guide include:
IoT Hub endpoints describes the various endpoints that each IoT hub exposes for run-time and
management operations.
Throttling and quotas describes the quotas and throttling behaviors that apply to the IoT Hub
service.
Azure IoT device and service SDKs lists the various language SDKs you can use when you
develop both device and service apps that interact with IoT Hub.
IoT Hub query language describes the query language you can use to retrieve information from
IoT Hub about your device twins and jobs.
IoT Hub MQTT support provides more information about IoT Hub support for the MQTT
protocol.

Next steps
Now that you have learned how to use the IoT Hub identity registry, you may be interested in the
following IoT Hub developer guide topics:
Control access to IoT Hub
Use device twins to synchronize state and configurations
Invoke a direct method on a device
Schedule jobs on multiple devices
To try out some of the concepts described in this article, see the following IoT Hub tutorial:
Get started with Azure IoT Hub
To explore using the IoT Hub Device Provisioning Service to enable zero-touch, just-in-time
provisioning, see:
Azure IoT Hub Device Provisioning Service
Control access to IoT Hub
6/6/2018 • 16 min to read • Edit Online

This article describes the options for securing your IoT hub. IoT Hub uses permissions to grant access
to each IoT hub endpoint. Permissions limit the access to an IoT hub based on functionality.
This article introduces:
The different permissions that you can grant to a device or back-end app to access your IoT hub.
The authentication process and the tokens it uses to verify permissions.
How to scope credentials to limit access to specific resources.
IoT Hub support for X.509 certificates.
Custom device authentication mechanisms that use existing device identity registries or
authentication schemes.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device
management, are only available in the standard tier of IoT hub. For more information about the basic and
standard IoT Hub tiers, see How to choose the right IoT Hub tier.

You must have appropriate permissions to access any of the IoT Hub endpoints. For example, a device
must include a token containing security credentials along with every message it sends to IoT Hub.

Access control and permissions


You can grant permissions in the following ways:
IoT hub-level shared access policies. Shared access policies can grant any combination of
permissions. You can define policies in the Azure portal, or programmatically by using the IoT
Hub resource provider REST APIs. A newly created IoT hub has the following default policies:
iothubowner: Policy with all permissions.
service: Policy with ServiceConnect permission.
device: Policy with DeviceConnect permission.
registryRead: Policy with RegistryRead permission.
registryReadWrite: Policy with RegistryRead and RegistryWrite permissions.
Per-device security credentials. Each IoT Hub contains an identity registry. For each
device in this identity registry, you can configure security credentials that grant
DeviceConnect permissions scoped to the corresponding device endpoints.
For example, in a typical IoT solution:
The device management component uses the registryReadWrite policy.
The event processor component uses the service policy.
The run-time device business logic component uses the service policy.
Individual devices connect using credentials stored in the IoT hub's identity registry.
NOTE
See permissions for detailed information.

Authentication
Azure IoT Hub grants access to endpoints by verifying a token against the shared access policies and
identity registry security credentials.
Security credentials, such as symmetric keys, are never sent over the wire.

NOTE
The Azure IoT Hub resource provider is secured through your Azure subscription, as are all providers in the
Azure Resource Manager.

For more information about how to construct and use security tokens, see IoT Hub security tokens.
Protocol specifics
Each supported protocol, such as MQTT, AMQP, and HTTPS, transports tokens in different ways.
When using MQTT, the CONNECT packet has the deviceId as the ClientId,
{iothubhostname}/{deviceId} in the Username field, and a SAS token in the Password field.
{iothubhostname} should be the full CName of the IoT hub (for example, contoso.azure-devices.net).

When using AMQP, IoT Hub supports SASL PL AIN and AMQP Claims-Based-Security.
If you use AMQP claims-based-security, the standard specifies how to transmit these tokens.
For SASL PL AIN, the username can be:
{policyName}@sas.root.{iothubName} if using IoT hub-level tokens.
{deviceId}@sas.{iothubname} if using device-scoped tokens.

In both cases, the password field contains the token, as described in IoT Hub security tokens.
HTTPS implements authentication by including a valid token in the Authorization request header.
Example
Username (DeviceId is case-sensitive): iothubname.azure-devices.net/DeviceId

Password (Generate SAS token with the device explorer tool):


SharedAccessSignature sr=iothubname.azure-
devices.net%2fdevices%2fDeviceId&sig=kPszxZZZZZZZZZZZZZZZZZAhLT%2bV7o%3d&se=1487709501

NOTE
The Azure IoT SDKs automatically generate tokens when connecting to the service. In some cases, the Azure
IoT SDKs do not support all the protocols or all the authentication methods.

Special considerations for SASL PLAIN


When using SASL PL AIN with AMQP, a client connecting to an IoT hub can use a single token for
each TCP connection. When the token expires, the TCP connection disconnects from the service and
triggers a reconnection. This behavior, while not problematic for a back-end app, is damaging for a
device app for the following reasons:
Gateways usually connect on behalf of many devices. When using SASL PL AIN, they have to create
a distinct TCP connection for each device connecting to an IoT hub. This scenario considerably
increases the consumption of power and networking resources, and increases the latency of each
device connection.
Resource-constrained devices are adversely affected by the increased use of resources to reconnect
after each token expiration.

Scope IoT hub-level credentials


You can scope IoT hub-level security policies by creating tokens with a restricted resource URI. For
example, the endpoint to send device-to-cloud messages from a device is
/devices/{deviceId}/messages/events. You can also use an IoT hub-level shared access policy with
DeviceConnect permissions to sign a token whose resourceURI is /devices/{deviceId}. This
approach creates a token that is only usable to send messages on behalf of device deviceId.
This mechanism is similar to the Event Hubs publisher policy, and enables you to implement custom
authentication methods.

Security tokens
IoT Hub uses security tokens to authenticate devices and services to avoid sending keys on the wire.
Additionally, security tokens are limited in time validity and scope. Azure IoT SDKs automatically
generate tokens without requiring any special configuration. Some scenarios do require you to
generate and use security tokens directly. Such scenarios include:
The direct use of the MQTT, AMQP, or HTTPS surfaces.
The implementation of the token service pattern, as explained in Custom device authentication.
IoT Hub also allows devices to authenticate with IoT Hub using X.509 certificates.
Security token structure
You use security tokens to grant time-bounded access to devices and services to specific functionality
in IoT Hub. To get authorization to connect to IoT Hub, devices and services must send security tokens
signed with either a shared access or symmetric key. These keys are stored with a device identity in the
identity registry.
A token signed with a shared access key grants access to all the functionality associated with the
shared access policy permissions. A token signed with a device identity's symmetric key only grants the
DeviceConnect permission for the associated device identity.
The security token has the following format:
SharedAccessSignature sig={signature-string}&se={expiry}&skn={policyName}&sr={URL-encoded-
resourceURI}

Here are the expected values:

VALUE DESCRIPTION

{signature} An HMAC-SHA256 signature string of the form:


{URL-encoded-resourceURI} + "\n" + expiry .
Important: The key is decoded from base64 and used
as key to perform the HMAC-SHA256 computation.
VALUE DESCRIPTION

{resourceURI} URI prefix (by segment) of the endpoints that can be


accessed with this token, starting with host name of
the IoT hub (no protocol). For example,
myHub.azure-devices.net/devices/device1

{expiry} UTF8 strings for number of seconds since the epoch


00:00:00 UTC on 1 January 1970.

{URL-encoded-resourceURI} Lower case URL-encoding of the lower case resource


URI

{policyName} The name of the shared access policy to which this


token refers. Absent if the token refers to device-
registry credentials.

Note on prefix: The URI prefix is computed by segment and not by character. For example /a/b is a
prefix for /a/b/c but not for /a/bc .
The following Node.js snippet shows a function called generateSasToken that computes the token
from the inputs resourceUri, signingKey, policyName, expiresInMins . The next sections detail how to
initialize the different inputs for the different token use cases.

var generateSasToken = function(resourceUri, signingKey, policyName, expiresInMins) {


resourceUri = encodeURIComponent(resourceUri);

// Set expiration in seconds


var expires = (Date.now() / 1000) + expiresInMins * 60;
expires = Math.ceil(expires);
var toSign = resourceUri + '\n' + expires;

// Use crypto
var hmac = crypto.createHmac('sha256', new Buffer(signingKey, 'base64'));
hmac.update(toSign);
var base64UriEncoded = encodeURIComponent(hmac.digest('base64'));

// Construct autorization string


var token = "SharedAccessSignature sr=" + resourceUri + "&sig="
+ base64UriEncoded + "&se=" + expires;
if (policyName) token += "&skn="+policyName;
return token;
};

As a comparison, the equivalent Python code to generate a security token is:


from base64 import b64encode, b64decode
from hashlib import sha256
from time import time
from urllib import quote_plus, urlencode
from hmac import HMAC

def generate_sas_token(uri, key, policy_name, expiry=3600):


ttl = time() + expiry
sign_key = "%s\n%d" % ((quote_plus(uri)), int(ttl))
print sign_key
signature = b64encode(HMAC(b64decode(key), sign_key, sha256).digest())

rawtoken = {
'sr' : uri,
'sig': signature,
'se' : str(int(ttl))
}

if policy_name is not None:


rawtoken['skn'] = policy_name

return 'SharedAccessSignature ' + urlencode(rawtoken)

The functionality in C# to generate a security token is:

using System;
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;

public static string generateSasToken(string resourceUri, string key, string policyName, int
expiryInSeconds = 3600)
{
TimeSpan fromEpochStart = DateTime.UtcNow - new DateTime(1970, 1, 1);
string expiry = Convert.ToString((int)fromEpochStart.TotalSeconds + expiryInSeconds);

string stringToSign = WebUtility.UrlEncode(resourceUri) + "\n" + expiry;

HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(key));


string signature =
Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));

string token = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig=


{1}&se={2}", WebUtility.UrlEncode(resourceUri), WebUtility.UrlEncode(signature), expiry);

if (!String.IsNullOrEmpty(policyName))
{
token += "&skn=" + policyName;
}

return token;
}

NOTE
Since the time validity of the token is validated on IoT Hub machines, the drift on the clock of the machine that
generates the token must be minimal.

Use SAS tokens in a device app


There are two ways to obtain DeviceConnect permissions with IoT Hub with security tokens: use a
symmetric device key from the identity registry, or use a shared access key.
Remember that all functionality accessible from devices is exposed by design on endpoints with prefix
/devices/{deviceId} .

IMPORTANT
The only way that IoT Hub authenticates a specific device is using the device identity symmetric key. In cases
when a shared access policy is used to access device functionality, the solution must consider the component
issuing the security token as a trusted subcomponent.

The device-facing endpoints are (irrespective of the protocol):

ENDPOINT FUNCTIONALITY

{iot hub host Send device-to-cloud messages.


name}/devices/{deviceId}/messages/events

{iot hub host Receive cloud-to-device messages.


name}/devices/{deviceId}/messages/devicebound

Use a symmetric key in the identity registry


When using a device identity's symmetric key to generate a token, the policyName ( skn ) element of
the token is omitted.
For example, a token created to access all device functionality should have the following parameters:
resource URI: {IoT hub name}.azure-devices.net/devices/{device id} ,
signing key: any symmetric key for the {device id} identity,
no policy name,
any expiration time.
An example using the preceding Node.js function would be:

var endpoint ="myhub.azure-devices.net/devices/device1";


var deviceKey ="...";

var token = generateSasToken(endpoint, deviceKey, null, 60);

The result, which grants access to all functionality for device1, would be:
SharedAccessSignature sr=myhub.azure-
devices.net%2fdevices%2fdevice1&sig=13y8ejUk2z7PLmvtwR5RqlGBOVwiq7rQR3WZ5xZX3N4%3D&se=1456971697

NOTE
It is possible to generate a SAS token using the .NET device explorer tool or the cross-platform, Python-based
The IoT extension for Azure CLI 2.0 command-line utility.

Use a shared access policy


When you create a token from a shared access policy, set the skn field to the name of the policy. This
policy must grant the DeviceConnect permission.
The two main scenarios for using shared access policies to access device functionality are:
cloud protocol gateways,
token services used to implement custom authentication schemes.
Since the shared access policy can potentially grant access to connect as any device, it is important to
use the correct resource URI when creating security tokens. This setting is especially important for
token services, which have to scope the token to a specific device using the resource URI. This point is
less relevant for protocol gateways as they are already mediating traffic for all devices.
As an example, a token service using the pre-created shared access policy called device would create a
token with the following parameters:
resource URI: {IoT hub name}.azure-devices.net/devices/{device id} ,
signing key: one of the keys of the device policy,
policy name: device ,
any expiration time.
An example using the preceding Node.js function would be:

var endpoint ="myhub.azure-devices.net/devices/device1";


var policyName = 'device';
var policyKey = '...';

var token = generateSasToken(endpoint, policyKey, policyName, 60);

The result, which grants access to all functionality for device1, would be:
SharedAccessSignature sr=myhub.azure-
devices.net%2fdevices%2fdevice1&sig=13y8ejUk2z7PLmvtwR5RqlGBOVwiq7rQR3WZ5xZX3N4%3D&se=1456971697&skn=device

A protocol gateway could use the same token for all devices simply setting the resource URI to
myhub.azure-devices.net/devices .

Use security tokens from service components


Service components can only generate security tokens using shared access policies granting the
appropriate permissions as explained previously.
Here is the service functions exposed on the endpoints:

ENDPOINT FUNCTIONALITY

{iot hub host name}/devices Create, update, retrieve, and delete device identities.

{iot hub host name}/messages/events Receive device-to-cloud messages.

{iot hub host name}/servicebound/feedback Receive feedback for cloud-to-device messages.

{iot hub host name}/devicebound Send cloud-to-device messages.

As an example, a service generating using the pre-created shared access policy called registryRead
would create a token with the following parameters:
resource URI: {IoT hub name}.azure-devices.net/devices ,
signing key: one of the keys of the registryRead policy,
policy name: registryRead ,
any expiration time.
var endpoint ="myhub.azure-devices.net/devices";
var policyName = 'device';
var policyKey = '...';

var token = generateSasToken(endpoint, policyKey, policyName, 60);

The result, which would grant access to read all device identities, would be:
SharedAccessSignature sr=myhub.azure-
devices.net%2fdevices&sig=JdyscqTpXdEJs49elIUCcohw2DlFDR3zfH5KqGJo4r4%3D&se=1456973447&skn=registryRead

Supported X.509 certificates


You can use any X.509 certificate to authenticate a device with IoT Hub by uploading either a
certificate thumbprint or a certificate authority (CA) to Azure IoT Hub. Authentication using certificate
thumbprints only verifies that the presented thumbprint matches the configured thumbprint.
Authentication using certificate authority validates the certificate chain.
Supported certificates include:
An existing X.509 certificate. A device may already have an X.509 certificate associated with it.
The device can use this certificate to authenticate with IoT Hub. Works with either thumbprint or
CA authentication.
CA -signed X.509 certificate. To identify a device and authenticate it with IoT Hub, you can use an
X.509 certificate generated and signed by a Certification Authority (CA). Works with either
thumbprint or CA authentication.
A self-generated and self-signed X-509 certificate. A device manufacturer or in-house deployer
can generate these certificates and store the corresponding private key (and certificate) on the
device. You can use tools such as OpenSSL and Windows SelfSignedCertificate utility for this
purpose. Only works with thumbprint authentication.
A device may either use an X.509 certificate or a security token for authentication, but not both.
For more information about authentication using certificate authority, see Conceptual understanding
of X.509 CA certificates.
Register an X.509 certificate for a device
The Azure IoT Service SDK for C# (version 1.0.8+) supports registering a device that uses an X.509
certificate for authentication. Other APIs such as import/export of devices also support X.509
certificates.
C# Support
The RegistryManager class provides a programmatic way to register a device. In particular, the
AddDeviceAsync and UpdateDeviceAsync methods enable you to register and update a device in
the IoT Hub identity registry. These two methods take a Device instance as input. The Device class
includes an Authentication property that allows you to specify primary and secondary X.509
certificate thumbprints. The thumbprint represents a SHA256 hash of the X.509 certificate (stored
using binary DER encoding). You have the option of specifying a primary thumbprint or a secondary
thumbprint or both. Primary and secondary thumbprints are supported to handle certificate rollover
scenarios.
Here is a sample C# code snippet to register a device using an X.509 certificate thumbprint:
var device = new Device(deviceId)
{
Authentication = new AuthenticationMechanism()
{
X509Thumbprint = new X509Thumbprint()
{
PrimaryThumbprint = "B4172AB44C28F3B9E117648C6F7294978A00CDCBA34A46A1B8588B3F7D82C4F1"
}
}
};
RegistryManager registryManager =
RegistryManager.CreateFromConnectionString(deviceGatewayConnectionString);
await registryManager.AddDeviceAsync(device);

Use an X.509 certificate during run-time operations


The Azure IoT device SDK for .NET (version 1.0.11+) supports the use of X.509 certificates.
C# Support
The class DeviceAuthenticationWithX509Certificate supports the creation of DeviceClient
instances using an X.509 certificate. The X.509 certificate must be in the PFX (also called PKCS #12)
format that includes the private key.
Here is a sample code snippet:

var authMethod = new DeviceAuthenticationWithX509Certificate("<device id>", x509Certificate);

var deviceClient = DeviceClient.Create("<IotHub DNS HostName>", authMethod);

Custom device and module authentication


You can use the IoT Hub identity registry to configure per-device/module security credentials and
access control using tokens. If an IoT solution already has a custom identity registry and/or
authentication scheme, consider creating a token service to integrate this infrastructure with IoT Hub.
In this way, you can use other IoT features in your solution.
A token service is a custom cloud service. It uses an IoT Hub shared access policy with
DeviceConnect or ModuleConnect permissions to create device-scoped or module-scoped tokens.
These tokens enable a device and module to connect to your IoT hub.
Here are the main steps of the token service pattern:
1. Create an IoT Hub shared access policy with DeviceConnect or ModuleConnect permissions for
your IoT hub. You can create this policy in the Azure portal or programmatically. The token service
uses this policy to sign the tokens it creates.
2. When a device/module needs to access your IoT hub, it requests a signed token from your token
service. The device can authenticate with your custom identity registry/authentication scheme to
determine the device/module identity that the token service uses to create the token.
3. The token service returns a token. The token is created by using /devices/{deviceId} or
/devices/{deviceId}/module/{moduleId} as resourceURI , with deviceId as the device being
authenticated or moduleId as the module being authenticated. The token service uses the shared
access policy to construct the token.
4. The device/module uses the token directly with the IoT hub.

NOTE
You can use the .NET class SharedAccessSignatureBuilder or the Java class IotHubServiceSasToken to create a
token in your token service.

The token service can set the token expiration as desired. When the token expires, the IoT hub severs
the device/module connection. Then, the device/module must request a new token from the token
service. A short expiry time increases the load on both the device/module and the token service.
For a device/module to connect to your hub, you must still add it to the IoT Hub identity registry —
even though the it is using a token and not a key to connect. Therefore, you can continue to use per-
device/per-module access control by enabling or disabling device/module identities in the identity
registry. This approach mitigates the risks of using tokens with long expiry times.
Comparison with a custom gateway
The token service pattern is the recommended way to implement a custom identity
registry/authentication scheme with IoT Hub. This pattern is recommended because IoT Hub
continues to handle most of the solution traffic. However, if the custom authentication scheme is so
intertwined with the protocol, you may require a custom gateway to process all the traffic. An example
of such a scenario is usingTransport Layer Security (TLS ) and pre-shared keys (PSKs). For more
information, see the protocol gateway article.

Reference topics:
The following reference topics provide you with more information about controlling access to your IoT
hub.

IoT Hub permissions


The following table lists the permissions you can use to control access to your IoT hub.

PERMISSION NOTES

RegistryRead Grants read access to the identity registry. For more


information, see Identity registry.
This permission is used by back-end cloud services.

RegistryReadWrite Grants read and write access to the identity registry.


For more information, see Identity registry.
This permission is used by back-end cloud services.

ServiceConnect Grants access to cloud service-facing communication


and monitoring endpoints.
Grants permission to receive device-to-cloud messages,
send cloud-to-device messages, and retrieve the
corresponding delivery acknowledgments.
Grants permission to retrieve delivery
acknowledgements for file uploads.
Grants permission to access twins to update tags and
desired properties, retrieve reported properties, and
run queries.
This permission is used by back-end cloud services.

DeviceConnect Grants access to device-facing endpoints.


Grants permission to send device-to-cloud messages
and receive cloud-to-device messages.
Grants permission to perform file upload from a device.
Grants permission to receive device twin desired
property notifications and update device twin reported
properties.
Grants permission to perform file uploads.
This permission is used by devices.

Additional reference material


Other reference topics in the IoT Hub developer guide include:
IoT Hub endpoints describes the various endpoints that each IoT hub exposes for run-time and
management operations.
Throttling and quotas describes the quotas and throttling behaviors that apply to the IoT Hub
service.
Azure IoT device and service SDKs lists the various language SDKs you can use when you develop
both device and service apps that interact with IoT Hub.
IoT Hub query language describes the query language you can use to retrieve information from IoT
Hub about your device twins and jobs.
IoT Hub MQTT support provides more information about IoT Hub support for the MQTT protocol.

Next steps
Now that you have learned how to control access IoT Hub, you may be interested in the following IoT
Hub developer guide topics:
Use device twins to synchronize state and configurations
Invoke a direct method on a device
Schedule jobs on multiple devices
If you would like to try out some of the concepts described in this article, see the following IoT Hub
tutorials:
Get started with Azure IoT Hub
How to send cloud-to-device messages with IoT Hub
How to process IoT Hub device-to-cloud messages
Understand and use device twins in IoT Hub
5/29/2018 • 11 min to read • Edit Online

Device twins are JSON documents that store device state information including metadata,
configurations, and conditions. Azure IoT Hub maintains a device twin for each device that you
connect to IoT Hub.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more
information about the basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This article describes:


The structure of the device twin: tags, desired and reported properties.
The operations that device apps and back ends can perform on device twins.
Use device twins to:
Store device-specific metadata in the cloud. For example, the deployment location of a vending
machine.
Report current state information such as available capabilities and conditions from your device
app. For example, a device is connected to your IoT hub over cellular or WiFi.
Synchronize the state of long-running workflows between device app and back-end app. For
example, when the solution back end specifies the new firmware version to install, and the
device app reports the various stages of the update process.
Query your device metadata, configuration, or state.
Refer to Device-to-cloud communication guidance for guidance on using reported properties,
device-to-cloud messages, or file upload. Refer to Cloud-to-device communication guidance for
guidance on using desired properties, direct methods, or cloud-to-device messages.

Device twins
Device twins store device-related information that:
Device and back ends can use to synchronize device conditions and configuration.
The solution back end can use to query and target long-running operations.
The lifecycle of a device twin is linked to the corresponding device identity. Device twins are
implicitly created and deleted when a device identity is created or deleted in IoT Hub.
A device twin is a JSON document that includes:
Tags. A section of the JSON document that the solution back end can read from and write to.
Tags are not visible to device apps.
Desired properties. Used along with reported properties to synchronize device configuration
or conditions. The solution back end can set desired properties, and the device app can read
them. The device app can also receive notifications of changes in the desired properties.
Reported properties. Used along with desired properties to synchronize device configuration
or conditions. The device app can set reported properties, and the solution back end can read
and query them.
Device identity properties. The root of the device twin JSON document contains the read-
only properties from the corresponding device identity stored in the identity registry.

The following example shows a device twin JSON document:


{
"deviceId": "devA",
"etag": "AAAAAAAAAAc=",
"status": "enabled",
"statusReason": "provisioned",
"statusUpdateTime": "0001-01-01T00:00:00",
"connectionState": "connected",
"lastActivityTime": "2015-02-30T16:24:48.789Z",
"cloudToDeviceMessageCount": 0,
"authenticationType": "sas",
"x509Thumbprint": {
"primaryThumbprint": null,
"secondaryThumbprint": null
},
"version": 2,
"tags": {
"$etag": "123",
"deploymentLocation": {
"building": "43",
"floor": "1"
}
},
"properties": {
"desired": {
"telemetryConfig": {
"sendFrequency": "5m"
},
"$metadata" : {...},
"$version": 1
},
"reported": {
"telemetryConfig": {
"sendFrequency": "5m",
"status": "success"
}
"batteryLevel": 55,
"$metadata" : {...},
"$version": 4
}
}
}

In the root object are the device identity properties, and container objects for tags and both
reported and desired properties. The properties container contains some read-only elements (
$metadata , $etag , and $version ) described in the Device twin metadata and Optimistic
concurrency sections.
Reported property example
In the previous example, the device twin contains a batteryLevel property that is reported by the
device app. This property makes it possible to query and operate on devices based on the last
reported battery level. Other examples include the device app reporting device capabilities or
connectivity options.

NOTE
Reported properties simplify scenarios where the solution back end is interested in the last known value
of a property. Use device-to-cloud messages if the solution back end needs to process device telemetry in
the form of sequences of timestamped events, such as time series.

Desired property example


In the previous example, the telemetryConfig device twin desired and reported properties are
used by the solution back end and the device app to synchronize the telemetry configuration for
this device. For example:
1. The solution back end sets the desired property with the desired configuration value. Here
is the portion of the document with the desired property set:

...
"desired": {
"telemetryConfig": {
"sendFrequency": "5m"
},
...
},
...

2. The device app is notified of the change immediately if connected, or at the first reconnect.
The device app then reports the updated configuration (or an error condition using the
status property). Here is the portion of the reported properties:

...
"reported": {
"telemetryConfig": {
"sendFrequency": "5m",
"status": "success"
}
...
}
...

3. The solution back end can track the results of the configuration operation across many
devices, by querying device twins.

NOTE
The preceding snippets are examples, optimized for readability, of one way to encode a device
configuration and its status. IoT Hub does not impose a specific schema for the device twin desired and
reported properties in the device twins.

You can use twins to synchronize long-running operations such as firmware updates. For more
information on how to use properties to synchronize and track a long running operation across
devices, see Use desired properties to configure devices.

Back-end operations
The solution back end operates on the device twin using the following atomic operations, exposed
through HTTPS:
Retrieve device twin by ID. This operation returns the device twin document, including tags
and desired and reported system properties.
Partially update device twin. This operation enables the solution back end to partially
update the tags or desired properties in a device twin. The partial update is expressed as a
JSON document that adds or updates any property. Properties set to null are removed.
The following example creates a new desired property with value
{"newProperty": "newValue"} , overwrites the existing value of existingProperty with
"otherNewValue" , and removes otherOldProperty . No other changes are made to existing
desired properties or tags:

{
"properties": {
"desired": {
"newProperty": {
"nestedProperty": "newValue"
},
"existingProperty": "otherNewValue",
"otherOldProperty": null
}
}
}

Replace desired properties. This operation enables the solution back end to completely
overwrite all existing desired properties and substitute a new JSON document for
properties/desired .

Replace tags. This operation enables the solution back end to completely overwrite all
existing tags and substitute a new JSON document for tags .
Receive twin notifications. This operation allows the solution back end to be notified
when the twin is modified. To do so, your IoT solution needs to create a route and to set the
Data Source equal to twinChangeEvents. By default, no twin notifications are sent, that is,
no such routes pre-exist. If the rate of change is too high, or for other reasons such as
internal failures, the IoT Hub might send only one notification that contains all changes.
Therefore, if your application needs reliable auditing and logging of all intermediate states,
you should use device-to-cloud messages. The twin notification message includes
properties and body.
Properties

NAME VALUE

$content-type application/json

$iothub-enqueuedtime Time when the notification was sent

$iothub-message-source twinChangeEvents

$content-encoding utf-8

deviceId ID of the device

hubName Name of IoT Hub

operationTimestamp ISO8601 timestamp of operation

iothub-message-schema deviceLifecycleNotification

opType "replaceTwin" or "updateTwin"

Message system properties are prefixed with the '$' symbol.


Body
This section includes all the twin changes in a JSON format. It uses the same format
as a patch, with the difference that it can contain all twin sections: tags,
properties.reported, properties.desired, and that it contains the “$metadata”
elements. For example,

{
"properties": {
"desired": {
"$metadata": {
"$lastUpdated": "2016-02-30T16:24:48.789Z"
},
"$version": 1
},
"reported": {
"$metadata": {
"$lastUpdated": "2016-02-30T16:24:48.789Z"
},
"$version": 1
}
}
}

All the preceding operations support Optimistic concurrency and require the ServiceConnect
permission, as defined in the Security article.
In addition to these operations, the solution back end can:
Query the device twins using the SQL -like IoT Hub query language.
Perform operations on large sets of device twins using jobs.

Device operations
The device app operates on the device twin using the following atomic operations:
Retrieve device twin. This operation returns the device twin document (including tags and
desired and reported system properties) for the currently connected device.
Partially update reported properties. This operation enables the partial update of the
reported properties of the currently connected device. This operation uses the same JSON
update format that the solution back end uses for a partial update of desired properties.
Observe desired properties. The currently connected device can choose to be notified of
updates to the desired properties when they happen. The device receives the same form of
update (partial or full replacement) executed by the solution back end.
All the preceding operations require the DeviceConnect permission, as defined in the Security
article.
The Azure IoT device SDKs make it easy to use the preceding operations from many languages
and platforms. For more information on the details of IoT Hub primitives for desired properties
synchronization, see Device reconnection flow.

Tags and properties format


Tags, desired properties, and reported properties are JSON objects with the following restrictions:
All keys in JSON objects are case-sensitive 64 bytes UTF -8 UNICODE strings. Allowed
characters exclude UNICODE control characters (segments C0 and C1), and '.' , ' ' , and
'$' .
All values in JSON objects can be of the following JSON types: boolean, number, string, object.
Arrays are not allowed. The maximum value for integers is 4503599627370495 and the
minimum value for integers is -4503599627370496.
All JSON objects in tags, desired, and reported properties can have a maximum depth of 5.
For instance, the following object is valid:

{
...
"tags": {
"one": {
"two": {
"three": {
"four": {
"five": {
"property": "value"
}
}
}
}
}
},
...
}

All string values can be at most 4 KB in length.

Device twin size


IoT Hub enforces an 8KB size limitation on each of the respective total values of tags ,
properties/desired , and properties/reported , excluding read-only elements. The size is
computed by counting all characters, excluding UNICODE control characters (segments C0 and
C1) and spaces that are outside of string constants. IoT Hub rejects with an error all operations
that would increase the size of those documents above the limit.

Device twin metadata


IoT Hub maintains the timestamp of the last update for each JSON object in device twin desired
and reported properties. The timestamps are in UTC and encoded in the ISO8601 format
YYYY-MM-DDTHH:MM:SS.mmmZ . For example:
{
...
"properties": {
"desired": {
"telemetryConfig": {
"sendFrequency": "5m"
},
"$metadata": {
"telemetryConfig": {
"sendFrequency": {
"$lastUpdated": "2016-03-30T16:24:48.789Z"
},
"$lastUpdated": "2016-03-30T16:24:48.789Z"
},
"$lastUpdated": "2016-03-30T16:24:48.789Z"
},
"$version": 23
},
"reported": {
"telemetryConfig": {
"sendFrequency": "5m",
"status": "success"
}
"batteryLevel": "55%",
"$metadata": {
"telemetryConfig": {
"sendFrequency": "5m",
"status": {
"$lastUpdated": "2016-03-31T16:35:48.789Z"
},
"$lastUpdated": "2016-03-31T16:35:48.789Z"
}
"batteryLevel": {
"$lastUpdated": "2016-04-01T16:35:48.789Z"
},
"$lastUpdated": "2016-04-01T16:24:48.789Z"
},
"$version": 123
}
}
...
}

This information is kept at every level (not just the leaves of the JSON structure) to preserve
updates that remove object keys.

Optimistic concurrency
Tags, desired, and reported properties all support optimistic concurrency. Tags have an ETag, as
per RFC7232, that represents the tag's JSON representation. You can use ETags in conditional
update operations from the solution back end to ensure consistency.
Device twin desired and reported properties do not have ETags, but have a $version value that is
guaranteed to be incremental. Similarly to an ETag, the version can be used by the updating party
to enforce consistency of updates. For example, a device app for a reported property or the
solution back end for a desired property.
Versions are also useful when an observing agent (such as the device app observing the desired
properties) must reconcile races between the result of a retrieve operation and an update
notification. The section Device reconnection flow provides more information.
Device reconnection flow
IoT Hub does not preserve desired properties update notifications for disconnected devices. It
follows that a device that is connecting must retrieve the full desired properties document, in
addition to subscribing for update notifications. Given the possibility of races between update
notifications and full retrieval, the following flow must be ensured:
1. Device app connects to an IoT hub.
2. Device app subscribes for desired properties update notifications.
3. Device app retrieves the full document for desired properties.
The device app can ignore all notifications with $version less or equal than the version of the full
retrieved document. This approach is possible because IoT Hub guarantees that versions always
increment.

NOTE
This logic is already implemented in the Azure IoT device SDKs. This description is useful only if the device
app cannot use any of Azure IoT device SDKs and must program the MQTT interface directly.

Additional reference material


Other reference topics in the IoT Hub developer guide include:
The IoT Hub endpoints article describes the various endpoints that each IoT hub exposes for
run-time and management operations.
The Throttling and quotas article describes the quotas that apply to the IoT Hub service and
the throttling behavior to expect when you use the service.
The Azure IoT device and service SDKs article lists the various language SDKs you can use
when you develop both device and service apps that interact with IoT Hub.
The IoT Hub query language for device twins, jobs, and message routing article describes the
IoT Hub query language you can use to retrieve information from IoT Hub about your device
twins and jobs.
The IoT Hub MQTT support article provides more information about IoT Hub support for the
MQTT protocol.

Next steps
Now you have learned about device twins, you may be interested in the following IoT Hub
developer guide topics:
Understand and use module twins in IoT Hub
Invoke a direct method on a device
Schedule jobs on multiple devices
To try out some of the concepts described in this article, see the following IoT Hub tutorials:
How to use the device twin
How to use device twin properties
Understand and use module twins in IoT Hub
5/29/2018 • 10 min to read • Edit Online

This article assumes you've read understand and use device twins in IoT Hub first. In IoT Hub, under each device
identity, you can create up to 20 module identities. Each module identity implicitly generates a module twin. Very
similar to device twins, module twins are JSON documents that store module state information including
metadata, configurations, and conditions. Azure IoT Hub maintains a module twin for each module that you
connect to IoT Hub.
On the device side, the IoT Hub device SDKs enable you to create modules which each opens an independent
connection to IoT Hub. This enables you to use separate namespaces for different components on your device. For
example, you have a vending machine that has three different sensors. Each sensor is controlled by different
departments in your company. You can create a module for each sensor. This way, each department is only able to
send jobs or direct methods to the sensor that they control, avoiding conflicts and user errors.
Module identity and module twin provides the same capabilities as device identity and device twin but at a finer
granularity. This finer granularity enables capable devices, such as operating system based devices or firmware
devices managing multiple components, to isolate configuration and conditions for each of those components.
Module identity and module twins provide a management separation of concerns when working with IoT devices
that have modular software components. We aim at supporting all the device twin functionality at module twin
level by module twin general availability.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This article describes:


The structure of the module twin: tags, desired and reported properties.
The operations that the modules and back ends can perform on module twins.
Refer to Device-to-cloud communication guidance for guidance on using reported properties, device-to-cloud
messages, or file upload. Refer to Cloud-to-device communication guidance for guidance on using desired
properties, direct methods, or cloud-to-device messages.

Module twins
Module twins store module-related information that:
Modules on the device and IoT Hub can use to synchronize module conditions and configuration.
The solution back end can use to query and target long-running operations.
The lifecycle of a module twin is linked to the corresponding module identity. Modules twins are implicitly created
and deleted when a module identity is created or deleted in IoT Hub.
A module twin is a JSON document that includes:
Tags. A section of the JSON document that the solution back end can read from and write to. Tags are not
visible to modules on the device. Tags are set for querying purpose.
Desired properties. Used along with reported properties to synchronize module configuration or conditions.
The solution back end can set desired properties, and the module app can read them. The module app can also
receive notifications of changes in the desired properties.
Reported properties. Used along with desired properties to synchronize module configuration or conditions.
The module app can set reported properties, and the solution back end can read and query them.
Module identity properties. The root of the module twin JSON document contains the read-only properties
from the corresponding module identity stored in the identity registry.

The following example shows a module twin JSON document:


{
"deviceId": "devA",
"moduleId": "moduleA",
"etag": "AAAAAAAAAAc=",
"status": "enabled",
"statusReason": "provisioned",
"statusUpdateTime": "0001-01-01T00:00:00",
"connectionState": "connected",
"lastActivityTime": "2015-02-30T16:24:48.789Z",
"cloudToDeviceMessageCount": 0,
"authenticationType": "sas",
"x509Thumbprint": {
"primaryThumbprint": null,
"secondaryThumbprint": null
},
"version": 2,
"tags": {
"$etag": "123",
"deploymentLocation": {
"building": "43",
"floor": "1"
}
},
"properties": {
"desired": {
"telemetryConfig": {
"sendFrequency": "5m"
},
"$metadata" : {...},
"$version": 1
},
"reported": {
"telemetryConfig": {
"sendFrequency": "5m",
"status": "success"
}
"batteryLevel": 55,
"$metadata" : {...},
"$version": 4
}
}
}

In the root object are the module identity properties, and container objects for tags and both reported and
desired properties. The properties container contains some read-only elements ( $metadata , $etag , and
$version ) described in the Module twin metadata and Optimistic concurrency sections.

Reported property example


In the previous example, the module twin contains a batteryLevel property that is reported by the module app.
This property makes it possible to query and operate on modules based on the last reported battery level. Other
examples include the module app reporting module capabilities or connectivity options.

NOTE
Reported properties simplify scenarios where the solution back end is interested in the last known value of a property. Use
device-to-cloud messages if the solution back end needs to process module telemetry in the form of sequences of
timestamped events, such as time series.

Desired property example


In the previous example, the telemetryConfig module twin desired and reported properties are used by the
solution back end and the module app to synchronize the telemetry configuration for this module. For example:
1. The solution back end sets the desired property with the desired configuration value. Here is the portion of
the document with the desired property set:

...
"desired": {
"telemetryConfig": {
"sendFrequency": "5m"
},
...
},
...

2. The module app is notified of the change immediately if connected, or at the first reconnect. The module
app then reports the updated configuration (or an error condition using the status property). Here is the
portion of the reported properties:

...
"reported": {
"telemetryConfig": {
"sendFrequency": "5m",
"status": "success"
}
...
}
...

3. The solution back end can track the results of the configuration operation across many modules, by
querying module twins.

NOTE
The preceding snippets are examples, optimized for readability, of one way to encode a module configuration and its status.
IoT Hub does not impose a specific schema for the module twin desired and reported properties in the module twins.

Back-end operations
The solution back end operates on the module twin using the following atomic operations, exposed through
HTTPS:
Retrieve module twin by ID. This operation returns the module twin document, including tags and desired
and reported system properties.
Partially update module twin. This operation enables the solution back end to partially update the tags
or desired properties in a module twin. The partial update is expressed as a JSON document that adds or
updates any property. Properties set to null are removed. The following example creates a new desired
property with value {"newProperty": "newValue"} , overwrites the existing value of existingProperty with
"otherNewValue" , and removes otherOldProperty . No other changes are made to existing desired
properties or tags:
{
"properties": {
"desired": {
"newProperty": {
"nestedProperty": "newValue"
},
"existingProperty": "otherNewValue",
"otherOldProperty": null
}
}
}

Replace desired properties. This operation enables the solution back end to completely overwrite all
existing desired properties and substitute a new JSON document for properties/desired .
Replace tags. This operation enables the solution back end to completely overwrite all existing tags and
substitute a new JSON document for tags .
Receive twin notifications. This operation allows the solution back end to be notified when the twin is
modified. To do so, your IoT solution needs to create a route and to set the Data Source equal to
twinChangeEvents. By default, no twin notifications are sent, that is, no such routes pre-exist. If the rate of
change is too high, or for other reasons such as internal failures, the IoT Hub might send only one
notification that contains all changes. Therefore, if your application needs reliable auditing and logging of
all intermediate states, you should use device-to-cloud messages. The twin notification message includes
properties and body.
Properties

NAME VALUE

$content-type application/json

$iothub-enqueuedtime Time when the notification was sent

$iothub-message-source twinChangeEvents

$content-encoding utf-8

deviceId ID of the device

moduleId ID of the module

hubName Name of IoT Hub

operationTimestamp ISO8601 timestamp of operation

iothub-message-schema deviceLifecycleNotification

opType "replaceTwin" or "updateTwin"

Message system properties are prefixed with the '$' symbol.


Body
This section includes all the twin changes in a JSON format. It uses the same format as a patch, with
the difference that it can contain all twin sections: tags, properties.reported, properties.desired, and
that it contains the “$metadata” elements. For example,
{
"properties": {
"desired": {
"$metadata": {
"$lastUpdated": "2016-02-30T16:24:48.789Z"
},
"$version": 1
},
"reported": {
"$metadata": {
"$lastUpdated": "2016-02-30T16:24:48.789Z"
},
"$version": 1
}
}
}

All the preceding operations support Optimistic concurrency and require the ServiceConnect permission, as
defined in the Security article.
In addition to these operations, the solution back end can:
Query the module twins using the SQL -like IoT Hub query language.

Module operations
The module app operates on the module twin using the following atomic operations:
Retrieve module twin. This operation returns the module twin document (including tags and desired and
reported system properties) for the currently connected module.
Partially update reported properties. This operation enables the partial update of the reported properties of
the currently connected module. This operation uses the same JSON update format that the solution back end
uses for a partial update of desired properties.
Observe desired properties. The currently connected module can choose to be notified of updates to the
desired properties when they happen. The module receives the same form of update (partial or full
replacement) executed by the solution back end.
All the preceding operations require the ModuleConnect permission, as defined in the Security article.
The Azure IoT device SDKs make it easy to use the preceding operations from many languages and platforms.

Tags and properties format


Tags, desired properties, and reported properties are JSON objects with the following restrictions:
All keys in JSON objects are case-sensitive 64 bytes UTF -8 UNICODE strings. Allowed characters exclude
UNICODE control characters (segments C0 and C1), and '.' , ' ' , and '$' .
All values in JSON objects can be of the following JSON types: boolean, number, string, object. Arrays are not
allowed. The maximum value for integers is 4503599627370495 and the minimum value for integers is -
4503599627370496.
All JSON objects in tags, desired, and reported properties can have a maximum depth of 5. For instance,
the following object is valid:
{
...
"tags": {
"one": {
"two": {
"three": {
"four": {
"five": {
"property": "value"
}
}
}
}
}
},
...
}

All string values can be at most 4 KB in length.

Module twin size


IoT Hub enforces an 8KB size limitation on each of the respective total values of tags , properties/desired , and
properties/reported , excluding read-only elements. The size is computed by counting all characters, excluding
UNICODE control characters (segments C0 and C1) and spaces that are outside of string constants. IoT Hub
rejects with an error all operations that would increase the size of those documents above the limit.

Module twin metadata


IoT Hub maintains the timestamp of the last update for each JSON object in module twin desired and reported
properties. The timestamps are in UTC and encoded in the ISO8601 format YYYY-MM-DDTHH:MM:SS.mmmZ . For
example:
{
...
"properties": {
"desired": {
"telemetryConfig": {
"sendFrequency": "5m"
},
"$metadata": {
"telemetryConfig": {
"sendFrequency": {
"$lastUpdated": "2016-03-30T16:24:48.789Z"
},
"$lastUpdated": "2016-03-30T16:24:48.789Z"
},
"$lastUpdated": "2016-03-30T16:24:48.789Z"
},
"$version": 23
},
"reported": {
"telemetryConfig": {
"sendFrequency": "5m",
"status": "success"
}
"batteryLevel": "55%",
"$metadata": {
"telemetryConfig": {
"sendFrequency": "5m",
"status": {
"$lastUpdated": "2016-03-31T16:35:48.789Z"
},
"$lastUpdated": "2016-03-31T16:35:48.789Z"
}
"batteryLevel": {
"$lastUpdated": "2016-04-01T16:35:48.789Z"
},
"$lastUpdated": "2016-04-01T16:24:48.789Z"
},
"$version": 123
}
}
...
}

This information is kept at every level (not just the leaves of the JSON structure) to preserve updates that remove
object keys.

Optimistic concurrency
Tags, desired, and reported properties all support optimistic concurrency. Tags have an ETag, as per RFC7232, that
represents the tag's JSON representation. You can use ETags in conditional update operations from the solution
back end to ensure consistency.
Module twin desired and reported properties do not have ETags, but have a $version value that is guaranteed to
be incremental. Similarly to an ETag, the version can be used by the updating party to enforce consistency of
updates. For example, a module app for a reported property or the solution back end for a desired property.
Versions are also useful when an observing agent (such as the module app observing the desired properties)
must reconcile races between the result of a retrieve operation and an update notification. The section [Device
reconnection flow ][lnk-reconnection] provides more information.

Next steps
To try out some of the concepts described in this article, see the following IoT Hub tutorials:
Get started with IoT Hub module identity and module twin using .NET backup and .NET device
Understand and invoke direct methods from IoT
Hub
6/4/2018 • 5 min to read • Edit Online

IoT Hub gives you the ability to invoke direct methods on devices from the cloud. Direct methods
represent a request-reply interaction with a device similar to an HTTP call in that they succeed or fail
immediately (after a user-specified timeout). This approach is useful for scenarios where the course of
immediate action is different depending on whether the device was able to respond.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information
about the basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Each device method targets a single device. Jobs provide a way to invoke direct methods on multiple
devices, and schedule method invocation for disconnected devices.
Anyone with service connect permissions on IoT Hub may invoke a method on a device.
Direct methods follow a request-response pattern and are meant for communications that require
immediate confirmation of their result. For example, interactive control of the device, such as turning on
a fan.
Refer to Cloud-to-device communication guidance if in doubt between using desired properties, direct
methods, or cloud-to-device messages.

Method lifecycle
Direct methods are implemented on the device and may require zero or more inputs in the method
payload to correctly instantiate. You invoke a direct method through a service-facing URI (
{iot hub}/twins/{device id}/methods/ ). A device receives direct methods through a device-specific
MQTT topic ( $iothub/methods/POST/{method name}/ ) or through AMQP links ( IoThub-methodname and
IoThub-status application properties).

NOTE
When you invoke a direct method on a device, property names and values can only contain US-ASCII printable
alphanumeric, except any in the following set:
{'$', '(', ')', '<', '>', '@', ',', ';', ':', '\', '"', '/', '[', ']', '?', '=', '{', '}', SP,
HT}
.

Direct methods are synchronous and either succeed or fail after the timeout period (default: 30 seconds,
settable up to 3600 seconds). Direct methods are useful in interactive scenarios where you want a device
to act if and only if the device is online and receiving commands. For example, turning on a light from a
phone. In these scenarios, you want to see an immediate success or failure so the cloud service can act
on the result as soon as possible. The device may return some message body as a result of the method,
but it isn't required for the method to do so. There is no guarantee on ordering or any concurrency
semantics on method calls.
Direct methods are HTTPS -only from the cloud side, and MQTT or AMQP from the device side.
The payload for method requests and responses is a JSON document up to 128 KB.

Invoke a direct method from a back-end app


Method invocation
Direct method invocations on a device are HTTPS calls that comprise:
The URI specific to the device ( {iot hub}/twins/{device id}/methods/ )
The POST method
Headers that contain the authorization, request ID, content type, and content encoding
A transparent JSON body in the following format:

{
"methodName": "reboot",
"responseTimeoutInSeconds": 200,
"payload": {
"input1": "someInput",
"input2": "anotherInput"
}
}

Timeout is in seconds. If timeout is not set, it defaults to 30 seconds.


Response
The back-end app receives a response that comprises:
HTTP status code, which is used for errors coming from the IoT Hub, including a 404 error for
devices not currently connected
Headers that contain the ETag, request ID, content type, and content encoding
A JSON body in the following format:

{
"status" : 201,
"payload" : {...}
}

Both status and body are provided by the device and used to respond with the device's own
status code and/or description.
Method invocation for IoT Edge modules
Invoking direct methods using a module ID is supported in the C# preview SDK (available here).
For this purpose, use the ServiceClient.InvokeDeviceMethodAsync() method and pass in the deviceId
and moduleId as parameters.

Handle a direct method on a device


MQTT
Method invocation
Devices receive direct method requests on the MQTT topic:
$iothub/methods/POST/{method name}/?$rid={request id}

The body that the device receives is in the following format:


{
"input1": "someInput",
"input2": "anotherInput"
}

Method requests are QoS 0.


Response
The device sends responses to $iothub/methods/res/{status}/?$rid={request id} , where:
The status property is the device-supplied status of method execution.
The $rid property is the request ID from the method invocation received from IoT Hub.

The body is set by the device and can be any status.


AMQP
Method invocation
The device receives direct method requests by creating a receive link on address
amqps://{hostname}:5671/devices/{deviceId}/methods/deviceBound

The AMQP message arrives on the receive link that represents the method request. It contains the
following:
The correlation ID property, which contains a request ID that should be passed back with the
corresponding method response
An application property named IoThub-methodname , which contains the name of the method being
invoked
The AMQP message body containing the method payload as JSON
Response
The device creates a sending link to return the method response on address
amqps://{hostname}:5671/devices/{deviceId}/methods/deviceBound

The method’s response is returned on the sending link and is structured as follows:
The correlation ID property, which contains the request ID passed in the method’s request message
An application property named IoThub-status , which contains the user supplied method status
The AMQP message body containing the method response as JSON

Additional reference material


Other reference topics in the IoT Hub developer guide include:
IoT Hub endpoints describes the various endpoints that each IoT hub exposes for run-time and
management operations.
Throttling and quotas describes the quotas that apply and the throttling behavior to expect when you
use IoT Hub.
Azure IoT device and service SDKs lists the various language SDKs you can use when you develop
both device and service apps that interact with IoT Hub.
IoT Hub query language for device twins, jobs, and message routing describes the IoT Hub query
language you can use to retrieve information from IoT Hub about your device twins and jobs.
IoT Hub MQTT support provides more information about IoT Hub support for the MQTT protocol.

Next steps
Now you have learned how to use direct methods, you may be interested in the following IoT Hub
developer guide article:
Schedule jobs on multiple devices
If you would like to try out some of the concepts described in this article, you may be interested in the
following IoT Hub tutorial:
Use direct methods
Schedule jobs on multiple devices
5/29/2018 • 4 min to read • Edit Online

Azure IoT Hub enables a number of building blocks like device twin properties and tags and direct methods.
Typically, back-end apps enable device administrators and operators to update and interact with IoT devices
in bulk and at a scheduled time. Jobs execute device twin updates and direct methods against a set of
devices at a scheduled time. For example, an operator would use a back-end app that initiates and tracks a
job to reboot a set of devices in building 43 and floor 3 at a time that would not be disruptive to the
operations of the building.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about
the basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Consider using jobs when you need to schedule and track progress any of the following activities on a set of
devices:
Update desired properties
Update tags
Invoke direct methods

Job lifecycle
Jobs are initiated by the solution back end and maintained by IoT Hub. You can initiate a job through a
service-facing URI ( {iot hub}/jobs/v2/{device id}/methods/<jobID>?api-version=2016-11-14 ) and query for
progress on an executing job through a service-facing URI (
{iot hub}/jobs/v2/<jobId>?api-version=2016-11-14 ). To refresh the status of running jobs once a job is
initiated, run a job query.

NOTE
When you initiate a job, property names and values can only contain US-ASCII printable alphanumeric, except any in
the following set: $ ( ) < > @ , ; : \ " / [ ] ? = { } SP HT .

Jobs to execute direct methods


The following snippet shows the HTTPS 1.1 request details for executing a direct method on a set of devices
using a job:
PUT /jobs/v2/<jobId>?api-version=2016-11-14

Authorization: <config.sharedAccessSignature>
Content-Type: application/json; charset=utf-8
Request-Id: <guid>
User-Agent: <sdk-name>/<sdk-version>

{
jobId: '<jobId>',
type: 'scheduleDirectRequest',
cloudToDeviceMethod: {
methodName: '<methodName>',
payload: <payload>,
responseTimeoutInSeconds: methodTimeoutInSeconds
},
queryCondition: '<queryOrDevices>', // query condition
startTime: <jobStartTime>, // as an ISO-8601 date string
maxExecutionTimeInSeconds: <maxExecutionTimeInSeconds>
}

The query condition can also be on a single device ID or on a list of device IDs as shown in the following
examples:

queryCondition = "deviceId = 'MyDevice1'"


queryCondition = "deviceId IN ['MyDevice1','MyDevice2']"
queryCondition = "deviceId IN ['MyDevice1']

IoT Hub Query Language covers IoT Hub query language in additional detail.

Jobs to update device twin properties


The following snippet shows the HTTPS 1.1 request details for updating device twin properties using a job:

PUT /jobs/v2/<jobId>?api-version=2016-11-14
Authorization: <config.sharedAccessSignature>
Content-Type: application/json; charset=utf-8
Request-Id: <guid>
User-Agent: <sdk-name>/<sdk-version>

{
jobId: '<jobId>',
type: 'scheduleTwinUpdate',
updateTwin: <patch> // Valid JSON object
queryCondition: '<queryOrDevices>', // query condition
startTime: <jobStartTime>, // as an ISO-8601 date string
maxExecutionTimeInSeconds: <maxExecutionTimeInSeconds> // format TBD
}

Querying for progress on jobs


The following snippet shows the HTTPS 1.1 request details for querying for jobs:

GET /jobs/v2/query?api-version=2016-11-14[&jobType=<jobType>][&jobStatus=<jobStatus>][&pageSize=
<pageSize>][&continuationToken=<continuationToken>]

Authorization: <config.sharedAccessSignature>
Content-Type: application/json; charset=utf-8
Request-Id: <guid>
User-Agent: <sdk-name>/<sdk-version>
The continuationToken is provided from the response.

Jobs Properties
The following list shows the properties and corresponding descriptions, which can be used when querying
for jobs or job results.

PROPERTY DESCRIPTION

jobId Application provided ID for the job.

startTime Application provided start time (ISO-8601) for the job.

endTime IoT Hub provided date (ISO-8601) for when the job
completed. Valid only after the job reaches the 'completed'
state.

type Types of jobs:

scheduledUpdateTwin: A job used to update a set of


desired properties or tags.

scheduledDeviceMethod: A job used to invoke a device


method on a set of device twins.

status Current state of the job. Possible values for status:

pending: Scheduled and waiting to be picked up by the


job service.

scheduled: Scheduled for a time in the future.

running: Currently active job.

canceled: Job has been canceled.

failed: Job failed.

completed: Job has completed.

deviceJobStatistics Statistics about the job's execution.

deviceJobStatistics properties:

deviceJobStatistics.deviceCount: Number of devices in


the job.

deviceJobStatistics.failedCount: Number of devices


where the job failed.

deviceJobStatistics.succeededCount: Number of
devices where the job succeeded.
PROPERTY DESCRIPTION

deviceJobStatistics.runningCount: Number of devices


that are currently running the job.

deviceJobStatistics.pendingCount: Number of devices


that are pending to run the job.

Additional reference material


Other reference topics in the IoT Hub developer guide include:
IoT Hub endpoints describes the various endpoints that each IoT hub exposes for run-time and
management operations.
Throttling and quotas describes the quotas that apply to the IoT Hub service and the throttling behavior
to expect when you use the service.
Azure IoT device and service SDKs lists the various language SDKs you can use when you develop both
device and service apps that interact with IoT Hub.
IoT Hub query language for device twins, jobs, and message routing describes the IoT Hub query
language. Use this query language to retrieve information from IoT Hub about your device twins and
jobs.
IoT Hub MQTT support provides more information about IoT Hub support for the MQTT protocol.

Next steps
To try out some of the concepts described in this article, see the following IoT Hub tutorial:
Schedule and broadcast jobs
Reference - IoT Hub endpoints
5/29/2018 • 5 min to read • Edit Online

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device
management, are only available in the standard tier of IoT hub. For more information about the basic and
standard IoT Hub tiers, see How to choose the right IoT Hub tier.

IoT Hub names


You can find the name of the IoT hub that hosts your endpoints in the portal on the Overview blade. By
default, the DNS name of an IoT hub looks like: {your iot hub name}.azure-devices.net .
You can use Azure DNS to create a custom DNS name for your IoT hub. For more information, see Use
Azure DNS to provide custom domain settings for an Azure service.

List of built-in IoT Hub endpoints


Azure IoT Hub is a multi-tenant service that exposes its functionality to various actors. The following
diagram shows the various endpoints that IoT Hub exposes.

The following list describes the endpoints:


Resource provider. The IoT Hub resource provider exposes an Azure Resource Manager interface.
This interface enables Azure subscription owners to create and delete IoT hubs, and to update IoT
hub properties. IoT Hub properties govern hub-level security policies, as opposed to device-level
access control, and functional options for cloud-to-device and device-to-cloud messaging. The IoT
Hub resource provider also enables you to export device identities.
Device identity management. Each IoT hub exposes a set of HTTPS REST endpoints to manage
device identities (create, retrieve, update, and delete). Device identities are used for device
authentication and access control.
Device twin management. Each IoT hub exposes a set of service-facing HTTPS REST endpoint to
query and update device twins (update tags and properties).
Jobs management. Each IoT hub exposes a set of service-facing HTTPS REST endpoint to query
and manage jobs.
Device endpoints. For each device in the identity registry, IoT Hub exposes a set of endpoints:
Send device-to -cloud messages. A device uses this endpoint to send device-to-cloud
messages.
Receive cloud -to -device messages. A device uses this endpoint to receive targeted cloud-to-
device messages.
Initiate file uploads. A device uses this endpoint to receive an Azure Storage SAS URI from
IoT Hub to upload a file.
Retrieve and update device twin properties. A device uses this endpoint to access its device
twin's properties.
Receive direct method requests. A device uses this endpoint to listen for direct method's
requests.
These endpoints are exposed using MQTT v3.1.1, HTTPS 1.1, and AMQP 1.0 protocols.
AMQP is also available over WebSockets on port 443.
Service endpoints. Each IoT hub exposes a set of endpoints for your solution back end to
communicate with your devices. With one exception, these endpoints are only exposed using the
AMQP protocol. The method invocation endpoint is exposed over the HTTPS protocol.
Receive device-to -cloud messages. This endpoint is compatible with Azure Event Hubs. A
back-end service can use it to read the device-to-cloud messages sent by your devices. You
can create custom endpoints on your IoT hub in addition to this built-in endpoint.
Send cloud -to -device messages and receive delivery acknowledgments. These endpoints
enable your solution back end to send reliable cloud-to-device messages, and to receive the
corresponding delivery or expiration acknowledgments.
Receive file notifications. This messaging endpoint allows you to receive notifications of when
your devices successfully upload a file.
Direct method invocation. This endpoint allows a back-end service to invoke a direct method
on a device.
Receive operations monitoring events. This endpoint allows you to receive operations
monitoring events if your IoT hub has been configured to emit them. For more information,
see IoT Hub operations monitoring.
The Azure IoT SDKs article describes the various ways to access these endpoints.
All IoT Hub endpoints use the TLS protocol, and no endpoint is ever exposed on
unencrypted/unsecured channels.

Custom endpoints
You can link existing Azure services in your subscription to your IoT hub to act as endpoints for
message routing. These endpoints act as service endpoints and are used as sinks for message routes.
Devices cannot write directly to the additional endpoints. To learn more about message routes, see the
developer guide entry on sending and receiving messages with IoT hub.
IoT Hub currently supports the following Azure services as additional endpoints:
Azure Storage containers
Event Hubs
Service Bus Queues
Service Bus Topics
IoT Hub needs write access to these service endpoints for message routing to work. If you configure
your endpoints through the Azure portal, the necessary permissions are added for you. Make sure you
configure your services to support the expected throughput. When you first configure your IoT solution,
you may need to monitor your additional endpoints and make any necessary adjustments for the actual
load.
If a message matches multiple routes that all point to the same endpoint, IoT Hub delivers message to
that endpoint only once. Therefore, you do not need to configure deduplication on your Service Bus
queue or topic. In partitioned queues, partition affinity guarantees message ordering.
For the limits on the number of endpoints you can add, see Quotas and throttling.
When using Azure Storage containers
IoT Hub only supports writing data to Azure Storage containers as blobs in the Apache Avro format.
IoT Hub batches messages and writes data to a blob whenever:
The batch reaches a certain size.
Or a certain amount of time has elapsed.
IoT Hub will write to an empty blob if there is no data to write.
IoT Hub defaults to the following file naming convention:

{iothub}/{partition}/{YYYY}/{MM}/{DD}/{HH}/{mm}

You may use whatever file naming convention you wish, however you must use all listed tokens.
When using Service Bus queues and topics
Service Bus queues and topics used as IoT Hub endpoints must not have Sessions or Duplicate
Detection enabled. If either of those options are enabled, the endpoint appears as Unreachable in the
Azure portal.

Field gateways
In an IoT solution, a field gateway sits between your devices and your IoT Hub endpoints. It is typically
located close to your devices. Your devices communicate directly with the field gateway by using a
protocol supported by the devices. The field gateway connects to an IoT Hub endpoint using a protocol
that is supported by IoT Hub. A field gateway might be a dedicated hardware device or a low -power
computer running custom gateway software.
You can use Azure IoT Edge to implement a field gateway. IoT Edge offers functionality such as
multiplexing communications from multiple devices onto the same IoT Hub connection.

Next steps
Other reference topics in this IoT Hub developer guide include:
IoT Hub query language for device twins, jobs, and message routing
Quotas and throttling
IoT Hub MQTT support
IoT Hub query language for device and
module twins, jobs, and message routing
5/29/2018 • 15 min to read • Edit Online

IoT Hub provides a powerful SQL -like language to retrieve information regarding device twins and
jobs, and message routing. This article presents:
An introduction to the major features of the IoT Hub query language, and
The detailed description of the language.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device
management, are only available in the standard tier of IoT hub. For more information about the basic and
standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Device and module twin queries


Device twins and module twins can contain arbitrary JSON objects as both tags and properties. IoT
Hub enables you to query device twins and module twins as a single JSON document containing all
twin information. Assume, for instance, that your IoT hub device twins have the following structure
(module twin would be similar just with an additional moduleId):
{
"deviceId": "myDeviceId",
"etag": "AAAAAAAAAAc=",
"status": "enabled",
"statusUpdateTime": "0001-01-01T00:00:00",
"connectionState": "Disconnected",
"lastActivityTime": "0001-01-01T00:00:00",
"cloudToDeviceMessageCount": 0,
"authenticationType": "sas",
"x509Thumbprint": {
"primaryThumbprint": null,
"secondaryThumbprint": null
},
"version": 2,
"tags": {
"location": {
"region": "US",
"plant": "Redmond43"
}
},
"properties": {
"desired": {
"telemetryConfig": {
"configId": "db00ebf5-eeeb-42be-86a1-458cccb69e57",
"sendFrequencyInSecs": 300
},
"$metadata": {
...
},
"$version": 4
},
"reported": {
"connectivity": {
"type": "cellular"
},
"telemetryConfig": {
"configId": "db00ebf5-eeeb-42be-86a1-458cccb69e57",
"sendFrequencyInSecs": 300,
"status": "Success"
},
"$metadata": {
...
},
"$version": 7
}
}
}

Device twin queries


IoT Hub exposes the device twins as a document collection called devices. So the following query
retrieves the whole set of device twins:

SELECT * FROM devices

NOTE
Azure IoT SDKs support paging of large results.

IoT Hub allows you to retrieve device twins filtering with arbitrary conditions. For instance, to receive
device twins where the location.region tag is set to US use the following query:
SELECT * FROM devices
WHERE tags.location.region = 'US'

Boolean operators and arithmetic comparisons are supported as well. For example, to retrieve device
twins located in the US and configured to send telemetry less than every minute use the following
query:

SELECT * FROM devices


WHERE tags.location.region = 'US'
AND properties.reported.telemetryConfig.sendFrequencyInSecs >= 60

As a convenience, it is also possible to use array constants with the IN and NIN (not in) operators.
For instance, to retrieve device twins that report WiFi or wired connectivity use the following query:

SELECT * FROM devices


WHERE properties.reported.connectivity IN ['wired', 'wifi']

It is often necessary to identify all device twins that contain a specific property. IoT Hub supports the
function is_defined() for this purpose. For instance, to retrieve device twins that define the
connectivity property use the following query:

SELECT * FROM devices


WHERE is_defined(properties.reported.connectivity)

Refer to the WHERE clause section for the full reference of the filtering capabilities.
Grouping and aggregations are also supported. For instance, to find the count of devices in each
telemetry configuration status use the following query:

SELECT properties.reported.telemetryConfig.status AS status,


COUNT() AS numberOfDevices
FROM devices
GROUP BY properties.reported.telemetryConfig.status

This grouping query would return a result similar to the following example:

[
{
"numberOfDevices": 3,
"status": "Success"
},
{
"numberOfDevices": 2,
"status": "Pending"
},
{
"numberOfDevices": 1,
"status": "Error"
}
]

In this example, three devices reported successful configuration, two are still applying the
configuration, and one reported an error.
Projection queries allow developers to return only the properties they care about. For example, to
retrieve the last activity time of all disconnected devices use the following query:

SELECT LastActivityTime FROM devices WHERE status = 'enabled'

Module twin queries


Querying on module twins is similar to query on device twins, but using a different
collection/namespace, i.e. instead of “from devices” you can query

SELECT * FROM devices.modules

We don't allow join between the devices and devices.modules collections. If you want to query
module twins across devices, you do do it based on tags. This query will return all module twins
across all devices with the scanning status:

Select * from devices.modules where reported.properties.status = 'scanning'

This query will return all module twins with the scanning status, but only on the specified subset of
devices.

Select * from devices.modules where reported.properties.status = 'scanning' and deviceId IN


('device1', 'device2')

C# example
The query functionality is exposed by the C# service SDK in the RegistryManager class. Here is an
example of a simple query:

var query = registryManager.CreateQuery("SELECT * FROM devices", 100);


while (query.HasMoreResults)
{
var page = await query.GetNextAsTwinAsync();
foreach (var twin in page)
{
// do work on twin object
}
}

The query object is instantiated with a page size (up to 100). Then multiple pages are retrieved by
calling the GetNextAsTwinAsync methods multiple times.
The query object exposes multiple Next values, depending on the deserialization option required by
the query. For example, device twin or job objects, or plain JSON when using projections.
Node.js example
The query functionality is exposed by the Azure IoT service SDK for Node.js in the Registry object.
Here is an example of a simple query:
var query = registry.createQuery('SELECT * FROM devices', 100);
var onResults = function(err, results) {
if (err) {
console.error('Failed to fetch the results: ' + err.message);
} else {
// Do something with the results
results.forEach(function(twin) {
console.log(twin.deviceId);
});

if (query.hasMoreResults) {
query.nextAsTwin(onResults);
}
}
};
query.nextAsTwin(onResults);

The query object is instantiated with a page size (up to 100). Then multiple pages are retrieved by
calling the nextAsTwin method multiple times.
The query object exposes multiple Next values, depending on the deserialization option required by
the query. For example, device twin or job objects, or plain JSON when using projections.
Limitations

IMPORTANT
Query results can have a few minutes of delay with respect to the latest values in device twins. If querying
individual device twins by ID, use the retrieve device twin API. This API always contains the latest values and
has higher throttling limits.

Currently, comparisons are supported only between primitive types (no objects), for instance
... WHERE properties.desired.config = properties.reported.config is supported only if those
properties have primitive values.

Get started with jobs queries


Jobs provide a way to execute operations on sets of devices. Each device twin contains the information
of the jobs of which it is part in a collection called jobs. Logically,
{
"deviceId": "myDeviceId",
"etag": "AAAAAAAAAAc=",
"tags": {
...
},
"properties": {
...
},
"jobs": [
{
"deviceId": "myDeviceId",
"jobId": "myJobId",
"jobType": "scheduleTwinUpdate",
"status": "completed",
"startTimeUtc": "2016-09-29T18:18:52.7418462",
"endTimeUtc": "2016-09-29T18:20:52.7418462",
"createdDateTimeUtc": "2016-09-29T18:18:56.7787107Z",
"lastUpdatedDateTimeUtc": "2016-09-29T18:18:56.8894408Z",
"outcome": {
"deviceMethodResponse": null
}
},
...
]
}

Currently, this collection is queryable as devices.jobs in the IoT Hub query language.

IMPORTANT
Currently, the jobs property is never returned when querying device twins. That is, queries that contain 'FROM
devices'. The jobs property can only be accessed directly with queries using FROM devices.jobs .

For instance, to get all jobs (past and scheduled) that affect a single device, you can use the following
query:

SELECT * FROM devices.jobs


WHERE devices.jobs.deviceId = 'myDeviceId'

Note how this query provides the device-specific status (and possibly the direct method response) of
each job returned. It is also possible to filter with arbitrary Boolean conditions on all object properties
in the devices.jobs collection. For instance, to retrieve all completed device twin update jobs that
were created after September 2016 for a specific device, use the following query:

SELECT * FROM devices.jobs


WHERE devices.jobs.deviceId = 'myDeviceId'
AND devices.jobs.jobType = 'scheduleTwinUpdate'
AND devices.jobs.status = 'completed'
AND devices.jobs.createdTimeUtc > '2016-09-01'

You can also retrieve the per-device outcomes of a single job.

SELECT * FROM devices.jobs


WHERE devices.jobs.jobId = 'myJobId'

Limitations
Currently, queries on devices.jobs do not support:
Projections, therefore only SELECT * is possible.
Conditions that refer to the device twin in addition to job properties (see the preceding section).
Performing aggregations, such as count, avg, group by.

Device-to-cloud message routes query expressions


Using device-to-cloud routes, you can configure IoT Hub to dispatch device-to-cloud messages to
different endpoints. Dispatching is based on expressions evaluated against individual messages.
The route condition uses the same IoT Hub query language as conditions in twin and job queries.
Route conditions are evaluated on the message headers and body. Your routing query expression may
involve only message headers, only the message body, or both. IoT Hub assumes a specific schema
for the headers and message body in order to route messages. The following sections describe what is
required for IoT Hub to properly route.
Routing on message headers
IoT Hub assumes the following JSON representation of message headers for message routing:

{
"message": {
"systemProperties": {
"contentType": "application/json",
"contentEncoding": "utf-8",
"iothub-message-source": "deviceMessages",
"iothub-enqueuedtime": "2017-05-08T18:55:31.8514657Z"
},
"appProperties": {
"processingPath": "<optional>",
"verbose": "<optional>",
"severity": "<optional>",
"testDevice": "<optional>"
},
"body": "{\"Weather\":{\"Temperature\":50}}"
}
}

Message system properties are prefixed with the '$' symbol. User properties are always accessed
with their name. If a user property name coincides with a system property (such as $contentType ), the
user property is retrieved with the $contentType expression. You can always access the system
property using brackets {} : for instance, you can use the expression {$contentType} to access the
system property contentType . Bracketed property names always retrieve the corresponding system
property.
Remember that property names are case insensitive.

NOTE
All message properties are strings. System properties, as described in the developer guide, are currently not
available to use in queries.

For example, if you use a messageType property, you might want to route all telemetry to one
endpoint, and all alerts to another endpoint. You can write the following expression to route the
telemetry:
messageType = 'telemetry'

And the following expression to route the alert messages:

messageType = 'alert'

Boolean expressions and functions are also supported. This feature enables you to distinguish
between severity level, for example:

messageType = 'alerts' AND as_number(severity) <= 2

Refer to the Expression and conditions section for the full list of supported operators and functions.
Routing on message bodies
IoT Hub can only route based on message body contents if the message body is properly formed
JSON encoded in UTF -8, UTF -16, or UTF -32. Set the content type of the message to
application/json . Set the content encoding to one of the supported UTF encodings in the message
headers. If either of the headers is not specified, IoT Hub does not attempt to evaluate any query
expression involving the body against the message. If your message is not a JSON message, or if the
message does not specify the content type and content encoding, you can still use message routing to
route the message based on the message headers.
The following example shows how to create a message with a properly formed and encoded JSON
body:
string messageBody = @"{
""Weather"":{
""Temperature"":50,
""Time"":""2017-03-09T00:00:00.000Z"",
""PrevTemperatures"":[
20,
30,
40
],
""IsEnabled"":true,
""Location"":{
""Street"":""One Microsoft Way"",
""City"":""Redmond"",
""State"":""WA""
},
""HistoricalData"":[
{
""Month"":""Feb"",
""Temperature"":40
},
{
""Month"":""Jan"",
""Temperature"":30
}
]
}
}";

// Encode message body using UTF-8


byte[] messageBytes = Encoding.UTF8.GetBytes(messageBody);

using (var message = new Message(messageBytes))


{
// Set message body type and content encoding.
message.ContentEncoding = "utf-8";
message.ContentType = "application/json";

// Add other custom application properties.


message.Properties["Status"] = "Active";

await deviceClient.SendEventAsync(message);
}

You can use $body in the query expression to route the message. You can use a simple body
reference, body array reference, or multiple body references in the query expression. Your query
expression can also combine a body reference with a message header reference. For example, the
following are all valid query expressions:

$body.Weather.HistoricalData[0].Month = 'Feb'
$body.Weather.Temperature = 50 AND $body.Weather.IsEnabled
length($body.Weather.Location.State) = 2
$body.Weather.Temperature = 50 AND Status = 'Active'

Basics of an IoT Hub query


Every IoT Hub query consists of SELECT and FROM clauses, with optional WHERE and GROUP BY
clauses. Every query is run on a collection of JSON documents, for example device twins. The FROM
clause indicates the document collection to be iterated on (devices or devices.jobs). Then, the filter in
the WHERE clause is applied. With aggregations, the results of this step are grouped as specified in
the GROUP BY clause. For each group, a row is generated as specified in the SELECT clause.
SELECT <select_list>
FROM <from_specification>
[WHERE <filter_condition>]
[GROUP BY <group_specification>]

FROM clause
The FROM <from_specification> clause can assume only two values: FROM devices to query
device twins, or FROM devices.jobs to query job per-device details.

WHERE clause
The WHERE <filter_condition> clause is optional. It specifies one or more conditions that the
JSON documents in the FROM collection must satisfy to be included as part of the result. Any JSON
document must evaluate the specified conditions to "true" to be included in the result.
The allowed conditions are described in section Expressions and conditions.

SELECT clause
The SELECT <select_list> is mandatory and specifies what values are retrieved from the query. It
specifies the JSON values to be used to generate new JSON objects. For each element of the filtered
(and optionally grouped) subset of the FROM collection, the projection phase generates a new JSON
object. This object is constructed with the values specified in the SELECT clause.
Following is the grammar of the SELECT clause:

SELECT [TOP <max number>] <projection list>

<projection_list> ::=
'*'
| <projection_element> AS alias [, <projection_element> AS alias]+

<projection_element> :==
attribute_name
| <projection_element> '.' attribute_name
| <aggregate>

<aggregate> :==
count()
| avg(<projection_element>)
| sum(<projection_element>)
| min(<projection_element>)
| max(<projection_element>)

Attribute_name refers to any property of the JSON document in the FROM collection. Some
examples of SELECT clauses can be found in the Getting started with device twin queries section.
Currently, selection clauses different than SELECT* are only supported in aggregate queries on
device twins.

GROUP BY clause
The GROUP BY <group_specification> clause is an optional step that executes after the filter
specified in the WHERE clause, and before the projection specified in the SELECT. It groups
documents based on the value of an attribute. These groups are used to generate aggregated values
as specified in the SELECT clause.
An example of a query using GROUP BY is:

SELECT properties.reported.telemetryConfig.status AS status,


COUNT() AS numberOfDevices
FROM devices
GROUP BY properties.reported.telemetryConfig.status

The formal syntax for GROUP BY is:

GROUP BY <group_by_element>
<group_by_element> :==
attribute_name
| < group_by_element > '.' attribute_name

Attribute_name refers to any property of the JSON document in the FROM collection.
Currently, the GROUP BY clause is only supported when querying device twins.

Expressions and conditions


At a high level, an expression:
Evaluates to an instance of a JSON type (such as Boolean, number, string, array, or object).
Is defined by manipulating data coming from the device JSON document and constants using
built-in operators and functions.
Conditions are expressions that evaluate to a Boolean. Any constant different than Boolean true is
considered as false. This rule includes null, undefined, any object or array instance, any string, and
the Boolean false.
The syntax for expressions is:

<expression> ::=
<constant> |
attribute_name |
<function_call> |
<expression> binary_operator <expression> |
<create_array_expression> |
'(' <expression> ')'

<function_call> ::=
<function_name> '(' expression ')'

<constant> ::=
<undefined_constant>
| <null_constant>
| <number_constant>
| <string_constant>
| <array_constant>

<undefined_constant> ::= undefined


<null_constant> ::= null
<number_constant> ::= decimal_literal | hexadecimal_literal
<string_constant> ::= string_literal
<array_constant> ::= '[' <constant> [, <constant>]+ ']'

To understand what each symbol in the expressions syntax stands for, refer to the following table:
SYMBOL DEFINITION

attribute_name Any property of the JSON document in the FROM


collection.

binary_operator Any binary operator listed in the Operators section.

function_name Any function listed in the Functions section.

decimal_literal A float expressed in decimal notation.

hexadecimal_literal A number expressed by the string ‘0x’ followed by a


string of hexadecimal digits.

string_literal String literals are Unicode strings represented by a


sequence of zero or more Unicode characters or escape
sequences. String literals are enclosed in single quotes
or double quotes. Allowed escapes: \' , \" , \\ ,
\uXXXX for Unicode characters defined by 4
hexadecimal digits.

Operators
The following operators are supported:

FAMILY OPERATORS

Arithmetic +, -, *, /, %

Logical AND, OR, NOT

Comparison =, !=, <, >, <=, >=, <>

Functions
When querying twins and jobs the only supported function is:

FUNCTION DESCRIPTION

IS_DEFINED(property) Returns a Boolean indicating if the property has been


assigned a value (including null ).

In routes conditions, the following math functions are supported:

FUNCTION DESCRIPTION

ABS(x) Returns the absolute (positive) value of the specified


numeric expression.

EXP(x) Returns the exponential value of the specified numeric


expression (e^x).

POWER(x,y) Returns the value of the specified expression to the


specified power (x^y).

SQUARE(x) Returns the square of the specified numeric value.


FUNCTION DESCRIPTION

CEILING(x) Returns the smallest integer value greater than, or


equal to, the specified numeric expression.

FLOOR(x) Returns the largest integer less than or equal to the


specified numeric expression.

SIGN(x) Returns the positive (+1), zero (0), or negative (-1) sign
of the specified numeric expression.

SQRT(x) Returns the square root of the specified numeric value.

In routes conditions, the following type checking and casting functions are supported:

FUNCTION DESCRIPTION

AS_NUMBER Converts the input string to a number. noop if input


is a number; Undefined if string does not represent a
number.

IS_ARRAY Returns a Boolean value indicating if the type of the


specified expression is an array.

IS_BOOL Returns a Boolean value indicating if the type of the


specified expression is a Boolean.

IS_DEFINED Returns a Boolean indicating if the property has been


assigned a value.

IS_NULL Returns a Boolean value indicating if the type of the


specified expression is null.

IS_NUMBER Returns a Boolean value indicating if the type of the


specified expression is a number.

IS_OBJECT Returns a Boolean value indicating if the type of the


specified expression is a JSON object.

IS_PRIMITIVE Returns a Boolean value indicating if the type of the


specified expression is a primitive (string, Boolean,
numeric, or null ).

IS_STRING Returns a Boolean value indicating if the type of the


specified expression is a string.

In routes conditions, the following string functions are supported:

FUNCTION DESCRIPTION

CONCAT(x, y, …) Returns a string that is the result of concatenating two


or more string values.

LENGTH(x) Returns the number of characters of the specified


string expression.
FUNCTION DESCRIPTION

LOWER(x) Returns a string expression after converting uppercase


character data to lowercase.

UPPER(x) Returns a string expression after converting lowercase


character data to uppercase.

SUBSTRING(string, start [, length]) Returns part of a string expression starting at the


specified character zero-based position and continues
to the specified length, or to the end of the string.

INDEX_OF(string, fragment) Returns the starting position of the first occurrence of


the second string expression within the first specified
string expression, or -1 if the string is not found.

STARTS_WITH(x, y) Returns a Boolean indicating whether the first string


expression starts with the second.

ENDS_WITH(x, y) Returns a Boolean indicating whether the first string


expression ends with the second.

CONTAINS(x,y) Returns a Boolean indicating whether the first string


expression contains the second.

Next steps
Learn how to execute queries in your apps using Azure IoT SDKs.
Reference - IoT Hub quotas and throttling
5/29/2018 • 4 min to read • Edit Online

Quotas and throttling


Each Azure subscription can have at most 10 IoT hubs, and at most 1 Free hub.
Each IoT hub is provisioned with a certain number of units in a specific tier. For more information, see
Azure IoT Hub Pricing. The tier and number of units determine the maximum daily quota of
messages that you can send.
The tier also determines the throttling limits that IoT Hub enforces on all operations.

Operation throttles
Operation throttles are rate limitations that are applied in minute ranges, and are intended to prevent
abuse. IoT Hub tries to avoid returning errors whenever possible, but starts returning exceptions if
the throttle is violated for too long.
At any given time, you can increase quotas or throttle limits by increasing the number of provisioned
units in an IoT hub.
The following table shows the enforced throttles. Values refer to an individual hub.

THROTTLE FREE, B1, AND S1 B2 AND S2 B3 AND S3

Identity registry 1.67/sec/unit 1.67/sec/unit 83.33/sec/unit


operations (create, (100/min/unit) (100/min/unit) (5000/min/unit)
retrieve, list, update,
delete)

New device connections Higher of 100/sec or 120 new 6000 new


(this limit applies to the 12/sec/unit connections/sec/unit connections/sec/unit
rate at which new For example, two S1
connections are units are 2*12 = 24 new
established, not the total connections/sec, but you
number of connections) have at least 100 new
connections/sec across
your units. With nine S1
units, you have 108 new
connections/sec (9*12)
across your units.

Device-to-cloud sends Higher of 100/sec or 120/sec/unit 6000/sec/unit


12/sec/unit
For example, two S1
units are 2*12 = 24/sec,
but you have at least
100/sec across your
units. With nine S1 units,
you have 108/sec (9*12)
across your units.

Cloud-to-device sends1 1.67/sec/unit 1.67/sec/unit 83.33/sec/unit


(100/min/unit) (100/min/unit) (5000/min/unit)
THROTTLE FREE, B1, AND S1 B2 AND S2 B3 AND S3

Cloud-to-device 16.67/sec/unit 16.67/sec/unit 833.33/sec/unit


receives1 (1000/min/unit) (1000/min/unit) (50000/min/unit)
(only when device uses
HTTPS)

File upload 1.67 file upload 1.67 file upload 83.33 file upload
notifications/sec/unit notifications/sec/unit notifications/sec/unit
(100/min/unit) (100/min/unit) (5000/min/unit)

Direct methods1 160KB/sec/unit2 480KB/sec/unit2 24MB/sec/unit2

Twin (device and 10/sec Higher of 10/sec or 50/sec/unit


module) reads1 1/sec/unit

Twin updates (device and 10/sec Higher of 10/sec or 50/sec/unit


module)1 1/sec/unit

Jobs operations1 1.67/sec/unit 1.67/sec/unit 83.33/sec/unit


(create, update, list, (100/min/unit) (100/min/unit) (5000/min/unit)
delete)

Jobs per-device 10/sec Higher of 10/sec or 50/sec/unit


operation throughput1 1/sec/unit

Configurations and edge 0.33/sec/unit 0.33/sec/unit 0.33/sec/unit


deployments1 (20/min/unit) (20/min/unit) (20/min/unit)
(create, update, list,
delete)

1This feature is not available in the basic tier of IoT Hub. For more information, see How to choose
the right IoT Hub.
2Throttling meter size is 8 KB.

The device connections throttle governs the rate at which new device connections can be established
with an IoT hub. The device connections throttle does not govern the maximum number of
simultaneously connected devices. The throttle depends on the number of units that are provisioned
for the IoT hub.
For example, if you buy a single S1 unit, you get a throttle of 100 connections per second. Therefore,
to connect 100,000 devices, it takes at least 1000 seconds (approximately 16 minutes). However, you
can have as many simultaneously connected devices as you have devices registered in your identity
registry.
For an in-depth discussion of IoT Hub throttling behavior, see the blog post IoT Hub throttling and
you.

IMPORTANT
Identity registry operations are intended for run-time use in device management and provisioning scenarios.
Reading or updating a large number of device identities is supported through import and export jobs.

Other limits
IoT Hub enforces other operational limits:
OPERATION LIMIT

File upload URIs 10000 SAS URIs can be out for a storage account at
one time.
10 SAS URIs/device can be out at one time.

Jobs1 Job history is retained up to 30 days


Maximum concurrent jobs is 1 (for Free) and S1, 5 (for
S2), 10 (for S3).

Additional endpoints Paid SKU hubs may have 10 additional endpoints. Free
SKU hubs may have one additional endpoint.

Message routing rules Paid SKU hubs may have 100 routing rules. Free SKU
hubs may have five routing rules.

Device-to-cloud messaging Maximum message size 256 KB

Cloud-to-device messaging1 Maximum message size 64 KB. Maximum pending


messages for delivery is 50.

Direct method1 Maximum direct method payload size is 128 KB.

Configurations 20 configurations per hub.

Edge deployments 20 deployments per hub. 20 modules per deployment.

Twins Maximum size per twin section (tags, desired


properties, reported properties) is 8 KB

1This feature is not available in the basic tier of IoT Hub. For more information, see How to choose
the right IoT Hub.

NOTE
Currently, the maximum number of devices you can connect to a single IoT hub is 500,000. If you want to
increase this limit, contact Microsoft Support.

Latency
IoT Hub strives to provide low latency for all operations. However, due to network conditions and
other unpredictable factors it cannot guarantee a maximum latency. When designing your solution,
you should:
Avoid making any assumptions about the maximum latency of any IoT Hub operation.
Provision your IoT hub in the Azure region closest to your devices.
Consider using Azure IoT Edge to perform latency-sensitive operations on the device or on a
gateway close to the device.
Multiple IoT Hub units affect throttling as described previously, but do not provide any additional
latency benefits or guarantees. If you see unexpected increases in operation latency, contact Microsoft
Support.

Next steps
Other reference topics in this IoT Hub developer guide include:
IoT Hub endpoints
IoT Hub query language for device twins, jobs, and message routing
IoT Hub MQTT support
Azure IoT Hub pricing information
5/29/2018 • 3 min to read • Edit Online

Azure IoT Hub pricing provides the general information on different SKUs and pricing for IoT Hub. This article
contains additional details on how the various IoT Hub functionalities are metered as messages by IoT Hub.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are
only available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to
choose the right IoT Hub tier.

Charges per operation


OPERATION BILLING INFORMATION

Identity registry operations Not charged.


(create, retrieve, list, update, delete)

Device-to-cloud messages Successfully sent messages are charged in 4-KB chunks on


ingress into IoT Hub. For example, a 6-KB message is charged
2 messages.

Cloud-to-device messages Successfully sent messages are charged in 4-KB chunks, for
example a 6-KB message is charged 2 messages.

File uploads File transfer to Azure Storage is not metered by IoT Hub. File
transfer initiation and completion messages are charged as
messaged metered in 4-KB increments. For example,
transferring a 10-MB file is charged two messages in addition
to the Azure Storage cost.

Direct methods Successful method requests are charged in 4-KB chunks,


responses with non-empty bodies are charged in 4-KB chunks
as additional messages. Requests to disconnected devices are
charged as messages in 4-KB chunks. For example, a method
with a 6-KB body that results in a response with no body
from the device, is charged as two messages. A method with a
6-KB body that results in a 1-KB response from the device is
charged as two messages for the request plus another
message for the response.

Device and module twin reads Twin reads from the device or module and from the solution
back end are charged as messages in 512-byte chunks. For
example, reading a 6-KB twin is charged as 12 messages.

Device and module twin updates (tags and properties) Twin updates from the device or module and from the
solution back end are charged as messages in 512-byte
chunks. For example, reading a 6-KB twin is charged as 12
messages.
OPERATION BILLING INFORMATION

Device and module twin queries Queries are charged as messages depending on the result size
in 512-byte chunks.

Jobs operations Not charged.


(create, update, list, delete)

Jobs per-device operations Jobs operations (such as twin updates, and methods) are
charged as normal. For example, a job resulting in 1000
method calls with 1-KB requests and empty-body responses
is charged 1000 messages.

NOTE
All sizes are computed considering the payload size in bytes (protocol framing is ignored). For messages, which have
properties and body, the size is computed in a protocol-agnostic way. For more information, see IoT Hub messaging
developer's guide.

Example #1
A device sends one 1-KB device-to-cloud message per minute to IoT Hub, which is then read by Azure Stream
Analytics. The solution back end invokes a method (with 512-byte payload) on the device every 10 minutes to
trigger a specific action. The device responds to the method with a result of 200 bytes.
The device consumes:
One message * 60 minutes * 24 hours = 1440 messages per day for the device-to-cloud messages.
Two request plus response * 6 times per hour * 24 hours = 288 messages for the methods.
This calculation gives a total of 1728 messages per day.

Example #2
A device sends one 100-KB device-to-cloud message every hour. It also updates its device twin with 1-KB
payloads every four hours. The solution back end, once per day, reads the 14-KB device twin and updates it with
512-byte payloads to change configurations.
The device consumes:
25 (100 KB / 4 KB ) messages * 24 hours for device-to-cloud messages.
Two messages (1 KB / 0.5 KB ) * six times per day for device twin updates.
This calculation gives a total of 612 messages per day.
The solution back end consumes 28 messages (14 KB / 0.5 KB ) to read the device twin, plus one message to
update it, for a total of 29 messages.
In total, the device and the solution back end consume 641 messages per day.
Understand and use Azure IoT Hub SDKs
6/6/2018 • 2 min to read • Edit Online

There are two categories of software development kits (SDKs) for working with IoT Hub:
Device SDKs enable you to build apps that run on your IoT devices. These apps send
telemetry to your IoT hub, and optionally receive messages, job, method, or twin updates
from your IoT hub.
Service SDKs enable you to manage your IoT hub, and optionally send messages, schedule
jobs, invoke direct methods, or send desired property updates to your IoT devices.
Learn about the benefits of developing using Azure IoT SDKs here.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device
management, are only available in the standard tier of IoT hub. For more information about the basic and
standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Azure IoT device SDKs


The Microsoft Azure IoT device SDKs contain code that facilitates building devices and
applications that connect to and are managed by Azure IoT Hub services.
Azure IoT Hub device SDK for .NET:
Install from Nuget
Source code
API reference
Azure IoT Hub device SDK for C: written in ANSI C (C99) for portability and broad platform
compatibility
Install from apt-get, MBED, Arduino IDE, or Nuget
Source code
API reference
Azure IoT Hub device SDK for Java:
Add to Maven project
Source code
API reference
Azure IoT Hub device SDK for Node.js:
Install from npm
Source code
API reference
Azure IoT Hub device SDK for Python:
Install from pip
Source code
Azure IoT Hub device SDK for iOS:
Install from CocoaPod
Samples

NOTE
See the readme files in the GitHub repositories for information about using language and platform-specific
package managers to install binaries and dependencies on your development machine.

OS platform and hardware compatibility


For more information about SDK compatibility with specific hardware devices, see the Azure
Certified for IoT device catalog or individual repository.

Azure IoT service SDKs


The Azure IoT service SDKs contain code to facilitate building applications that interact directly
with IoT Hub to manage devices and security.
Azure IoT Hub service SDK for .NET:
Download from Nuget
Source code
API reference
Azure IoT Hub service SDK for Java:
Add to Maven project
Source code
API reference
Azure IoT Hub service SDK for Node.js:
Download from npm
Source code
API reference
Azure IoT Hub service SDK for Python:
Download from pip
Source code
Azure IoT Hub service SDK for C:
Download from apt-get, MBED, Arduino IDE, or Nuget
Source code
Azure IoT Hub service SDK for iOS:
Install from CocoaPod
Samples
NOTE
See the readme files in the GitHub repositories for information about using language and platform-specific
package managers to install binaries and dependencies on your development machine.

Next steps
Other reference topics in this IoT Hub developer guide include:
IoT Hub endpoints
IoT Hub query language for device twins, jobs, and message routing
Quotas and throttling
IoT Hub MQTT support
IoT Hub REST API reference
Communicate with your IoT hub using the MQTT
protocol
5/29/2018 • 11 min to read • Edit Online

IoT Hub enables devices to communicate with the IoT Hub device endpoints using:
MQTT v3.1.1 on port 8883
MQTT v3.1.1 over WebSocket on port 443.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management,
are only available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see
How to choose the right IoT Hub tier.

All device communication with IoT Hub must be secured using TLS/SSL. Therefore, IoT Hub doesn’t support
non-secure connections over port 1883.

Connecting to IoT Hub


A device can use the MQTT protocol to connect to an IoT hub using:
Either the libraries in the Azure IoT SDKs.
Or the MQTT protocol directly.

Using the device SDKs


Device SDKs that support the MQTT protocol are available for Java, Node.js, C, C#, and Python. The device
SDKs use the standard IoT Hub connection string to establish a connection to an IoT hub. To use the MQTT
protocol, the client protocol parameter must be set to MQTT. By default, the device SDKs connect to an IoT
Hub with the CleanSession flag set to 0 and use QoS 1 for message exchange with the IoT hub.
When a device is connected to an IoT hub, the device SDKs provide methods that enable the device to
exchange messages with an IoT hub.
The following table contains links to code samples for each supported language and specifies the parameter
to use to establish a connection to IoT Hub using the MQTT protocol.

LANGUAGE PROTOCOL PARAMETER

Node.js azure-iot-device-mqtt

Java IotHubClientProtocol.MQTT

C MQTT_Protocol

C# TransportType.Mqtt

Python IoTHubTransportProvider.MQTT
Migrating a device app from AMQP to MQTT
If you are using the device SDKs, switching from using AMQP to MQTT requires changing the protocol
parameter in the client initialization as stated previously.
When doing so, make sure to check the following items:
AMQP returns errors for many conditions, while MQTT terminates the connection. As a result your
exception handling logic might require some changes.
MQTT does not support the reject operations when receiving cloud-to-device messages. If your back-end
app needs to receive a response from the device app, consider using direct methods.

Using the MQTT protocol directly


If a device cannot use the device SDKs, it can still connect to the public device endpoints using the MQTT
protocol on port 8883. In the CONNECT packet the device should use the following values:
For the ClientId field, use the deviceId.
For the Username field, use {iothubhostname}/{device_id}/api-version=2016-11-14 , where
{iothubhostname} is the full CName of the IoT hub.

For example, if the name of your IoT hub is contoso.azure-devices.net and if the name of your
device is MyDevice01, the full Username field should contain:
contoso.azure-devices.net/MyDevice01/api-version=2016-11-14

For the Password field, use a SAS token. The format of the SAS token is the same as for both the
HTTPS and AMQP protocols:
SharedAccessSignature sig={signature-string}&se={expiry}&sr={URL-encoded-resourceURI}

NOTE
If you use X.509 certificate authentication, SAS token passwords are not required. For more information, see
Set up X.509 security in your Azure IoT Hub

For more information about how to generate SAS tokens, see the device section of Using IoT Hub
security tokens.
When testing, you can also use the device explorer tool to quickly generate a SAS token that you can
copy and paste into your own code:
1. Go to the Management tab in Device Explorer.
2. Click SAS Token (top right).
3. On SASTokenForm, select your device in the DeviceID drop down. Set your TTL.
4. Click Generate to create your token.
The SAS token that's generated has the following structure:
HostName={your hub name}.azure-
devices.net;DeviceId=javadevice;SharedAccessSignature=SharedAccessSignature sr={your hub
name}.azure-devices.net%2Fdevices%2FMyDevice01%2Fapi-version%3D2016-11-
14&sig=vSgHBMUG.....Ntg%3d&se=1456481802

The part of this token to use as the Password field to connect using MQTT is:
SharedAccessSignature sr={your hub name}.azure-devices.net%2Fdevices%2FMyDevice01%2Fapi-
version%3D2016-11-14&sig=vSgHBMUG.....Ntg%3d&se=1456481802
For MQTT connect and disconnect packets, IoT Hub issues an event on the Operations Monitoring
channel. This event has additional information that can help you to troubleshoot connectivity issues.
The device app can specify a Will message in the CONNECT packet. The device app should use
devices/{device_id}/messages/events/{property_bag} or devices/{device_id}/messages/events/{property_bag}
as the Will topic name to define Will messages to be forwarded as a telemetry message. In this case, if the
network connection is closed, but a DISCONNECT packet was not previously received from the device, then
IoT Hub sends the Will message supplied in the CONNECT packet to the telemetry channel. The telemetry
channel can be either the default Events endpoint or a custom endpoint defined by IoT Hub routing. The
message has the iothub-MessageType property with a value of Will assigned to it.
TLS/SSL configuration
To use the MQTT protocol directly, your client must connect over TLS/SSL. Attempts to skip this step fail with
connection errors.
In order to establish a TLS connection, you may need to download and reference the DigiCert Baltimore Root
Certificate. This certificate is the one that Azure uses to secure the connection. You can find this certificate in
the Azure-iot-sdk-c repository. More information about these certificates can be found on Digicert's website.
An example of how to implement this using the Python version of the Paho MQTT library by the Eclipse
Foundation might look like the following.
First, install the Paho library from your command-line environment:

pip install paho-mqtt

Then, implement the client in a Python script. Replace the placeholders as follows:
<local path to digicert.cer> is the path to a local file that contains the DigiCert Baltimore Root
certificate. You can create this file by copying the certificate information from certs.c in the Azure IoT SDK
for C. Include the lines -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- , remove the "
marks at the beginning and end of every line, and remove the \r\n characters at the end of every line.
<device id from device registry> is the ID of a device you added to your IoT hub.
<generated SAS token> is a SAS token for the device created as described previously in this article.
<iot hub name> the name of your IoT hub.
from paho.mqtt import client as mqtt
import ssl

path_to_root_cert = "<local path to digicert.cer>"


device_id = "<device id from device registry>"
sas_token = "<generated SAS token>"
iot_hub_name = "<iot hub name>"

def on_connect(client, userdata, flags, rc):


print ("Device connected with result code: " + str(rc))
def on_disconnect(client, userdata, rc):
print ("Device disconnected with result code: " + str(rc))
def on_publish(client, userdata, mid):
print ("Device sent message")

client = mqtt.Client(client_id=device_id, protocol=mqtt.MQTTv311)

client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish

client.username_pw_set(username=iot_hub_name+".azure-devices.net/" + device_id, password=sas_token)

client.tls_set(ca_certs=path_to_root_cert, certfile=None, keyfile=None, cert_reqs=ssl.CERT_REQUIRED,


tls_version=ssl.PROTOCOL_TLSv1, ciphers=None)
client.tls_insecure_set(False)

client.connect(iot_hub_name+".azure-devices.net", port=8883)

client.publish("devices/" + device_id + "/messages/events/", "{id=123}", qos=1)


client.loop_forever()

Sending device -to -cloud messages


After making a successful connection, a device can send messages to IoT Hub using
devices/{device_id}/messages/events/ or devices/{device_id}/messages/events/{property_bag} as a Topic
Name. The {property_bag} element enables the device to send messages with additional properties in a url-
encoded format. For example:

RFC 2396-encoded(<PropertyName1>)=RFC 2396-encoded(<PropertyValue1>)&RFC 2396-


encoded(<PropertyName2>)=RFC 2396-encoded(<PropertyValue2>)…

NOTE
This {property_bag} element uses the same encoding as for query strings in the HTTPS protocol.

The following is a list of IoT Hub implementation-specific behaviors:


IoT Hub does not support QoS 2 messages. If a device app publishes a message with QoS 2, IoT Hub
closes the network connection.
IoT Hub does not persist Retain messages. If a device sends a message with the RETAIN flag set to 1, IoT
Hub adds the x-opt-retain application property to the message. In this case, instead of persisting the
retain message, IoT Hub passes it to the backend app.
IoT Hub only supports one active MQTT connection per device. Any new MQTT connection on behalf of
the same device ID causes IoT Hub to drop the existing connection.
For more information, see Messaging developer's guide.
Receiving cloud-to -device messages
To receive messages from IoT Hub, a device should subscribe using
devices/{device_id}/messages/devicebound/# as a Topic Filter. The multi-level wildcard # in the Topic Filter
is used only to allow the device to receive additional properties in the topic name. IoT Hub does not allow the
usage of the # or ? wildcards for filtering of subtopics. Since IoT Hub is not a general-purpose pub-sub
messaging broker, it only supports the documented topic names and topic filters.
The device does not receive any messages from IoT Hub, until it has successfully subscribed to its device-
specific endpoint, represented by the devices/{device_id}/messages/devicebound/# topic filter. After a
subscription has been established, the device receives cloud-to-device messages that were sent to it after the
time of the subscription. If the device connects with CleanSession flag set to 0, the subscription is persisted
across different sessions. In this case, the next time the device connects with CleanSession 0 it receives any
outstanding messages sent to it while disconnected. If the device uses CleanSession flag set to 1 though, it
does not receive any messages from IoT Hub until it subscribes to its device-endpoint.
IoT Hub delivers messages with the Topic Name , or
devices/{device_id}/messages/devicebound/
devices/{device_id}/messages/devicebound/{property_bag} when there are message properties.
{property_bag} contains url-encoded key/value pairs of message properties. Only application properties and
user-settable system properties (such as messageId or correlationId) are included in the property bag.
System property names have the prefix $, application properties use the original property name with no
prefix.
When a device app subscribes to a topic with QoS 2, IoT Hub grants maximum QoS level 1 in the SUBACK
packet. After that, IoT Hub delivers messages to the device using QoS 1.
Retrieving a device twin's properties
First, a device subscribes to $iothub/twin/res/# , to receive the operation's responses. Then, it sends an empty
message to topic $iothub/twin/GET/?$rid={request id} , with a populated value for request ID. The service
then sends a response message containing the device twin data on topic
$iothub/twin/res/{status}/?$rid={request id} , using the same request ID as the request.

Request ID can be any valid value for a message property value, as per IoT Hub messaging developer's
guide, and status is validated as an integer.
The response body contains the properties section of the device twin. The following snippet shows the body
of the identity registry entry limited to the "properties" member, for example:

{
"properties": {
"desired": {
"telemetrySendFrequency": "5m",
"$version": 12
},
"reported": {
"telemetrySendFrequency": "5m",
"batteryLevel": 55,
"$version": 123
}
}
}

The possible status codes are:

STATUS DESCRIPTION

200 Success
STATUS DESCRIPTION

429 Too many requests (throttled), as per IoT Hub throttling

5** Server errors

For more information, see Device twins developer's guide.


Update device twin's reported properties
The following sequence describes how a device updates the reported properties in the device twin in IoT
Hub:
1. A device must first subscribe to the $iothub/twin/res/# topic to receive the operation's responses
from IoT Hub.
2. A device sends a message that contains the device twin update to the
$iothub/twin/PATCH/properties/reported/?$rid={request id} topic. This message includes a request ID
value.
3. The service then sends a response message that contains the new ETag value for the reported
properties collection on topic $iothub/twin/res/{status}/?$rid={request id} . This response message
uses the same request ID as the request.
The request message body contains a JSON document, that contains new values for reported properties.
Each member in the JSON document updates or add the corresponding member in the device twin’s
document. A member set to null , deletes the member from the containing object. For example:

{
"telemetrySendFrequency": "35m",
"batteryLevel": 60
}

The possible status codes are:

STATUS DESCRIPTION

200 Success

400 Bad Request. Malformed JSON

429 Too many requests (throttled), as per IoT Hub throttling

5** Server errors

For more information, see Device twins developer's guide.


Receiving desired properties update notifications
When a device is connected, IoT Hub sends notifications to the topic
$iothub/twin/PATCH/properties/desired/?$version={new version} , which contain the content of the update
performed by the solution back end. For example:
{
"telemetrySendFrequency": "5m",
"route": null
}

As for property updates, null values means that the JSON object member is being deleted.

IMPORTANT
IoT Hub generates change notifications only when devices are connected. Make sure to implement the device
reconnection flow to keep the desired properties synchronized between IoT Hub and the device app.

For more information, see Device twins developer's guide.


Respond to a direct method
First, a device has to subscribe to $iothub/methods/POST/# . IoT Hub sends method requests to the topic
$iothub/methods/POST/{method name}/?$rid={request id} , with either a valid JSON or an empty body.

To respond, the device sends a message with a valid JSON or empty body to the topic
$iothub/methods/res/{status}/?$rid={request id} . In this message, the request ID must match the one in the
request message, and status must be an integer.
For more information, see Direct method developer's guide.
Additional considerations
As a final consideration, if you need to customize the MQTT protocol behavior on the cloud side, you should
review the Azure IoT protocol gateway. This software enables you to deploy a high-performance custom
protocol gateway that interfaces directly with IoT Hub. The Azure IoT protocol gateway enables you to
customize the device protocol to accommodate brownfield MQTT deployments or other custom protocols.
This approach does require, however, that you run and operate a custom protocol gateway.

Next steps
To learn more about the MQTT protocol, see the MQTT documentation.
To learn more about planning your IoT Hub deployment, see:
Azure Certified for IoT device catalog
Support additional protocols
Compare with Event Hubs
Scaling, HA, and DR
To further explore the capabilities of IoT Hub, see:
IoT Hub developer guide
Deploying AI to edge devices with Azure IoT Edge
Glossary of IoT Hub terms
5/29/2018 • 19 min to read • Edit Online

This article lists some of the common terms used in the IoT Hub articles.

Advanced Message Queueing Protocol


Advanced Message Queueing Protocol (AMQP ) is one of the messaging protocols that IoT Hub supports for
communicating with devices. For more information about the messaging protocols that IoT Hub supports, see
Send and receive messages with IoT Hub.

Automatic Device Management


Automatic Device Management in Azure IoT Hub automates many of the repetitive and complex tasks of
managing large device fleets over the entirety of their lifecycles. With Automatic Device Management, you can
target a set of devices based on their properties, define a desired configuration, and let IoT Hub update devices
whenever they come into scope. Consists of automatic device configurations and IoT Edge automatic
deployments.

Automatic device configuration


Your solution back end can use automatic device configurations to assign desired properties to a set of device
twins and report status using system metrics and custom metrics.

Azure CLI
The Azure CLI is a cross-platform, open-source, shell-based, command tool for creating and managing resources
in Microsoft Azure. This version of the CLI is implemented using Node.js.

Azure CLI 2.0


The Azure CLI 2.0 is a cross-platform, open-source, shell-based, command tool for creating and managing
resources in Microsoft Azure. This preview version of the CLI is implemented using Python.

Azure IoT device SDKs


There are device SDKs available for multiple languages that enable you to create device apps that interact with an
IoT hub. The IoT Hub tutorials show you how to use these device SDKs. You can find the source code and further
information about the device SDKs in this GitHub repository.

Azure IoT service SDKs


There are service SDKs available for multiple languages that enable you to create back-end apps that interact with
an IoT hub. The IoT Hub tutorials show you how to use these service SDKs. You can find the source code and
further information about the service SDKs in this GitHub repository.

Azure portal
The Microsoft Azure portal is a central place where you can provision and manage your Azure resources. It
organizes its content using blades.
Azure PowerShell
Azure PowerShell is a collection of cmdlets you can use to manage Azure with Windows PowerShell. You can use
the cmdlets to create, test, deploy, and manage solutions and services delivered through the Azure platform.

Azure Resource Manager


Azure Resource Manager enables you to work with the resources in your solution as a group. You can deploy,
update, or delete the resources for your solution in a single, coordinated operation.

Azure Service Bus


Service Bus provides cloud-enabled communication with enterprise messaging and relayed communication that
helps you connect on-premises solutions with the cloud. Some IoT Hub tutorials make use Service Bus queues.

Azure Storage
Azure Storage is a cloud storage solution. It includes the Blob Storage service that you can use to store
unstructured object data. Some IoT Hub tutorials use blob storage.

Back-end app
In the context of IoT Hub, a back-end app is an app that connects to one of the service-facing endpoints on an IoT
hub. For example, a back-end app might retrieve device-to-cloudmessages or manage the identity registry.
Typically, a back-end app runs in the cloud, but in many of the tutorials the back-end apps are console apps
running on your local development machine.

Built-in endpoints
Every IoT hub includes a built-in endpoint that is Event Hub-compatible. You can use any mechanism that works
with Event Hubs to read device-to-cloud messages from this endpoint.

Cloud gateway
A cloud gateway enables connectivity for devices that cannot connect directly to IoT Hub. A cloud gateway is
hosted in the cloud in contrast to a field gateway that runs local to your devices. A typical use case for a cloud
gateway is to implement protocol translation for your devices.

Cloud-to-device
Refers to messages sent from an IoT hub to a connected device. Often, these messages are commands that
instruct the device to take an action. For more information, see Send and receive messages with IoT Hub.

Configuration
In the context of automatic device configuration, a configuration within IoT Hub defines the desired configuration
for a set of devices twins and provides a set of metrics to report status and progress.

Connection string
You use connection strings in your app code to encapsulate the information required to connect to an endpoint. A
connection string typically includes the address of the endpoint and security information, but connection string
formats vary across services. There are two types of connection string associated with the IoT Hub service:
Device connection strings enable devices to connect to the device-facing endpoints on an IoT hub.
IoT Hub connection strings enable back-end apps to connect to the service-facing endpoints on an IoT hub.

Custom endpoints
You can create custom endpoints on an IoT hub to deliver messages dispatched by a routing rule. Custom
endpoints connect directly to an Event hub, a Service Bus queue, or a Service Bus topic.

Custom gateway
A gateway enables connectivity for devices that cannot connect directly to IoT Hub. You can use Azure IoT Edge to
build custom gateways that implement custom logic to handle messages, custom protocol conversions, and other
processing on the edge.

Data-point message
A data-point message is a device-to-cloud message that contains telemetry data such as wind speed or
temperature.

Desired configuration
In the context of a device twin, desired configuration refers to the complete set of properties and metadata in the
device twin that should be synchronized with the device.

Desired properties
In the context of a device twin, desired properties is a subsection of the device twin that is used with reported
properties to synchronize device configuration or condition. Desired properties can only be set by a back-end app
and are observed by the device app.

Device-to-cloud
Refers to messages sent from a connected device to IoT Hub. These messages may be data-point or interactive
messages. For more information, see Send and receive messages with IoT Hub.

Device
In the context of IoT, a device is typically a small-scale, standalone computing device that may collect data or
control other devices. For example, a device might be an environmental monitoring device, or a controller for the
watering and ventilation systems in a greenhouse. The device catalog provides a list of hardware devices certified
to work with IoT Hub.

Device app
A device app runs on your device and handles the communication with your IoT hub. Typically, you use one of the
Azure IoT device SDKs when you implement a device app. In many of the IoT tutorials, you use a simulated device
for convenience.

Device condition
Refers to device state information, such as the connectivity method currently in use, as reported by a device app.
Device apps can also report their capabilities. You can query for condition and capability information using device
twins.
Device data
Device data refers to the per-device data stored in the IoT Hub identity registry. It is possible to import and export
this data.

Device explorer
The device explorer is a tool that runs on Windows and enables you to manage your devices in the identity
registry.The tool can also send and receive messages to your devices.

Device Identities REST API


The Device Identities REST API enables you to manage your devices registered in the identity registry using a
REST API. Typically, you should use one of the higher-level service SDKs as shown in the IoT Hub tutorials.

Device identity
The device identity is the unique identifier assigned to every device registered in the identity registry.

Module identity
The module identity is the unique identifier assigned to every module that belong to a device. Module identity is
also registered in the identity registry.

Device management
Device management encompasses the full lifecycle associated with managing the devices in your IoT solution
including planning, provisioning, configuring, monitoring, and retiring.

Device management patterns


IoT hub enables common device management patterns including rebooting, performing factory resets, and
performing firmware updates on your devices.

Device Messaging REST API


You can use the Device Messaging REST API from a device to send device-to-cloud messages to an IoT hub, and
receive cloud-to-device messages from an IoT hub. Typically, you should use one of the higher-level device SDKs
as shown in the IoT Hub tutorials.

Device provisioning
Device provisioning is the process of adding the initial device data to the stores in your solution. To enable a new
device to connect to your hub, you must add a device ID and keys to the IoT Hub identity registry. As part of the
provisioning process, you might need to initialize device-specific data in other solution stores.

Device twin
A device twin is JSON document that stores device state information such as metadata, configurations, and
conditions. IoT Hub persists a device twin for each device that you provision in your IoT hub. Device twins enable
you to synchronize device conditions and configurations between the device and the solution back end. You can
query device twins to locate specific devices and query the status of long-running operations.
Module twin
Similar to device twin, a module twin is JSON document that stores module state information such as metadata,
configurations, and conditions. IoT Hub persists a module twin for each module identity that you provision under a
device identity in your IoT hub. Module twins enable you to synchronize module conditions and configurations
between the module and the solution back end. You can query module twins to locate specific modules and query
the status of long-running operations.

Twin queries
Device and module twin queries use the SQL -like IoT Hub query language to retrieve information from your
device twins or module twins. You can use the same IoT Hub query language to retrieve information about jobs
running in your IoT hub.

Device Twin REST API


You can use the Device Twin REST API from the solution back end to manage your device twins. The API enables
you to retrieve and update device twin properties and invoke direct methods. Typically, you should use one of the
higher-level service SDKs as shown in the IoT Hub tutorials.

Twin synchronization
Twin synchronization uses the desired properties in your device twins or module twins to configure your devices
or modules and retrieve reported properties from them to store in the twin.

Direct method
A direct method is a way for you to trigger a method to execute on a device by invoking an API on your IoT hub.

Endpoint
An IoT hub exposes multiple endpoints that enable your apps to connect to the IoT hub. There are device-facing
endpoints that enable devices to perform operations such as sending device-to-cloud messages and receiving
cloud-to-device messages. There are service-facing management endpoints that enable back-end apps to perform
operations such as device identity management and device twin management. There are service-facing built-in
endpoints for reading device-to-cloud messages. You can create custom endpoints to receive device-to-cloud
messages dispatched by a routing rule.

Event Hubs service


Event Hubs is a highly scalable data ingress service that can ingest millions of events per second. The service
enables you to process and analyze the massive amounts of data produced by your connected devices and
applications. For a comparison with the IoT Hub service, see Comparison of Azure IoT Hub and Azure Event Hubs.

Event Hub-compatible endpoint


To read device-to-cloud messages sent to your IoT hub, you can connect to an endpoint on your hub and use any
Event Hub-compatible method to read those messages. Event Hub-compatible methods include using the Event
Hubs SDKs and Azure Stream Analytics.

Field gateway
A field gateway enables connectivity for devices that cannot connect directly to IoT Hub and is typically deployed
locally with your devices. For more information, see What is Azure IoT Hub?
Free account
You can create a free Azure account to complete the IoT Hub tutorials and experiment with the IoT Hub service
(and other Azure services).

Gateway
A gateway enables connectivity for devices that cannot connect directly to IoT Hub. See also Field Gateway, Cloud
Gateway, and Custom Gateway.

Identity registry
The identity registry is the built-in component of an IoT hub that stores information about the individual devices
permitted to connect to an IoT hub.

Interactive message
An interactive message is a cloud-to-device message that triggers an immediate action in the solution back end.
For example, a device might send an alarm about a failure that should be automatically logged in to a CRM
system.

Automatic Device Management


Automatic Device Management in Azure IoT Hub automates many of the repetitive and complex tasks of
managing large device fleets over the entirety of their lifecycles. With Automatic Device Management, you can
target a set of devices based on their properties, define a desired configuration, and let IoT Hub update devices
whenever they come into scope. Consists of automatic device configurations and IoT Edge automatic
deployments.

IoT Edge
Azure IoT Edge enables cloud-driven deployment of Azure services and solution-specific code to on-premises
devices. IoT Edge devices can aggregate data from other devices to perform computing and analytics before the
data is sent to the cloud. For more information please see Azure IoT Edge.

IoT Edge agent


The part of the IoT Edge runtime responsible for deploying and monitoring modules.

IoT Edge device


IoT Edge devices have the IoT Edge runtime installed and are flagged as “IoT Edge device” in the device details.
Learn how to deploy Azure IoT Edge on a simulated device in Linux - preview.

IoT Edge automatic deployment


An IoT Edge automatic deployment configures a target set of IoT Edge devices to run a set of IoT Edge modules.
Each deployment continuously ensures that all devices that match its target condition are running the specified set
of modules, even when new devices are created or are modified to match the target condition. Each IoT Edge
device only receives the highest priority deployment whose target condition it meets. Learn more about IoT Edge
automatic deployment.

IoT Edge deployment manifest


A Json document containing the information to be copied in one or more IoT Edge devices' module twin(s) to
deploy a set of modules, routes and associated module desired properties.

IoT Edge gateway device


An IoT Edge device with downstream device. The downstream device can be either IoT Edge or not IoT Edge
device.

IoT Edge hub


The part of the IoT Edge runtime responsible for module to module communications, upstream (toward IoT Hub)
and downstream (away from IoT Hub) communications.

IoT Edge leaf device


An IoT Edge device with no downstream device.

IoT Edge module


An IoT Edge module is a Docker container that you can deploy to IoT Edge devices. It performs a specific task,
such as ingesting a message from a device, transforming a message, or sending a message to an IoT hub. It
communicates with other modules and sends data to the IoT Edge runtime. Understand the requirements and
tools for developing IoT Edge modules.

IoT Edge module identity


A record in the IoT Hub module identity registry detailing the existence and security credentials to be used by a
module to authenticate with an edge hub or IoT Hub.

IoT Edge module image


The docker image that is used by the IoT Edge runtime to instantiate module instances.

IoT Edge module twin


A Json document persisted in the IoT Hub that stores the state information for a module instance.

IoT Edge priority


When two IoT Edge deployments target the same device, the deployment with higher priority gets applied. If two
deployments have the same priority, the deployment with the later creation date gets applied. Learn more about
priority.

IoT Edge runtime


IoT Edge runtime includes everything that Microsoft distributes to be installed on an IoT Edge device. It included
Edge agent, Edge hub and Edge CTL tool.

IoT Edge set modules to a single device


An operation that copies the content of an IoT Edge manifest on one device' module twin. The underlying API is a
generic 'apply configuration', which simply takes an IoT Edge manifest as an input.
IoT Edge target condition
In an IoT Edge deployment, Target condition is any Boolean condition on device twins’ tags to select the target
devices of the deployment, e.g. "tag.environment = prod". The target condition is continuously evaluated to include
any new devices that meet the requirements or remove devices that no longer do. Learn more about target
condition

IoT Hub
IoT Hub is a fully managed Azure service that enables reliable and secure bidirectional communications between
millions of devices and a solution back end. For more information, see What is Azure IoT Hub? Using your Azure
subscription, you can create IoT hubs to handle your IoT messaging workloads.

IoT Hub metrics


IoT Hub metrics give you data about the state of the IoT hubs in your Azure subscription. IoT Hub metrics enable
you to assess the overall health of the service and the devices connected to it. IoT Hub metrics can help you see
what is going on with your IoT hub and investigate root-cause issues without needing to contact Azure support.

IoT Hub query language


The IoT Hub query language is a SQL -like language that enables you to query your jobs and device twins.

IoT Hub Resource Provider REST API


You can use the IoT Hub Resource Provider REST API to manage the IoT hubs in your Azure subscription
performing operations such as creating, updating, and deleting hubs.

IoT solution accelerators


Azure IoT solution accelerators package together multiple Azure services into solutions. These solutions enable
you to get started quickly with end-to-end implementations of common IoT scenarios. For more information, see
What are Azure IoT solution accelerators?

The IoT extension for Azure CLI 2.0


The IoT extension for Azure CLI 2.0 is a cross-platform, command-line tool. The tool enables you to manage your
devices in the identity registry, send and receive messages and files from your devices, and monitor your IoT hub
operations.

Job
Your solution back end can use jobs to schedule and track activities on a set of devices registered with your IoT
hub. Activities include updating device twin desired properties, updating device twin tags, and invoking direct
methods. IoT Hub also uses jobs to import to and export from the identity registry.

Jobs REST API


The Jobs REST API enables you to manage jobs running in your IoT hub.

MQTT
MQTT is one of the messaging protocols that IoT Hub supports for communicating with devices. For more
information about the messaging protocols that IoT Hub supports, see Send and receive messages with IoT Hub.
Operations monitoring
IoT Hub operations monitoring enables you to monitor the status of operations on your IoT hub in real time. IoT
Hub tracks events across several categories of operations. You can opt into sending events from one or more
categories to an IoT Hub endpoint for processing. You can monitor the data for errors or set up more complex
processing based on data patterns.

Physical device
A physical device is a real device such as a Raspberry Pi that connects to an IoT hub. For convenience, many of the
IoT Hub tutorials use simulated devices to enable you to run samples on your local machine.

Primary and secondary keys


When you connect to a device-facing or service-facing endpoint on an IoT hub, your connection string includes
key to grant you access. When you add a device to the identity registry or add a shared access policy to your hub,
the service generates a primary and secondary key. Having two keys enables you to roll over from one key to
another when you update a key without losing access to the IoT hub.

Protocol gateway
A protocol gateway is typically deployed in the cloud and provides protocol translation services for devices
connecting to IoT Hub. For more information, see What is Azure IoT Hub?

Quotas and throttling


There are various quotas that apply to your use of IoT Hub, many of the quotas vary based on the tier of the IoT
hub. IoT Hub also applies throttles to your use of the service at run time.

Reported configuration
In the context of a device twin, reported configuration refers to the complete set of properties and metadata in the
device twin that should be reported to the solution back end.

Reported properties
In the context of a device twin, reported properties is a subsection of the device twin used with desired properties
to synchronize device configuration or condition. Reported properties can only be set by the device app and can be
read and queried by a back-end app.

Resource group
Azure Resource Manager uses resource groups to group related resources together. You can use a resource group
to perform operations on all the resources on the group simultaneously.

Retry policy
You use a retry policy to handle transient errors when you connect to a cloud service.

Routing rules
You configure routing rules in your IoT hub to route device-to-cloud messages to a built-in endpoint or to custom
endpoints for processing by your solution back end.
SASL PLAIN
SASL PL AIN is a protocol that the AMQP protocol uses to transfer security tokens.

Shared access signature


Shared Access Signatures (SAS ) are an authentication mechanism based on SHA-256 secure hashes or URIs. SAS
authentication has two components: a Shared Access Policy and a Shared Access Signature (often called a token).
A device uses SAS to authenticate with an IoT hub. Back-end apps also use SAS to authenticate with the service-
facing endpoints on an IoT hub. Typically, you include the SAS token in the connection string that an app uses to
establish a connection to an IoT hub.

Shared access policy


A shared access policy defines the permissions granted to anyone who has a valid primary or secondary key
associated with that policy. You can manage the shared access policies and keys for your hub in the portal.

Simulated device
For convenience, many of the IoT Hub tutorials use simulated devices to enable you to run samples on your local
machine. In contrast, a physical device is a real device such as a Raspberry Pi that connects to an IoT hub.

Solution
A solution can refer to a Visual Studio solution that includes one or more projects. A solution might also refer to an
IoT solution that includes elements such as devices, device apps, an IoT hub, other Azure services, and back-end
apps.

Subscription
An Azure subscription is where billing takes place. Each Azure resource you create or Azure service you use is
associated with a single subscription. Many quotas also apply at the level of a subscription.

System properties
In the context of a device twin, system properties are read-only and include information regarding the device
usage such as last activity time and connection state.

Tags
In the context of a device twin, tags are device metadata stored and retrieved by the solution back end in the form
of a JSON document. Tags are not visible to apps on a device.

Telemetry
Devices collect telemetry data, such as wind speed or temperature, and use data-point messages to send the
telemetry to an IoT hub.

Token service
You can use a token service to implement an authentication mechanism for your devices. It uses an IoT Hub
shared access policy with DeviceConnect permissions to create device-scoped tokens. These tokens enable a
device to connect to your IoT hub. A device uses a custom authentication mechanism to authenticate with the
token service. IF the device authenticates successfully, the token service issues a SAS token for the device to use to
access your IoT hub.

X.509 client certificate


A device can use an X.509 certificate to authenticate with IoT Hub. Using an X.509 certificate is an alternative to
using a SAS token.
Azure IoT device SDK for C
5/29/2018 • 17 min to read • Edit Online

The Azure IoT device SDK is a set of libraries designed to simplify the process of sending messages to and
receiving messages from the Azure IoT Hub service. There are different variations of the SDK, each targeting
a specific platform, but this article describes the Azure IoT device SDK for C.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management,
are only available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see
How to choose the right IoT Hub tier.

The Azure IoT device SDK for C is written in ANSI C (C99) to maximize portability. This feature makes the
libraries well-suited to operate on multiple platforms and devices, especially where minimizing disk and
memory footprint is a priority.
There are a broad range of platforms on which the SDK has been tested (see the Azure Certified for IoT device
catalog for details). Although this article includes walkthroughs of sample code running on the Windows
platform, the code described in this article is identical across the range of supported platforms.
The following video presents an overview of the Azure IoT SDK for C:

This article introduces you to the architecture of the Azure IoT device SDK for C. It demonstrates how to
initialize the device library, send data to IoT Hub, and receive messages from it. The information in this article
should be enough to get started using the SDK, but also provides pointers to additional information about the
libraries.

SDK architecture
You can find the Azure IoT device SDK for C GitHub repository and view details of the API in the C API
reference.
The latest version of the libraries can be found in the master branch of the repository:
The core implementation of the SDK is in the iothub_client folder that contains the implementation of the
lowest API layer in the SDK: the IoTHubClient library. The IoTHubClient library contains APIs
implementing raw messaging for sending messages to IoT Hub and receiving messages from IoT Hub.
When using this library, you are responsible for implementing message serialization, but other details of
communicating with IoT Hub are handled for you.
The serializer folder contains helper functions and samples that show you how to serialize data before
sending to Azure IoT Hub using the client library. The use of the serializer is not mandatory and is provided
as a convenience. To use the serializer library, you define a model that specifies the data to send to IoT Hub
and the messages you expect to receive from it. Once the model is defined, the SDK provides you with an
API surface that enables you to easily work with device-to-cloud and cloud-to-device messages without
worrying about the serialization details. The library depends on other open source libraries that implement
transport using protocols such as MQTT and AMQP.
The IoTHubClient library depends on other open source libraries:
The Azure C shared utility library, which provides common functionality for basic tasks (such as
strings, list manipulation, and IO ) needed across several Azure-related C SDKs.
The Azure uAMQP library, which is a client-side implementation of AMQP optimized for resource
constrained devices.
The Azure uMQTT library, which is a general-purpose library implementing the MQTT protocol and
optimized for resource constrained devices.
Use of these libraries is easier to understand by looking at example code. The following sections walk you
through several of the sample applications that are included in the SDK. This walkthrough should give you a
good feel for the various capabilities of the architectural layers of the SDK and an introduction to how the APIs
work.

Before you run the samples


Before you can run the samples in the Azure IoT device SDK for C, you must create an instance of the IoT Hub
service in your Azure subscription. Then complete the following tasks:
Prepare your development environment
Obtain device credentials.
Prepare your development environment
Packages are provided for common platforms (such as NuGet for Windows or apt_get for Debian and Ubuntu)
and the samples use these packages when available. In some cases, you need to compile the SDK for or on
your device. If you need to compile the SDK, see Prepare your development environment in the GitHub
repository.
To obtain the sample application code, download a copy of the SDK from GitHub. Get your copy of the source
from the master branch of the GitHub repository.
Obtain the device credentials
Now that you have the sample source code, the next thing to do is to get a set of device credentials. For a
device to be able to access an IoT hub, you must first add the device to the IoT Hub identity registry. When you
add your device, you get a set of device credentials that you need for the device to be able to connect to the IoT
hub. The sample applications discussed in the next section expect these credentials in the form of a device
connection string.
There are several open source tools to help you manage your IoT hub.
A Windows application called device explorer.
A cross-platform Python CLI tool called the IoT extension for Azure CLI 2.0.
This tutorial uses the graphical device explorer tool. You can also use the the IoT extension for Azure CLI 2.0
tool if you prefer to use a CLI tool.
The device explorer tool uses the Azure IoT service libraries to perform various functions on IoT Hub, including
adding devices. If you use the device explorer tool to add a device, you get a connection string for your device.
You need this connection string to run the sample applications.
If you're not familiar with the device explorer tool, the following procedure describes how to use it to add a
device and obtain a device connection string.
To install the device explorer tool, see How to use the Device Explorer for IoT Hub devices.
When you run the program, you see this interface:
Enter your IoT Hub Connection String in the first field and click Update. This step configures the tool so
that it can communicate with IoT Hub.
When the IoT Hub connection string is configured, click the Management tab:
This tab is where you manage the devices registered in your IoT hub.
You create a device by clicking the Create button. A dialog displays with a set of pre-populated keys (primary
and secondary). Enter a Device ID and then click Create.

When the device is created, the Devices list updates with all the registered devices, including the one you just
created. If you right-click your new device, you see this menu:

If you choose Copy connection string for selected device, the device connection string is copied to the
clipboard. Keep a copy of the device connection string. You need it when running the sample applications
described in the following sections.
When you've completed the steps above, you're ready to start running some code. Both samples have a
constant at the top of the main source file that enables you to enter a connection string. For example, the
corresponding line from the iothub_client_sample_mqtt application appears as follows.

static const char* connectionString = "[device connection string]";

Use the IoTHubClient library


Within the iothub_client folder in the azure-iot-sdk-c repository, there is a samples folder that contains an
application called iothub_client_sample_mqtt.
The Windows version of the iothub_client_sample_mqtt application includes the following Visual Studio
solution:

NOTE
If you open this project in Visual Studio 2017, accept the prompts to retarget the project to the latest version.

This solution contains a single project. There are four NuGet packages installed in this solution:
Microsoft.Azure.C.SharedUtility
Microsoft.Azure.IoTHub.MqttTransport
Microsoft.Azure.IoTHub.IoTHubClient
Microsoft.Azure.umqtt
You always need the Microsoft.Azure.C.SharedUtility package when you are working with the SDK. This
sample uses the MQTT protocol, therefore you must include the Microsoft.Azure.umqtt and
Microsoft.Azure.IoTHub.MqttTransport packages (there are equivalent packages for AMQP and HTTPS ).
Because the sample uses the IoTHubClient library, you must also include the
Microsoft.Azure.IoTHub.IoTHubClient package in your solution.
You can find the implementation for the sample application in the iothub_client_sample_mqtt.c source file.
The following steps use this sample application to walk you through what's required to use the IoTHubClient
library.
Initialize the library

NOTE
Before you start working with the libraries, you may need to perform some platform-specific initialization. For example, if
you plan to use AMQP on Linux you must initialize the OpenSSL library. The samples in the GitHub repository call the
utility function platform_init when the client starts and call the platform_deinit function before exiting. These functions
are declared in the platform.h header file. Examine the definitions of these functions for your target platform in the
repository to determine whether you need to include any platform-specific initialization code in your client.

To start working with the libraries, first allocate an IoT Hub client handle:

if ((iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, MQTT_Protocol)) ==


NULL)
{
(void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
}
else
{
...

You pass a copy of the device connection string you obtained from the device explorer tool to this function. You
also designate the communications protocol to use. This example uses MQTT, but AMQP and HTTPS are also
options.
When you have a valid IOTHUB_CLIENT_HANDLE, you can start calling the APIs to send and receive
messages to and from IoT Hub.
Send messages
The sample application sets up a loop to send messages to your IoT hub. The following snippet:
Creates a message.
Adds a property to the message.
Sends a message.
First, create a message:
size_t iterator = 0;
do
{
if (iterator < MESSAGE_COUNT)
{
sprintf_s(msgText, sizeof(msgText), "{\"deviceId\":\"myFirstDevice\",\"windSpeed\":%.2f}",
avgWindSpeed + (rand() % 4 + 2));
if ((messages[iterator].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned
char*)msgText, strlen(msgText))) == NULL)
{
(void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
}
else
{
messages[iterator].messageTrackingId = iterator;
MAP_HANDLE propMap = IoTHubMessage_Properties(messages[iterator].messageHandle);
(void)sprintf_s(propText, sizeof(propText), "PropMsg_%zu", iterator);
if (Map_AddOrUpdate(propMap, "PropName", propText) != MAP_OK)
{
(void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
}

if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messages[iterator].messageHandle,
SendConfirmationCallback, &messages[iterator]) != IOTHUB_CLIENT_OK)
{
(void)printf("ERROR: IoTHubClient_LL_SendEventAsync..........FAILED!\r\n");
}
else
{
(void)printf("IoTHubClient_LL_SendEventAsync accepted message [%d] for transmission to IoT
Hub.\r\n", (int)iterator);
}
}
}
IoTHubClient_LL_DoWork(iotHubClientHandle);
ThreadAPI_Sleep(1);

iterator++;
} while (g_continueRunning);

Every time you send a message, you specify a reference to a callback function that's invoked when the data is
sent. In this example, the callback function is called SendConfirmationCallback. The following snippet shows
this callback function:

static void SendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)


{
EVENT_INSTANCE* eventInstance = (EVENT_INSTANCE*)userContextCallback;
(void)printf("Confirmation[%d] received for message tracking id = %zu with result = %s\r\n",
callbackCounter, eventInstance->messageTrackingId, ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT,
result));
/* Some device specific action code goes here... */
callbackCounter++;
IoTHubMessage_Destroy(eventInstance->messageHandle);
}

Note the call to the IoTHubMessage_Destroy function when you're done with the message. This function
frees the resources allocated when you created the message.
Receive messages
Receiving a message is an asynchronous operation. First, you register the callback to invoke when the device
receives a message:
if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext) !=
IOTHUB_CLIENT_OK)
{
(void)printf("ERROR: IoTHubClient_LL_SetMessageCallback..........FAILED!\r\n");
}
else
{
(void)printf("IoTHubClient_LL_SetMessageCallback...successful.\r\n");
...

The last parameter is a void pointer to whatever you want. In the sample, it's a pointer to an integer but it could
be a pointer to a more complex data structure. This parameter enables the callback function to operate on
shared state with the caller of this function.
When the device receives a message, the registered callback function is invoked. This callback function
retrieves:
The message id and correlation id from the message.
The message content.
Any custom properties from the message.
static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, void*
userContextCallback)
{
int* counter = (int*)userContextCallback;
const char* buffer;
size_t size;
MAP_HANDLE mapProperties;
const char* messageId;
const char* correlationId;

// Message properties
if ((messageId = IoTHubMessage_GetMessageId(message)) == NULL)
{
messageId = "<null>";
}

if ((correlationId = IoTHubMessage_GetCorrelationId(message)) == NULL)


{
correlationId = "<null>";
}

// Message content
if (IoTHubMessage_GetByteArray(message, (const unsigned char**)&buffer, &size) != IOTHUB_MESSAGE_OK)
{
(void)printf("unable to retrieve the message data\r\n");
}
else
{
(void)printf("Received Message [%d]\r\n Message ID: %s\r\n Correlation ID: %s\r\n Data: <<<%.*s>>>
& Size=%d\r\n", *counter, messageId, correlationId, (int)size, buffer, (int)size);
// If we receive the work 'quit' then we stop running
if (size == (strlen("quit") * sizeof(char)) && memcmp(buffer, "quit", size) == 0)
{
g_continueRunning = false;
}
}

// Retrieve properties from the message


mapProperties = IoTHubMessage_Properties(message);
if (mapProperties != NULL)
{
const char*const* keys;
const char*const* values;
size_t propertyCount = 0;
if (Map_GetInternals(mapProperties, &keys, &values, &propertyCount) == MAP_OK)
{
if (propertyCount > 0)
{
size_t index;

printf(" Message Properties:\r\n");


for (index = 0; index < propertyCount; index++)
{
(void)printf("\tKey: %s Value: %s\r\n", keys[index], values[index]);
}
(void)printf("\r\n");
}
}
}

/* Some device specific action code goes here... */


(*counter)++;
return IOTHUBMESSAGE_ACCEPTED;
}

Use the IoTHubMessage_GetByteArray function to retrieve the message, which in this example is a string.
Uninitialize the library
When you're done sending events and receiving messages, you can uninitialize the IoT library. To do so, issue
the following function call:

IoTHubClient_LL_Destroy(iotHubClientHandle);

This call frees up the resources previously allocated by the IoTHubClient_CreateFromConnectionString


function.
As you can see, it's easy to send and receive messages with the IoTHubClient library. The library handles the
details of communicating with IoT Hub, including which protocol to use (from the perspective of the developer,
this is a simple configuration option).
The IoTHubClient library also provides precise control over how to serialize the data your device sends to IoT
Hub. In some cases this level of control is an advantage, but in others it is an implementation detail that you
don't want to be concerned with. If that's the case, you might consider using the serializer library, which is
described in the next section.

Use the serializer library


Conceptually the serializer library sits on top of the IoTHubClient library in the SDK. It uses the
IoTHubClient library for the underlying communication with IoT Hub, but it adds modeling capabilities that
remove the burden of dealing with message serialization from the developer. How this library works is best
demonstrated by an example.
Inside the serializer folder in the azure-iot-sdk-c repository, is a samples folder that contains an application
called simplesample_mqtt. The Windows version of this sample includes the following Visual Studio solution:

NOTE
If you open this project in Visual Studio 2017, accept the prompts to retarget the project to the latest version.
As with the previous sample, this one includes several NuGet packages:
Microsoft.Azure.C.SharedUtility
Microsoft.Azure.IoTHub.MqttTransport
Microsoft.Azure.IoTHub.IoTHubClient
Microsoft.Azure.IoTHub.Serializer
Microsoft.Azure.umqtt
You've seen most of these packages in the previous sample, but Microsoft.Azure.IoTHub.Serializer is new.
This package is required when you use the serializer library.
You can find the implementation of the sample application in the simplesample_mqtt.c file.
The following sections walk you through the key parts of this sample.
Initialize the library
To start working with the serializer library, call the initialization APIs:

if (serializer_init(NULL) != SERIALIZER_OK)
{
(void)printf("Failed on serializer_init\r\n");
}
else
{
IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle =
IoTHubClient_LL_CreateFromConnectionString(connectionString, MQTT_Protocol);
srand((unsigned int)time(NULL));
int avgWindSpeed = 10;

if (iotHubClientHandle == NULL)
{
(void)printf("Failed on IoTHubClient_LL_Create\r\n");
}
else
{
ContosoAnemometer* myWeather = CREATE_MODEL_INSTANCE(WeatherStation, ContosoAnemometer);
if (myWeather == NULL)
{
(void)printf("Failed on CREATE_MODEL_INSTANCE\r\n");
}
else
{
...

The call to the serializer_init function is a one-time call and initializes the underlying library. Then, you call the
IoTHubClient_LL_CreateFromConnectionString function, which is the same API as in the IoTHubClient
sample. This call sets your device connection string (this call is also where you choose the protocol you want to
use). This sample uses MQTT as the transport, but could use AMQP or HTTPS.
Finally, call the CREATE_MODEL_INSTANCE function. WeatherStation is the namespace of the model and
ContosoAnemometer is the name of the model. Once the model instance is created, you can use it to start
sending and receiving messages. However, it's important to understand what a model is.
Define the model
A model in the serializer library defines the messages that your device can send to IoT Hub and the messages,
called actions in the modeling language, which it can receive. You define a model using a set of C macros as in
the simplesample_mqtt sample application:
BEGIN_NAMESPACE(WeatherStation);

DECLARE_MODEL(ContosoAnemometer,
WITH_DATA(ascii_char_ptr, DeviceId),
WITH_DATA(int, WindSpeed),
WITH_ACTION(TurnFanOn),
WITH_ACTION(TurnFanOff),
WITH_ACTION(SetAirResistance, int, Position)
);

END_NAMESPACE(WeatherStation);

The BEGIN_NAMESPACE and END_NAMESPACE macros both take the namespace of the model as an
argument. It's expected that anything between these macros is the definition of your model or models, and the
data structures that the models use.
In this example, there is a single model called ContosoAnemometer. This model defines two pieces of data
that your device can send to IoT Hub: DeviceId and WindSpeed. It also defines three actions (messages) that
your device can receive: TurnFanOn, TurnFanOff, and SetAirResistance. Each data element has a type, and
each action has a name (and optionally a set of parameters).
The data and actions defined in the model define an API surface that you can use to send messages to IoT Hub,
and respond to messages sent to the device. Use of this model is best understood through an example.
Send messages
The model defines the data you can send to IoT Hub. In this example, that means one of the two data items
defined using the WITH_DATA macro. There are several steps required to send DeviceId and WindSpeed
values to an IoT hub. The first is to set the data you want to send:

myWeather->DeviceId = "myFirstDevice";
myWeather->WindSpeed = avgWindSpeed + (rand() % 4 + 2);

The model you defined earlier enables you to set the values by setting members of a struct. Next, serialize the
message you want to send:

unsigned char* destination;


size_t destinationSize;
if (SERIALIZE(&destination, &destinationSize, myWeather->DeviceId, myWeather->WindSpeed) != CODEFIRST_OK)
{
(void)printf("Failed to serialize\r\n");
}
else
{
sendMessage(iotHubClientHandle, destination, destinationSize);
free(destination);
}

This code serializes the device-to-cloud to a buffer (referenced by destination). The code then invokes the
sendMessage function to send the message to IoT Hub:
static void sendMessage(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, const unsigned char* buffer, size_t
size)
{
static unsigned int messageTrackingId;
IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromByteArray(buffer, size);
if (messageHandle == NULL)
{
printf("unable to create a new IoTHubMessage\r\n");
}
else
{
if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, (void*)
(uintptr_t)messageTrackingId) != IOTHUB_CLIENT_OK)
{
printf("failed to hand over the message to IoTHubClient");
}
else
{
printf("IoTHubClient accepted the message for delivery\r\n");
}
IoTHubMessage_Destroy(messageHandle);
}
messageTrackingId++;
}

The second to last parameter of IoTHubClient_LL_SendEventAsync is a reference to a callback function


that's called when the data is successfully sent. Here's the callback function in the sample:

void sendCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)


{
unsigned int messageTrackingId = (unsigned int)(uintptr_t)userContextCallback;

(void)printf("Message Id: %u Received.\r\n", messageTrackingId);

(void)printf("Result Call Back Called! Result is: %s \r\n",


ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result));
}

The second parameter is a pointer to user context; the same pointer passed to
IoTHubClient_LL_SendEventAsync. In this case, the context is a simple counter, but it can be anything you
want.
That's all there is to sending device-to-cloud messages. The only thing left to cover is how to receive messages.
Receive messages
Receiving a message works similarly to the way messages work in the IoTHubClient library. First, you
register a message callback function:

if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, IoTHubMessage, myWeather) != IOTHUB_CLIENT_OK)


{
printf("unable to IoTHubClient_SetMessageCallback\r\n");
}
else
{
...

Then, you write the callback function that's invoked when a message is received:
static IOTHUBMESSAGE_DISPOSITION_RESULT IoTHubMessage(IOTHUB_MESSAGE_HANDLE message, void*
userContextCallback)
{
IOTHUBMESSAGE_DISPOSITION_RESULT result;
const unsigned char* buffer;
size_t size;
if (IoTHubMessage_GetByteArray(message, &buffer, &size) != IOTHUB_MESSAGE_OK)
{
printf("unable to IoTHubMessage_GetByteArray\r\n");
result = IOTHUBMESSAGE_ABANDONED;
}
else
{
/*buffer is not zero terminated*/
char* temp = malloc(size + 1);
if (temp == NULL)
{
printf("failed to malloc\r\n");
result = IOTHUBMESSAGE_ABANDONED;
}
else
{
(void)memcpy(temp, buffer, size);
temp[size] = '\0';
EXECUTE_COMMAND_RESULT executeCommandResult = EXECUTE_COMMAND(userContextCallback, temp);
result =
(executeCommandResult == EXECUTE_COMMAND_ERROR) ? IOTHUBMESSAGE_ABANDONED :
(executeCommandResult == EXECUTE_COMMAND_SUCCESS) ? IOTHUBMESSAGE_ACCEPTED :
IOTHUBMESSAGE_REJECTED;
free(temp);
}
}
return result;
}

This code is boilerplate -- it's the same for any solution. This function receives the message and takes care of
routing it to the appropriate function through the call to EXECUTE_COMMAND. The function called at this
point depends on the definition of the actions in your model.
When you define an action in your model, you're required to implement a function that's called when your
device receives the corresponding message. For example, if your model defines this action:

WITH_ACTION(SetAirResistance, int, Position)

Define a function with this signature:

EXECUTE_COMMAND_RESULT SetAirResistance(ContosoAnemometer* device, int Position)


{
(void)device;
(void)printf("Setting Air Resistance Position to %d.\r\n", Position);
return EXECUTE_COMMAND_SUCCESS;
}

Note how the name of the function matches the name of the action in the model and that the parameters of
the function match the parameters specified for the action. The first parameter is always required and contains
a pointer to the instance of your model.
When the device receives a message that matches this signature, the corresponding function is called.
Therefore, aside from having to include the boilerplate code from IoTHubMessage, receiving messages is just
a matter of defining a simple function for each action defined in your model.
Uninitialize the library
When you're done sending data and receiving messages, you can uninitialize the IoT library:

...
DESTROY_MODEL_INSTANCE(myWeather);
}
IoTHubClient_LL_Destroy(iotHubClientHandle);
}
serializer_deinit();

Each of these three functions aligns with the three initialization functions described previously. Calling these
APIs ensures that you free previously allocated resources.

Next Steps
This article covered the basics of using the libraries in the Azure IoT device SDK for C. It provided you with
enough information to understand what's included in the SDK, its architecture, and how to get started working
with the Windows samples. The next article continues the description of the SDK by explaining more about the
IoTHubClient library.
To learn more about developing for IoT Hub, see the Azure IoT SDKs.
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Azure IoT device SDK for C – more about
IoTHubClient
5/29/2018 • 13 min to read • Edit Online

The first article in this series introduced the Azure IoT device SDK for C. That article explained that there are
two architectural layers in SDK. At the base is the IoTHubClient library which directly manages communication
with IoT Hub. There's also the serializer library that builds on top of that to provide serialization services. In this
article we'll provide additional detail on the IoTHubClient library.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are
only available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to
choose the right IoT Hub tier.

The previous article described how to use the IoTHubClient library to send events to IoT Hub and receive
messages. This article extends that discussion by explaining how to more precisely manage when you send and
receive data, introducing you to the lower-level APIs. We'll also explain how to attach properties to events (and
retrieve them from messages) using the property handling features in the IoTHubClient library. Finally, we'll
provide additional explanation of different ways to handle messages received from IoT Hub.
The article concludes by covering a couple of miscellaneous topics, including more about device credentials and
how to change the behavior of the IoTHubClient through configuration options.
We'll use the IoTHubClient SDK samples to explain these topics. If you want to follow along, see the
iothub_client_sample_http and iothub_client_sample_amqp applications that are included in the Azure IoT
device SDK for C. Everything described in the following sections is demonstrated in these samples.
You can find the Azure IoT device SDK for C GitHub repository and view details of the API in the C API
reference.

The lower-level APIs


The previous article described the basic operation of the IotHubClient within the context of the
iothub_client_sample_amqp application. For example, it explained how to initialize the library using this code.

IOTHUB_CLIENT_HANDLE iotHubClientHandle;
iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, AMQP_Protocol);

It also described how to send events using this function call.

IoTHubClient_SendEventAsync(iotHubClientHandle, message.messageHandle, SendConfirmationCallback, &message);

The article also described how to receive messages by registering a callback function.

int receiveContext = 0;
IoTHubClient_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext);
The article also showed how to free resources using code such as the following.

IoTHubClient_Destroy(iotHubClientHandle);

However there are companion functions to each of these APIs:


IoTHubClient_LL_CreateFromConnectionString
IoTHubClient_LL_SendEventAsync
IoTHubClient_LL_SetMessageCallback
IoTHubClient_LL_Destroy
These functions all include “LL” in the API name. Other than that, the parameters of each of these functions are
identical to their non-LL counterparts. However, the behavior of these functions is different in one important way.
When you call IoTHubClient_CreateFromConnectionString, the underlying libraries create a new thread that
runs in the background. This thread sends events to, and receives messages from, IoT Hub. No such thread is
created when working with the "LL" APIs. The creation of the background thread is a convenience to the
developer. You don’t have to worry about explicitly sending events and receiving messages from IoT Hub -- it
happens automatically in the background. In contrast, the "LL" APIs give you explicit control over communication
with IoT Hub, if you need it.
To understand this better, let’s look at an example:
When you call IoTHubClient_SendEventAsync, what you're actually doing is putting the event in a buffer. The
background thread created when you call IoTHubClient_CreateFromConnectionString continually monitors
this buffer and sends any data that it contains to IoT Hub. This happens in the background at the same time that
the main thread is performing other work.
Similarly, when you register a callback function for messages using IoTHubClient_SetMessageCallback,
you're instructing the SDK to have the background thread invoke the callback function when a message is
received, independent of the main thread.
The "LL" APIs don’t create a background thread. Instead, a new API must be called to explicitly send and receive
data from IoT Hub. This is demonstrated in the following example.
The iothub_client_sample_http application that’s included in the SDK demonstrates the lower-level APIs. In
that sample, we send events to IoT Hub with code such as the following:

EVENT_INSTANCE message;
sprintf_s(msgText, sizeof(msgText), "Message_%d_From_IoTHubClient_LL_Over_HTTP", i);
message.messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText));

IoTHubClient_LL_SendEventAsync(iotHubClientHandle, message.messageHandle, SendConfirmationCallback, &message)

The first three lines create the message, and the last line sends the event. However, as mentioned previously,
"sending" the event means that the data is simply placed in a buffer. Nothing is transmitted on the network when
we call IoTHubClient_LL_SendEventAsync. In order to actually ingress the data to IoT Hub, you must call
IoTHubClient_LL_DoWork, as in this example:

while (1)
{
IoTHubClient_LL_DoWork(iotHubClientHandle);
ThreadAPI_Sleep(1000);
}

This code (from the iothub_client_sample_http application) repeatedly calls IoTHubClient_LL_DoWork. Each
time IoTHubClient_LL_DoWork is called, it sends some events from the buffer to IoT Hub and it retrieves a
queued message being sent to the device. The latter case means that if we registered a callback function for
messages, then the callback is invoked (assuming any messages are queued up). We would have registered such
a callback function with code such as the following:

IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext)

The reason that IoTHubClient_LL_DoWork is often called in a loop is that each time it’s called, it sends some
buffered events to IoT Hub and retrieves the next message queued up for the device. Each call isn’t guaranteed to
send all buffered events or to retrieve all queued messages. If you want to send all events in the buffer and then
continue on with other processing you can replace this loop with code such as the following:

IOTHUB_CLIENT_STATUS status;

while ((IoTHubClient_LL_GetSendStatus(iotHubClientHandle, &status) == IOTHUB_CLIENT_OK) && (status ==


IOTHUB_CLIENT_SEND_STATUS_BUSY))
{
IoTHubClient_LL_DoWork(iotHubClientHandle);
ThreadAPI_Sleep(1000);
}

This code calls IoTHubClient_LL_DoWork until all events in the buffer have been sent to IoT Hub. Note this
does not also imply that all queued messages have been received. Part of the reason for this is that checking for
"all" messages isn’t as deterministic an action. What happens if you retrieve "all" of the messages, but then
another one is sent to the device immediately after? A better way to deal with that is with a programmed
timeout. For example, the message callback function could reset a timer every time it’s invoked. You can then
write logic to continue processing if, for example, no messages have been received in the last X seconds.
When you’re finished ingressing events and receiving messages, be sure to call the corresponding function to
clean up resources.

IoTHubClient_LL_Destroy(iotHubClientHandle);

Basically there’s only one set of APIs to send and receive data with a background thread and another set of APIs
that does the same thing without the background thread. A lot of developers may prefer the non-LL APIs, but the
lower-level APIs are useful when the developer wants explicit control over network transmissions. For example,
some devices collect data over time and only ingress events at specified intervals (for example, once an hour or
once a day). The lower-level APIs give you the ability to explicitly control when you send and receive data from
IoT Hub. Others will simply prefer the simplicity that the lower-level APIs provide. Everything happens on the
main thread rather than some work happening in the background.
Whichever model you choose, be sure to be consistent in which APIs you use. If you start by calling
IoTHubClient_LL_CreateFromConnectionString, be sure you only use the corresponding lower-level APIs
for any follow -up work:
IoTHubClient_LL_SendEventAsync
IoTHubClient_LL_SetMessageCallback
IoTHubClient_LL_Destroy
IoTHubClient_LL_DoWork
The opposite is true as well. If you start with IoTHubClient_CreateFromConnectionString, then use the non-
LL APIs for any additional processing.
In the Azure IoT device SDK for C, see the iothub_client_sample_http application for a complete example of
the lower-level APIs. The iothub_client_sample_amqp application can be referenced for a full example of the
non-LL APIs.

Property handling
So far when we've described sending data, we've been referring to the body of the message. For example,
consider this code:

EVENT_INSTANCE message;
sprintf_s(msgText, sizeof(msgText), "Hello World");
message.messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText));
IoTHubClient_LL_SendEventAsync(iotHubClientHandle, message.messageHandle, SendConfirmationCallback, &message)

This example sends a message to IoT Hub with the text "Hello World." However, IoT Hub also allows properties
to be attached to each message. Properties are name/value pairs that can be attached to the message. For
example, we can modify the previous code to attach a property to the message:

MAP_HANDLE propMap = IoTHubMessage_Properties(message.messageHandle);


sprintf_s(propText, sizeof(propText), "%d", i);
Map_AddOrUpdate(propMap, "SequenceNumber", propText);

We start by calling IoTHubMessage_Properties and passing it the handle of our message. What we get back is
a MAP_HANDLE reference that enables us to start adding properties. The latter is accomplished by calling
Map_AddOrUpdate, which takes a reference to a MAP_HANDLE, the property name, and the property value.
With this API we can add as many properties as we like.
When the event is read from Event Hubs, the receiver can enumerate the properties and retrieve their
corresponding values. For example, in .NET this would be accomplished by accessing the Properties collection on
the EventData object.
In the previous example, we’re attaching properties to an event that we send to IoT Hub. Properties can also be
attached to messages received from IoT Hub. If we want to retrieve properties from a message, we can use code
such as the following in our message callback function:
static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, void*
userContextCallback)
{
. . .

// Retrieve properties from the message


MAP_HANDLE mapProperties = IoTHubMessage_Properties(message);
if (mapProperties != NULL)
{
const char*const* keys;
const char*const* values;
size_t propertyCount = 0;
if (Map_GetInternals(mapProperties, &keys, &values, &propertyCount) == MAP_OK)
{
if (propertyCount > 0)
{
printf("Message Properties:\r\n");
for (size_t index = 0; index < propertyCount; index++)
{
printf("\tKey: %s Value: %s\r\n", keys[index], values[index]);
}
printf("\r\n");
}
}
}

. . .
}

The call to IoTHubMessage_Properties returns the MAP_HANDLE reference. We then pass that reference to
Map_GetInternals to obtain a reference to an array of the name/value pairs (as well as a count of the
properties). At that point it's a simple matter of enumerating the properties to get to the values we want.
You don't have to use properties in your application. However, if you need to set them on events or retrieve them
from messages, the IoTHubClient library makes it easy.

Message handling
As stated previously, when messages arrive from IoT Hub the IoTHubClient library responds by invoking a
registered callback function. There is a return parameter of this function that deserves some additional
explanation. Here’s an excerpt of the callback function in the iothub_client_sample_http sample application:

static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, void*


userContextCallback)
{
. . .
return IOTHUBMESSAGE_ACCEPTED;
}

Note that the return type is IOTHUBMESSAGE_DISPOSITION_RESULT and in this particular case we return
IOTHUBMESSAGE_ACCEPTED. There are other values we can return from this function that change how the
IoTHubClient library reacts to the message callback. Here are the options.
IOTHUBMESSAGE_ACCEPTED – The message has been processed successfully. The IoTHubClient
library will not invoke the callback function again with the same message.
IOTHUBMESSAGE_REJECTED – The message was not processed and there is no desire to do so in the
future. The IoTHubClient library should not invoke the callback function again with the same message.
IOTHUBMESSAGE_ABANDONED – The message was not processed successfully, but the IoTHubClient
library should invoke the callback function again with the same message.
For the first two return codes, the IoTHubClient library sends a message to IoT Hub indicating that the
message should be deleted from the device queue and not delivered again. The net effect is the same (the
message is deleted from the device queue), but whether the message was accepted or rejected is still recorded.
Recording this distinction is useful to senders of the message who can listen for feedback and find out if a device
has accepted or rejected a particular message.
In the last case a message is also sent to IoT Hub, but it indicates that the message should be redelivered.
Typically you’ll abandon a message if you encounter some error but want to try to process the message again. In
contrast, rejecting a message is appropriate when you encounter an unrecoverable error (or if you simply decide
you don’t want to process the message).
In any case, be aware of the different return codes so that you can elicit the behavior you want from the
IoTHubClient library.

Alternate device credentials


As explained previously, the first thing to do when working with the IoTHubClient library is to obtain a
IOTHUB_CLIENT_HANDLE with a call such as the following:

IOTHUB_CLIENT_HANDLE iotHubClientHandle;
iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, AMQP_Protocol);

The arguments to IoTHubClient_CreateFromConnectionString are the device connection string and a


parameter that indicates the protocol we use to communicate with IoT Hub. The device connection string has a
format that appears as follows:

HostName=IOTHUBNAME.IOTHUBSUFFIX;DeviceId=DEVICEID;SharedAccessKey=SHAREDACCESSKEY

There are four pieces of information in this string: IoT Hub name, IoT Hub suffix, device ID, and shared access
key. You obtain the fully qualified domain name (FQDN ) of an IoT hub when you create your IoT hub instance in
the Azure portal — this gives you the IoT hub name (the first part of the FQDN ) and the IoT hub suffix (the rest
of the FQDN ). You get the device ID and the shared access key when you register your device with IoT Hub (as
described in the previous article).
IoTHubClient_CreateFromConnectionString gives you one way to initialize the library. If you prefer, you can
create a new IOTHUB_CLIENT_HANDLE by using these individual parameters rather than the device
connection string. This is achieved with the following code:

IOTHUB_CLIENT_CONFIG iotHubClientConfig;
iotHubClientConfig.iotHubName = "";
iotHubClientConfig.deviceId = "";
iotHubClientConfig.deviceKey = "";
iotHubClientConfig.iotHubSuffix = "";
iotHubClientConfig.protocol = HTTP_Protocol;
IOTHUB_CLIENT_HANDLE iotHubClientHandle = IoTHubClient_LL_Create(&iotHubClientConfig);

This accomplishes the same thing as IoTHubClient_CreateFromConnectionString.


It may seem obvious that you would want to use IoTHubClient_CreateFromConnectionString rather than
this more verbose method of initialization. Keep in mind, however, that when you register a device in IoT Hub
what you get is a device ID and device key (not a connection string). The device explorer SDK tool introduced in
the previous article uses libraries in the Azure IoT service SDK to create the device connection string from the
device ID, device key, and IoT Hub host name. So calling IoTHubClient_LL_Create may be preferable because it
saves you the step of generating a connection string. Use whichever method is convenient.
Configuration options
So far everything described about the way the IoTHubClient library works reflects its default behavior.
However, there are a few options that you can set to change how the library works. This is accomplished by
leveraging the IoTHubClient_LL_SetOption API. Consider this example:

unsigned int timeout = 30000;


IoTHubClient_LL_SetOption(iotHubClientHandle, "timeout", &timeout);

There are a couple of options that are commonly used:


SetBatching (bool) – If true, then data sent to IoT Hub is sent in batches. If false, then messages are sent
individually. The default is false. Note that the SetBatching option only applies to the HTTPS protocol and
not to the MQTT or AMQP protocols.
Timeout (unsigned int) – This value is represented in milliseconds. If sending an HTTPS request or receiving
a response takes longer than this time, then the connection times out.
The batching option is important. By default, the library ingresses events individually (a single event is whatever
you pass to IoTHubClient_LL_SendEventAsync). If the batching option is true, the library collects as many
events as it can from the buffer (up to the maximum message size that IoT Hub will accept). The event batch is
sent to IoT Hub in a single HTTPS call (the individual events are bundled into a JSON array). Enabling batching
typically results in big performance gains since you’re reducing network round-trips. It also significantly reduces
bandwidth since you are sending one set of HTTPS headers with an event batch rather than a set of headers for
each individual event. Unless you have a specific reason to do otherwise, typically you’ll want to enable batching.

Next steps
This article describes in detail the behavior of the IoTHubClient library found in the Azure IoT device SDK
for C. With this information, you should have a good understanding of the capabilities of the IoTHubClient
library. The next article provides similar detail on the serializer library.
To learn more about developing for IoT Hub, see the Azure IoT SDKs.
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Azure IoT device SDK for C – more about serializer
5/29/2018 • 21 min to read • Edit Online

The first article in this series introduced the Azure IoT device SDK for C. The next article provided a more
detailed description of the IoTHubClient. This article completes coverage of the SDK by providing a more
detailed description of the remaining component: the serializer library.

NOTE
Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are
only available in the standard tier of IoT hub. For more information about the basic and standard IoT Hub tiers, see How to
choose the right IoT Hub tier.

The introductory article described how to use the serializer library to send events to and receive messages from
IoT Hub. In this article, we extend that discussion by providing a more complete explanation of how to model your
data with the serializer macro language. The article also includes more detail about how the library serializes
messages (and in some cases how you can control the serialization behavior). We'll also describe some parameters
you can modify that determine the size of the models you create.
Finally, the article revisits some topics covered in previous articles such as message and property handling. As
we'll find out, those features work in the same way using the serializer library as they do with the IoTHubClient
library.
Everything described in this article is based on the serializer SDK samples. If you want to follow along, see the
simplesample_amqp and simplesample_http applications included in the Azure IoT device SDK for C.
You can find the Azure IoT device SDK for C GitHub repository and view details of the API in the C API
reference.

The modeling language


The introductory article in this series introduced the Azure IoT device SDK for C modeling language through
the example provided in the simplesample_amqp application:

BEGIN_NAMESPACE(WeatherStation);

DECLARE_MODEL(ContosoAnemometer,
WITH_DATA(ascii_char_ptr, DeviceId),
WITH_DATA(double, WindSpeed),
WITH_ACTION(TurnFanOn),
WITH_ACTION(TurnFanOff),
WITH_ACTION(SetAirResistance, int, Position)
);

END_NAMESPACE(WeatherStation);

As you can see, the modeling language is based on C macros. You always begin your definition with
BEGIN_NAMESPACE and always end with END_NAMESPACE. It's common to name the namespace for your
company or, as in this example, the project that you're working on.
What goes inside the namespace are model definitions. In this case, there is a single model for an anemometer.
Once again, the model can be named anything, but typically this is named for the device or type of data you want
to exchange with IoT Hub.
Models contain a definition of the events you can ingress to IoT Hub (the data) as well as the messages you can
receive from IoT Hub (the actions). As you can see from the example, events have a type and a name; actions have
a name and optional parameters (each with a type).
What’s not demonstrated in this sample are additional data types that are supported by the SDK. We'll cover that
next.

NOTE
IoT Hub refers to the data a device sends to it as events, while the modeling language refers to it as data (defined using
WITH_DATA). Likewise, IoT Hub refers to the data you send to devices as messages, while the modeling language refers to
it as actions (defined using WITH_ACTION). Be aware that these terms may be used interchangeably in this article.

Supported data types


The following data types are supported in models created with the serializer library:

TYPE DESCRIPTION

double double precision floating point number

int 32 bit integer

float single precision floating point number

long long integer

int8_t 8 bit integer

int16_t 16 bit integer

int32_t 32 bit integer

int64_t 64 bit integer

bool boolean

ascii_char_ptr ASCII string

EDM_DATE_TIME_OFFSET date time offset

EDM_GUID GUID

EDM_BINARY binary

DECLARE_STRUCT complex data type

Let’s start with the last data type. The DECLARE_STRUCT allows you to define complex data types, which are
groupings of the other primitive types. These groupings allow us to define a model that looks like this:
DECLARE_STRUCT(TestType,
double, aDouble,
int, aInt,
float, aFloat,
long, aLong,
int8_t, aInt8,
uint8_t, auInt8,
int16_t, aInt16,
int32_t, aInt32,
int64_t, aInt64,
bool, aBool,
ascii_char_ptr, aAsciiCharPtr,
EDM_DATE_TIME_OFFSET, aDateTimeOffset,
EDM_GUID, aGuid,
EDM_BINARY, aBinary
);

DECLARE_MODEL(TestModel,
WITH_DATA(TestType, Test)
);

Our model contains a single data event of type TestType. TestType is a complex type that includes several
members, which collectively demonstrate the primitive types supported by the serializer modeling language.
With a model like this, we can write code to send data to IoT Hub that appears as follows:

TestModel* testModel = CREATE_MODEL_INSTANCE(MyThermostat, TestModel);

testModel->Test.aDouble = 1.1;
testModel->Test.aInt = 2;
testModel->Test.aFloat = 3.0f;
testModel->Test.aLong = 4;
testModel->Test.aInt8 = 5;
testModel->Test.auInt8 = 6;
testModel->Test.aInt16 = 7;
testModel->Test.aInt32 = 8;
testModel->Test.aInt64 = 9;
testModel->Test.aBool = true;
testModel->Test.aAsciiCharPtr = "ascii string 1";

time_t now;
time(&now);
testModel->Test.aDateTimeOffset = GetDateTimeOffset(now);

EDM_GUID guid = { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
0x0F } };
testModel->Test.aGuid = guid;

unsigned char binaryArray[3] = { 0x01, 0x02, 0x03 };


EDM_BINARY binaryData = { sizeof(binaryArray), &binaryArray };
testModel->Test.aBinary = binaryData;

SendAsync(iotHubClientHandle, (const void*)&(testModel->Test));

Basically, we’re assigning a value to every member of the Test structure and then calling SendAsync to send the
Test data event to the cloud. SendAsync is a helper function that sends a single data event to IoT Hub:
void SendAsync(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, const void *dataEvent)
{
unsigned char* destination;
size_t destinationSize;
if (SERIALIZE(&destination, &destinationSize, *(const unsigned char*)dataEvent) ==
{
// null terminate the string
char* destinationAsString = (char*)malloc(destinationSize + 1);
if (destinationAsString != NULL)
{
memcpy(destinationAsString, destination, destinationSize);
destinationAsString[destinationSize] = '\0';
IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromString(destinationAsString);
if (messageHandle != NULL)
{
IoTHubClient_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, (void*)0);

IoTHubMessage_Destroy(messageHandle);
}
free(destinationAsString);
}
free(destination);
}
}

This function serializes the given data event and sends it to IoT Hub using IoTHubClient_SendEventAsync. This
is the same code discussed in previous articles (SendAsync encapsulates the logic into a convenient function).
One other helper function used in the previous code is GetDateTimeOffset. This function transforms the given
time into a value of type EDM_DATE_TIME_OFFSET:

EDM_DATE_TIME_OFFSET GetDateTimeOffset(time_t time)


{
struct tm newTime;
gmtime_s(&newTime, &time);
EDM_DATE_TIME_OFFSET dateTimeOffset;
dateTimeOffset.dateTime = newTime;
dateTimeOffset.fractionalSecond = 0;
dateTimeOffset.hasFractionalSecond = 0;
dateTimeOffset.hasTimeZone = 0;
dateTimeOffset.timeZoneHour = 0;
dateTimeOffset.timeZoneMinute = 0;
return dateTimeOffset;
}

If you run this code, the following message is sent to IoT Hub:

{"aDouble":1.100000000000000, "aInt":2, "aFloat":3.000000, "aLong":4, "aInt8":5, "auInt8":6, "aInt16":7,


"aInt32":8, "aInt64":9, "aBool":true, "aAsciiCharPtr":"ascii string 1", "aDateTimeOffset":"2015-09-
14T21:18:21Z", "aGuid":"00010203-0405-0607-0809-0A0B0C0D0E0F", "aBinary":"AQID"}

Note that the serialization is JSON, which is the format generated by the serializer library. Also note that each
member of the serialized JSON object matches the members of the TestType that we defined in our model. The
values also exactly match those used in the code. However, note that the binary data is base64-encoded: "AQID" is
the base64 encoding of {0x01, 0x02, 0x03}.
This example demonstrates the advantage of using the serializer library -- it enables us to send JSON to the
cloud, without having to explicitly deal with serialization in our application. All we have to worry about is setting
the values of the data events in our model and then calling simple APIs to send those events to the cloud.
With this information, we can define models that include the range of supported data types, including complex
types (we could even include complex types within other complex types). However, he serialized JSON generated
by the example above brings up an important point. How we send data with the serializer library determines
exactly how the JSON is formed. That particular point is what we'll cover next.

More about serialization


The previous section highlights an example of the output generated by the serializer library. In this section, we'll
explain how the library serializes data and how you can control that behavior using the serialization APIs.
In order to advance the discussion on serialization, we'll work with a new model based on a thermostat. First, let's
provide some background on the scenario we're trying to address.
We want to model a thermostat that measures temperature and humidity. Each piece of data is going to be sent to
IoT Hub differently. By default, the thermostat ingresses a temperature event once every 2 minutes; a humidity
event is ingressed once every 15 minutes. When either event is ingressed, it must include a timestamp that shows
the time that the corresponding temperature or humidity was measured.
Given this scenario, we'll demonstrate two different ways to model the data, and we'll explain the effect that
modeling has on the serialized output.
Model 1
Here's the first version of a model that supports the previous scenario:

BEGIN_NAMESPACE(Contoso);

DECLARE_STRUCT(TemperatureEvent,
int, Temperature,
EDM_DATE_TIME_OFFSET, Time);

DECLARE_STRUCT(HumidityEvent,
int, Humidity,
EDM_DATE_TIME_OFFSET, Time);

DECLARE_MODEL(Thermostat,
WITH_DATA(TemperatureEvent, Temperature),
WITH_DATA(HumidityEvent, Humidity)
);

END_NAMESPACE(Contoso);

Note that the model includes two data events: Temperature and Humidity. Unlike previous examples, the type of
each event is a structure defined using DECLARE_STRUCT. TemperatureEvent includes a temperature
measurement and a timestamp; HumidityEvent contains a humidity measurement and a timestamp. This model
gives us a natural way to model the data for the scenario described above. When we send an event to the cloud,
we'll either send a temperature/timestamp or a humidity/timestamp pair.
We can send a temperature event to the cloud using code such as the following:
time_t now;
time(&now);
thermostat->Temperature.Temperature = 75;
thermostat->Temperature.Time = GetDateTimeOffset(now);

unsigned char* destination;


size_t destinationSize;
if (SERIALIZE(&destination, &destinationSize, thermostat->Temperature) == IOT_AGENT_OK)
{
sendMessage(iotHubClientHandle, destination, destinationSize);
}

We'll use hard-coded values for temperature and humidity in the sample code, but imagine that we’re actually
retrieving these values by sampling the corresponding sensors on the thermostat.
The code above uses the GetDateTimeOffset helper that was introduced previously. For reasons that will
become clear later, this code explicitly separates the task of serializing and sending the event. The previous code
serializes the temperature event into a buffer. Then, sendMessage is a helper function (included in
simplesample_amqp) that sends the event to IoT Hub:

static void sendMessage(IOTHUB_CLIENT_HANDLE iotHubClientHandle, const unsigned char* buffer, size_t size)
{
static unsigned int messageTrackingId;
IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromByteArray(buffer, size);
if (messageHandle != NULL)
{
IoTHubClient_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, (void*)
(uintptr_t)messageTrackingId);

IoTHubMessage_Destroy(messageHandle);
}
free((void*)buffer);
}

This code is a subset of the SendAsync helper described in the previous section, so we won’t go over it again
here.
When we run the previous code to send the Temperature event, this serialized form of the event is sent to IoT Hub:

{"Temperature":75, "Time":"2015-09-17T18:45:56Z"}

We're sending a temperature which is of type TemperatureEvent and that struct contains a Temperature and
Time member. This is directly reflected in the serialized data.
Similarly, we can send a humidity event with this code:

thermostat->Humidity.Humidity = 45;
thermostat->Humidity.Time = GetDateTimeOffset(now);
if (SERIALIZE(&destination, &destinationSize, thermostat->Humidity) == IOT_AGENT_OK)
{
sendMessage(iotHubClientHandle, destination, destinationSize);
}

The serialized form that’s sent to IoT Hub appears as follows:

{"Humidity":45, "Time":"2015-09-17T18:45:56Z"}
Again, this is as expected.
With this model, you can imagine how additional events can easily be added. You define more structures using
DECLARE_STRUCT, and include the corresponding event in the model using WITH_DATA.
Now, let’s modify the model so that it includes the same data but with a different structure.
Model 2
Consider this alternative model to the one above:

DECLARE_MODEL(Thermostat,
WITH_DATA(int, Temperature),
WITH_DATA(int, Humidity),
WITH_DATA(EDM_DATE_TIME_OFFSET, Time)
);

In this case we've eliminated the DECLARE_STRUCT macros and are simply defining the data items from our
scenario using simple types from the modeling language.
Just for the moment let’s ignore the Time event. With that aside, here’s the code to ingress Temperature:

time_t now;
time(&now);
thermostat->Temperature = 75;

unsigned char* destination;


size_t destinationSize;
if (SERIALIZE(&destination, &destinationSize, thermostat->Temperature) == IOT_AGENT_OK)
{
sendMessage(iotHubClientHandle, destination, destinationSize);
}

This code sends the following serialized event to IoT Hub:

{"Temperature":75}

And the code for sending the Humidity event appears as follows:

thermostat->Humidity = 45;
if (SERIALIZE(&destination, &destinationSize, thermostat->Humidity) == IOT_AGENT_OK)
{
sendMessage(iotHubClientHandle, destination, destinationSize);
}

This code sends this to IoT Hub:

{"Humidity":45}

So far there are still no surprises. Now let's change how we use the SERIALIZE macro.
The SERIALIZE macro can take multiple data events as arguments. This enables us to serialize the Temperature
and Humidity event together and send them to IoT Hub in one call:
if (SERIALIZE(&destination, &destinationSize, thermostat->Temperature, thermostat->Humidity) == IOT_AGENT_OK)
{
sendMessage(iotHubClientHandle, destination, destinationSize);
}

You might guess that the result of this code is that two data events are sent to IoT Hub:
[
{"Temperature":75},
{"Humidity":45}
]
In other words, you might expect that this code is the same as sending Temperature and Humidity separately.
It’s just a convenience to pass both events to SERIALIZE in the same call. However, that’s not the case. Instead, the
code above sends this single data event to IoT Hub:
{"Temperature":75, "Humidity":45}
This may seem strange because our model defines Temperature and Humidity as two separate events:

DECLARE_MODEL(Thermostat,
WITH_DATA(int, Temperature),
WITH_DATA(int, Humidity),
WITH_DATA(EDM_DATE_TIME_OFFSET, Time)
);

More to the point, we didn’t model these events where Temperature and Humidity are in the same structure:

DECLARE_STRUCT(TemperatureAndHumidityEvent,
int, Temperature,
int, Humidity,
);

DECLARE_MODEL(Thermostat,
WITH_DATA(TemperatureAndHumidityEvent, TemperatureAndHumidity),
);

If we used this model, it would be easier to understand how Temperature and Humidity would be sent in the
same serialized message. However it may not be clear why it works that way when you pass both data events to
SERIALIZE using model 2.
This behavior is easier to understand if you know the assumptions that the serializer library is making. To make
sense of this let’s go back to our model:

DECLARE_MODEL(Thermostat,
WITH_DATA(int, Temperature),
WITH_DATA(int, Humidity),
WITH_DATA(EDM_DATE_TIME_OFFSET, Time)
);

Think of this model in object-oriented terms. In this case we’re modeling a physical device (a thermostat) and that
device includes attributes like Temperature and Humidity.
We can send the entire state of our model with code such as the following:
if (SERIALIZE(&destination, &destinationSize, thermostat->Temperature, thermostat->Humidity, thermostat->Time)
== IOT_AGENT_OK)
{
sendMessage(iotHubClientHandle, destination, destinationSize);
}

Assuming the values of Temperature, Humidity and Time are set, we would see an event like this sent to IoT Hub:

{"Temperature":75, "Humidity":45, "Time":"2015-09-17T18:45:56Z"}

Sometimes you may only want to send some properties of the model to the cloud (this is especially true if your
model contains a large number of data events). It’s useful to send only a subset of data events, such as in our
earlier example:

{"Temperature":75, "Time":"2015-09-17T18:45:56Z"}

This generates exactly the same serialized event as if we had defined a TemperatureEvent with a Temperature
and Time member, just as we did with model 1. In this case we were able to generate exactly the same serialized
event by using a different model (model 2) because we called SERIALIZE in a different way.
The important point is that if you pass multiple data events to SERIALIZE, then it assumes each event is a
property in a single JSON object.
The best approach depends on you and how you think about your model. If you’re sending "events" to the cloud
and each event contains a defined set of properties, then the first approach makes a lot of sense. In that case you
would use DECLARE_STRUCT to define the structure of each event and then include them in your model with
the WITH_DATA macro. Then you send each event as we did in the first example above. In this approach you
would only pass a single data event to SERIALIZER.
If you think about your model in an object-oriented fashion, then the second approach may suit you. In this case,
the elements defined using WITH_DATA are the "properties" of your object. You pass whatever subset of events
to SERIALIZE that you like, depending on how much of your "object’s" state you want to send to the cloud.
Nether approach is right or wrong. Just be aware of how the serializer library works, and pick the modeling
approach that best fits your needs.

Message handling
So far this article has only discussed sending events to IoT Hub, and hasn't addressed receiving messages. The
reason for this is that what we need to know about receiving messages has largely been covered in an earlier
article. Recall from that article that you process messages by registering a message callback function:

IoTHubClient_SetMessageCallback(iotHubClientHandle, IoTHubMessage, myWeather)

You then write the callback function that’s invoked when a message is received:
static IOTHUBMESSAGE_DISPOSITION_RESULT IoTHubMessage(IOTHUB_MESSAGE_HANDLE message, void*
userContextCallback)
{
IOTHUBMESSAGE_DISPOSITION_RESULT result;
const unsigned char* buffer;
size_t size;
if (IoTHubMessage_GetByteArray(message, &buffer, &size) != IOTHUB_MESSAGE_OK)
{
printf("unable to IoTHubMessage_GetByteArray\r\n");
result = EXECUTE_COMMAND_ERROR;
}
else
{
/*buffer is not zero terminated*/
char* temp = malloc(size + 1);
if (temp == NULL)
{
printf("failed to malloc\r\n");
result = EXECUTE_COMMAND_ERROR;
}
else
{
memcpy(temp, buffer, size);
temp[size] = '\0';
EXECUTE_COMMAND_RESULT executeCommandResult = EXECUTE_COMMAND(userContextCallback, temp);
result =
(executeCommandResult == EXECUTE_COMMAND_ERROR) ? IOTHUBMESSAGE_ABANDONED :
(executeCommandResult == EXECUTE_COMMAND_SUCCESS) ? IOTHUBMESSAGE_ACCEPTED :
IOTHUBMESSAGE_REJECTED;
free(temp);
}
}
return result;
}

This implementation of IoTHubMessage calls the specific function for each action in your model. For example, if
your model defines this action:

WITH_ACTION(SetAirResistance, int, Position)

You must define a function with this signature:

EXECUTE_COMMAND_RESULT SetAirResistance(ContosoAnemometer* device, int Position)


{
(void)device;
(void)printf("Setting Air Resistance Position to %d.\r\n", Position);
return EXECUTE_COMMAND_SUCCESS;
}

SetAirResistance is then called when that message is sent to your device.


What we haven't explained yet is what the serialized version of message looks like. In other words, if you want to
send a SetAirResistance message to your device, what does that look like?
If you're sending a message to a device, you would do so through the Azure IoT service SDK. You still need to
know what string to send to invoke a particular action. The general format for sending a message appears as
follows:

{"Name" : "", "Parameters" : "" }


You're sending a serialized JSON object with two properties: Name is the name of the action (message) and
Parameters contains the parameters of that action.
For example, to invoke SetAirResistance you can send this message to a device:

{"Name" : "SetAirResistance", "Parameters" : { "Position" : 5 }}

The action name must exactly match an action defined in your model. The parameter names must match as well.
Also note case sensitivity. Name and Parameters are always uppercase. Make sure to match the case of your
action name and parameters in your model. In this example, the action name is "SetAirResistance" and not
"setairresistance".
The two other actions TurnFanOn and TurnFanOff can be invoked by sending these messages to a device:

{"Name" : "TurnFanOn", "Parameters" : {}}


{"Name" : "TurnFanOff", "Parameters" : {}}

This section described everything you need to know when sending events and receiving messages with the
serializer library. Before moving on, let's cover some parameters you can configure that control how large your
model is.

Macro configuration
If you’re using the Serializer library an important part of the SDK to be aware of is found in the azure-c-shared-
utility library. If you have cloned the Azure-iot-sdk-c repository from GitHub using the --recursive option, then you
will find this shared utility library here:

.\\c-utility

If you have not cloned the library, you can find it here.
Within the shared utility library, you will find the following folder:

azure-c-shared-utility\\macro\_utils\_h\_generator.

This folder contains a Visual Studio solution called macro_utils_h_generator.sln:

The program in this solution generates the macro_utils.h file. There’s a default macro_utils.h file included with the
SDK. This solution allows you to modify some parameters and then recreate the header file based on these
parameters.
The two key parameters to be concerned with are nArithmetic and nMacroParameters which are defined in
these two lines found in macro_utils.tt:
<#int nArithmetic=1024;#>
<#int nMacroParameters=124;/*127 parameters in one macro definition in C99 in chapter 5.2.4.1 Translation
limits*/#>

These values are the default parameters included with the SDK. Each parameter has the following meaning:
nMacroParameters – Controls how many parameters you can have in one DECL ARE_MODEL macro
definition.
nArithmetic – Controls the total number of members allowed in a model.
The reason these parameters are important is because they control how large your model can be. For example,
consider this model definition:

DECLARE_MODEL(MyModel,
WITH_DATA(int, MyData)
);

As mentioned previously, DECLARE_MODEL is just a C macro. The names of the model and the WITH_DATA
statement (yet another macro) are parameters of DECLARE_MODEL. nMacroParameters defines how many
parameters can be included in DECLARE_MODEL. Effectively, this defines how many data event and action
declarations you can have. As such, with the default limit of 124 this means that you can define a model with a
combination of about 60 actions and data events. If you try to exceed this limit, you'll receive compiler errors that
look similar to this:

The nArithmetic parameter is more about the internal workings of the macro language than your application. It
controls the total number of members you can have in your model, including DECLARE_STRUCT macros. If you
start seeing compiler errors such as this, then you should try increasing nArithmetic:

If you want to change these parameters, modify the values in the macro_utils.tt file, recompile the
macro_utils_h_generator.sln solution, and run the compiled program. When you do so, a new macro_utils.h file is
generated and placed in the .\common\inc directory.
In order to use the new version of macro_utils.h, remove the serializer NuGet package from your solution and in
its place include the serializer Visual Studio project. This enables your code to compile against the source code of
the serializer library. This includes the updated macro_utils.h. If you want to do this for simplesample_amqp,
start by removing the NuGet package for the serializer library from the solution:
Then add this project to your Visual Studio solution:

.\c\serializer\build\windows\serializer.vcxproj

When you're done, your solution should look like this:

Now when you compile your solution, the updated macro_utils.h is included in your binary.
Note that increasing these values high enough can exceed compiler limits. To this point, the nMacroParameters is
the main parameter with which to be concerned. The C99 spec specifies that a minimum of 127 parameters are
allowed in a macro definition. The Microsoft compiler follows the spec exactly (and has a limit of 127), so you
won't be able to increase nMacroParameters beyond the default. Other compilers might allow you to do so (for
example, the GNU compiler supports a higher limit).
So far we've covered just about everything you need to know about how to write code with the serializer library.
Before concluding, let's revisit some topics from previous articles that you may be wondering about.

The lower-level APIs


The sample application on which this article focused is simplesample_amqp. This sample uses the higher-level
(the non-"LL") APIs to send events and receive messages. If you use these APIs, a background thread runs which
takes care of both sending events and receiving messages. However, you can use the lower-level (LL ) APIs to
eliminate this background thread and take explicit control over when you send events or receive messages from
the cloud.
As described in a previous article, there is a set of functions that consists of the higher-level APIs:
IoTHubClient_CreateFromConnectionString
IoTHubClient_SendEventAsync
IoTHubClient_SetMessageCallback
IoTHubClient_Destroy
These APIs are demonstrated in simplesample_amqp.
There is also an analogous set of lower-level APIs.
IoTHubClient_LL_CreateFromConnectionString
IoTHubClient_LL_SendEventAsync
IoTHubClient_LL_SetMessageCallback
IoTHubClient_LL_Destroy
Note that the lower-level APIs work exactly the same way as described in the previous articles. You can use the
first set of APIs if you want a background thread to handle sending events and receiving messages. You use the
second set of APIs if you want explicit control over when you send and receive data from IoT Hub. Either set of
APIs work equally well with the serializer library.
For an example of how the lower-level APIs are used with the serializer library, see the simplesample_http
application.

Additional topics
A few other topics worth mentioning again are property handling, using alternate device credentials, and
configuration options. These are all topics covered in a previous article. The main point is that all of these features
work in the same way with the serializer library as they do with the IoTHubClient library. For example, if you
want to attach properties to an event from your model, you use IoTHubMessage_Properties and
Map_AddorUpdate, the same way as described previously:

MAP_HANDLE propMap = IoTHubMessage_Properties(message.messageHandle);


sprintf_s(propText, sizeof(propText), "%d", i);
Map_AddOrUpdate(propMap, "SequenceNumber", propText);

Whether the event was generated from the serializer library or created manually using the IoTHubClient library
does not matter.
For the alternate device credentials, using IoTHubClient_LL_Create works just as well as
IoTHubClient_CreateFromConnectionString for allocating an IOTHUB_CLIENT_HANDLE.
Finally, if you're using the serializer library, you can set configuration options with IoTHubClient_LL_SetOption
just as you did when using the IoTHubClient library.
A feature that is unique to the serializer library are the initialization APIs. Before you can start working with the
library, you must call serializer_init:

serializer_init(NULL);
This is done just before you call IoTHubClient_CreateFromConnectionString.
Similarly, when you're done working with the library, the last call you’ll make is to serializer_deinit:

serializer_deinit();

Otherwise, all of the other features listed above work the same in the serializer library as they do in the
IoTHubClient library. For more information about any of these topics, see the previous article in this series.

Next steps
This article describes in detail the unique aspects of the serializer library contained in the Azure IoT device SDK
for C. With the information provided you should have a good understanding of how to use models to send events
and receive messages from IoT Hub.
This also concludes the three-part series on how to develop applications with the Azure IoT device SDK for C.
This should be enough information to not only get you started but give you a thorough understanding of how the
APIs work. For additional information, there are a few samples in the SDK not covered here. Otherwise, the SDK
documentation is a good resource for additional information.
To learn more about developing for IoT Hub, see the Azure IoT SDKs.
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Develop for constrained devices using Azure IoT
SDKs
5/25/2018 • 3 min to read • Edit Online

Develop using Azure IoT Hub C SDK


Azure IoT Hub C SDK is written in ANSI C (C99), which makes it well-suited to operate a variety of platforms with
small disk and memory footprint. The recommended RAM is at least 64 KB, but the exact memory footprint
depends on the protocol used, the number of connections opened, as well as the platform targeted.
C SDK is available in package form from apt-get, NuGet, and MBED. To target constrained devices, you may want
to build the SDK locally for your target platform. This documentation demonstrates how to remove certain
features to shrink the footprint of the C SDK using cmake. In addition, this documentation discusses the best
practice programming models for working with constrained devices.
Building the C SDK for constrained devices
Prerequisites
Follow this setup guide to prepare your development environment for building the C SDK. Before you get to the
step for building with cmake, you can invoke cmake flags to remove unused features.
Remove additional protocol libraries
C SDK supports five protocols today: MQTT, MQTT over WebSocket, AMQPs, AMQP over WebSocket, and
HTTPS. Most scenarios require one to two protocols running on a client, hence you can remove the protocol
library you are not using from the SDK. Additional information about choosing the appropriate communication
protocol for your scenario can be found in this document. For example, MQTT is a lightweight protocol that is
often better suited for constrained devices.
You can remove AMQP and HTTP libraries using the following cmake command:

cmake -Duse_amqp=OFF -Duse_http=OFF <Path_to_cmake>

Remove SDK logging capability


The C SDK provides extensive logging throughout to help with debugging. You can remove the logging capability
for production devices using the following cmake command:

cmake -Dno_logging=OFF <Path_to_cmake>

Remove upload to blob capability


You can upload large files to Azure Storage using the built-in capability in the SDK. Azure IoT Hub acts as a
dispatcher to an associated Azure Storage account. You can use this feature to send media files, large telemetry
batches, and logs. Learn more about upload files with IoT Hub in this document. If your application does not
require this functionality, you can remove this feature using the following cmake command:

cmake -Ddont_use_uploadtoblob=ON <Path_to_cmake>

Running strip on Linux environment


If your binaries run on Linux system, you can leverage the strip command to reduce the size of the final application
after compiling.
strip -s <Path_to_executable>

Programming models for constrained devices


Avoid using the Serializer
The C SDK has an optional serializer, which allows you to use declarative mapping tables to define methods and
device twin properties. The serializer is designed to simplify development, but it adds overhead, which is not
optimal for constrained devices. In this case, consider using primitive client APIs and parse json by using a
lightweight parser such as parson.
Use the lower layer (LL)
The C SDK supports two programming models. One set has APIs with an LL infix, which stands for lower layer.
This set of APIs are lighter weight and do not spin up worker threads, which means the user must manually control
scheduling. For example, for the device client, the LL APIs can be found in this header file. Another set of APIs
without the LL index is called the convenience layer, where a worker thread is spun automatically. For example, the
convenience layer APIs for the device client can be found in this header file. For constrained devices where each
extra thread can take a substantial percentage of system resources, consider using LL APIs.

Next steps
To learn more about Azure IoT C SDK architecture:
Azure IoT C SDK source code
Azure IoT device SDK for C introduction
Develop for mobile devices using Azure IoT SDKs
5/29/2018 • 2 min to read • Edit Online

Things in the Internet of Things may refer to a wide range of devices with varying capability: sensors,
microcontrollers, smart devices, industrial gateways, and even mobile devices. A mobile device can be an IoT
device, where it is sending device-to-cloud telemetry and managed by the cloud. It can also be the device running a
back-end service application, which manages other IoT devices. In both cases, Azure IoT Hub SDKs can be used to
develop applications that work for mobile devices.

Develop for native iOS platform


Azure IoT Hub SDKs provide native iOS platform support through Azure IoT Hub C SDK. You can think of it as an
iOS SDK that you can incorporate in your Swift or Objective C XCode project. There are two ways to use the C
SDK on iOS:
Use the CocoaPod libraries in XCode project directly.
Download the source code for C SDK and build for iOS platform following the build instruction for MacOS.
Azure IoT Hub C SDK is written in C99 for maximum portability to various platforms. The porting process
involves writing a thin adoption layer for the platform-specific components, which can be found here for iOS. The
features in the C SDK can be leveraged on iOS platform, including the Azure IoT Hub primitives supported and
SDK-specific features such as retry policy for network reliability. The interface for iOS SDK is also similar to the
interface for Azure IoT Hub C SDK.
These documentations walk through how to develop a device application or service application on an iOS device:
Quickstart: Send telemetry from a device to an IoT hub
Send messages from the cloud to your device with IoT hub
Develop with Azure IoT Hub CocoaPod libraries
Azure IoT Hub SDKs releases a set of Objective-C CocoaPod libraries for iOS development. To see the latest list of
CocoaPod libraries, see CocoaPods for Microsoft Azure IoT. Once the relevant libraries are incorporated into your
XCode project, there are two ways to write IoT Hub related code:
Objective C function: If your project is written in Objective-C, you can call APIs from Azure IoT Hub C SDK
directly. If your project is written in Swift, you can call @objc func before creating your function, and proceed to
writing all logics related to Azure IoT Hub using C or Objective-C code. A set of samples demonstrating both
can be found in the sample repository.
Incorporate C samples: If you have written a C device application, you can reference it directly in your XCode
project:
Add the sample.c file to your XCode project from XCode.
Add the header file to your dependency. A header file is included in the sample repository as example.
For more information, please visit Apple's documentation page for Objective-C.

Next steps
IoT Hub REST API reference
Azure IoT C SDK source code
Query Avro data using Azure Data Lake Analytics
6/1/2018 • 4 min to read • Edit Online

This article is about how to query Avro data for efficiently routing messages from Azure IoT Hub to Azure services.
Following the blog post announcement—Azure IoT Hub message routing: now with routing on message body, IoT
Hub supports routing on either properties or the message body. See also Routing on message bodies.
The challenge has been that when Azure IoT Hub routes messages to blob storage, IoT Hub writes the content in
Avro format, which has both message body and message properties. Note that IoT Hub only supports writing data
to blob storage in the Avro data format, and this format is not used for any other endpoints. See When using Azure
Storage containers. While the Avro format is great for data/message preservation, it's challenging for querying the
data. In comparison, JSON or CSV format is much easier for querying data.
To solve this, you can use many of the big data patterns for both transforming and scaling data to address non-
relational big data needs and formats. One of the patterns, a “pay per query” pattern, is Azure Data Lake Analytics
(ADL A). It is the focus of this article. Though you could easily execute the query in Hadoop or other solutions,
ADL A is often better suited for this “pay per query” approach. There is an “extractor” for Avro in U -SQL. See U -
SQL Avro Example.

Query and export Avro data to a CSV file


The section walks you through querying Avro data and exporting it to a CSV file in Azure Blob Storage, though
you could easily place the data in other repositories or data stores.
1. Set up Azure IoT Hub to route data to an Azure Blob Storage endpoint using a property in the message
body to select messages.
2. Ensure your device has the encoding, the content type, and the needed data in either the properties or the
message body as referenced in the product documentation. When viewed in Device Explorer (see below ),
you can verify that these attributes are set correctly.

3. Set up an Azure Data Lake Store (ADLS ) and an Azure Data Lake Analytics instance. While Azure IoT Hub
does not route to an Azure Data Lake Store, ADL A requires one.
4. In ADL A, configure the Azure Blob Storage as an additional store, the same Blob Storage that Azure IoT
Hub routes data to.

5. As discussed in U -SQL Avro Example, there are 4 DLLs that are needed. Upload these files to a location in
your ADLS.

6. In Visual Studio, create a U -SQL Project


7. Copy the content of the following script and paste it into the newly created file. Modify the 3 highlighted
sections: your ADL A account, the associated DLLs' paths, and the correct path for your Storage Account.

The actual U -SQL script for simple output to CSV:


DROP ASSEMBLY IF EXISTS [Avro];
CREATE ASSEMBLY [Avro] FROM @"/Assemblies/Avro/Avro.dll";
DROP ASSEMBLY IF EXISTS [Microsoft.Analytics.Samples.Formats];
CREATE ASSEMBLY [Microsoft.Analytics.Samples.Formats] FROM
@"/Assemblies/Avro/Microsoft.Analytics.Samples.Formats.dll";
DROP ASSEMBLY IF EXISTS [Newtonsoft.Json];
CREATE ASSEMBLY [Newtonsoft.Json] FROM @"/Assemblies/Avro/Newtonsoft.Json.dll";
DROP ASSEMBLY IF EXISTS [log4net];
CREATE ASSEMBLY [log4net] FROM @"/Assemblies/Avro/log4net.dll";

REFERENCE ASSEMBLY [Newtonsoft.Json];


REFERENCE ASSEMBLY [log4net];
REFERENCE ASSEMBLY [Avro];
REFERENCE ASSEMBLY [Microsoft.Analytics.Samples.Formats];

// Blob container storage account filenames, with any path


DECLARE @input_file string =
@"wasb://hottubrawdata@kevinsayazstorage/kevinsayIoT/{*}/{*}/{*}/{*}/{*}/{*}";
DECLARE @output_file string = @"/output/output.csv";

@rs =
EXTRACT
EnqueuedTimeUtc string,
Body byte[]
FROM @input_file

USING new Microsoft.Analytics.Samples.Formats.ApacheAvro.AvroExtractor(@"


{
""type"":""record"",
""name"":""Message"",
""namespace"":""Microsoft.Azure.Devices"",
""fields"":[{
""name"":""EnqueuedTimeUtc"",
""type"":""string""
},
{
""name"":""Properties"",
""type"":{
""type"":""map"",
""values"":""string""
}
},
{
""name"":""SystemProperties"",
""type"":{
""type"":""map"",
""values"":""string""
}
},
{
""name"":""Body"",
""type"":[""null"",""bytes""]
}
]
}");

@cnt =
SELECT EnqueuedTimeUtc AS time, Encoding.UTF8.GetString(Body) AS jsonmessage
FROM @rs;

OUTPUT @cnt TO @output_file USING Outputters.Text();

Running the script shown below, ADL A took 5 minutes when limited to 10 Analytic Units and processed
177 files, summarizing the output to a CSV file.
Viewing the output, you can see the Avro content has converted to a CSV file. Continue to step 8 if you want
to parse the JSON.

8. Most IoT messages are in JSON format. Adding the following lines, you can parse the message into JSON,
so you can add the WHERE clauses and only output the needed data.
@jsonify = SELECT
Microsoft.Analytics.Samples.Formats.Json.JsonFunctions.JsonTuple(Encoding.UTF8.GetString(Body)) AS
message FROM @rs;

/*
@cnt =
SELECT EnqueuedTimeUtc AS time, Encoding.UTF8.GetString(Body) AS jsonmessage
FROM @rs;

OUTPUT @cnt TO @output_file USING Outputters.Text();


*/

@cnt =
SELECT message["message"] AS iotmessage,
message["event"] AS msgevent,
message["object"] AS msgobject,
message["status"] AS msgstatus,
message["host"] AS msghost
FROM @jsonify;

OUTPUT @cnt TO @output_file USING Outputters.Text();

9. Viewing the output, you now see columns for each item in the select command.

Next steps
In this tutorial, you learned how to query Avro data for efficiently routing messages from Azure IoT Hub to Azure
services.
To see examples of complete end-to-end solutions that use IoT Hub, see Azure IoT Remote Monitoring solution
accelerator.
To learn more about developing solutions with IoT Hub, see the IoT Hub developer guide.
To learn more about message routing in IoT Hub, see Send and receive messages with IoT Hub.
Send messages from the cloud to your device with
IoT Hub (.NET)
5/29/2018 • 6 min to read • Edit Online

Introduction
Azure IoT Hub is a fully managed service that helps enable reliable and secure bi-directional communications
between millions of devices and a solution back end. The Get started with IoT Hub tutorial shows how to
create an IoT hub, provision a device identity in it, and code a device app that sends device-to-cloud messages.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial builds on Get started with IoT Hub. It shows you how to:
From your solution back end, send cloud-to-device messages to a single device through IoT Hub.
Receive cloud-to-device messages on a device.
From your solution back end, request delivery acknowledgement (feedback) for messages sent to a device
from IoT Hub.
You can find more information on cloud-to-device messages in the IoT Hub developer guide.
At the end of this tutorial, you run two .NET console apps:
SimulatedDevice, a modified version of the app created in Get started with IoT Hub, which connects to
your IoT hub and receives cloud-to-device messages.
SendCloudToDevice, which sends a cloud-to-device message to the device app through IoT Hub, and
then receives its delivery acknowledgement.

NOTE
IoT Hub has SDK support for many device platforms and languages (including C, Java, and Javascript) through Azure IoT
device SDKs. For step-by-step instructions on how to connect your device to this tutorial's code, and generally to Azure
IoT Hub, see the IoT Hub developer guide.

To complete this tutorial, you need the following:


Visual Studio 2015 or Visual Studio 2017
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Receive messages in the device app


In this section, you'll modify the device app you created in Get started with IoT Hub to receive cloud-to-device
messages from the IoT hub.
1. In Visual Studio, in the SimulatedDevice project, add the following method to the Program class.
private static async void ReceiveC2dAsync()
{
Console.WriteLine("\nReceiving cloud to device messages from service");
while (true)
{
Message receivedMessage = await deviceClient.ReceiveAsync();
if (receivedMessage == null) continue;

Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Received message: {0}",
Encoding.ASCII.GetString(receivedMessage.GetBytes()));
Console.ResetColor();

await deviceClient.CompleteAsync(receivedMessage);
}
}

The ReceiveAsync method asynchronously returns the received message at the time that it is received
by the device. It returns null after a specifiable timeout period (in this case, the default of one minute is
used). When the app receives a null, it should continue to wait for new messages. This requirement is
the reason for the if (receivedMessage == null) continue line.
The call to CompleteAsync() notifies IoT Hub that the message has been successfully processed. The
message can be safely removed from the device queue. If something happened that prevented the
device app from completing the processing of the message, IoT Hub delivers it again. It is then
important that message processing logic in the device app is idempotent, so that receiving the same
message multiple times produces the same result. An application can also temporarily abandon a
message, which results in IoT hub retaining the message in the queue for future consumption. Or, the
application can reject a message, which permanently removes the message from the queue. For more
information about the cloud-to-device message lifecycle, see the IoT Hub developer guide.

NOTE
When using HTTPS instead of MQTT or AMQP as a transport, the ReceiveAsync method returns immediately.
The supported pattern for cloud-to-device messages with HTTPS is intermittently connected devices that check
for messages infrequently (less than every 25 minutes). Issuing more HTTPS receives results in IoT Hub throttling
the requests. For more information about the differences between MQTT, AMQP and HTTPS support, and IoT
Hub throttling, see the IoT Hub developer guide.

2. Add the following method in the Main method, right before the Console.ReadLine() line:

ReceiveC2dAsync();

NOTE
For simplicity's sake, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Send a cloud-to-device message


In this section, you write a .NET console app that sends cloud-to-device messages to the device app.
1. In the current Visual Studio solution, create a Visual C# Desktop App project by using the Console
Application project template. Name the project SendCloudToDevice.
2. In Solution Explorer, right-click the solution, and then click Manage NuGet Packages for Solution....
This action opens the Manage NuGet Packages window.
3. Search for Microsoft.Azure.Devices, click Install, and accept the terms of use.
This downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package.
4. Add the following using statement at the top of the Program.cs file:

using Microsoft.Azure.Devices;

5. Add the following fields to the Program class. Substitute the placeholder value with the IoT hub
connection string from Get started with IoT Hub:

static ServiceClient serviceClient;


static string connectionString = "{iot hub connection string}";

6. Add the following method to the Program class:

private async static Task SendCloudToDeviceMessageAsync()


{
var commandMessage = new Message(Encoding.ASCII.GetBytes("Cloud to device message."));
await serviceClient.SendAsync("myFirstDevice", commandMessage);
}

This method sends a new cloud-to-device message to the device with the ID, myFirstDevice . Change
this parameter only if you modified it from the one used in Get started with IoT Hub.
7. Finally, add the following lines to the Main method:
Console.WriteLine("Send Cloud-to-Device message\n");
serviceClient = ServiceClient.CreateFromConnectionString(connectionString);

Console.WriteLine("Press any key to send a C2D message.");


Console.ReadLine();
SendCloudToDeviceMessageAsync().Wait();
Console.ReadLine();

8. From within Visual Studio, right-click your solution, and select Set StartUp projects.... Select Multiple
startup projects, then select the Start action for ReadDeviceToCloudMessages, SimulatedDevice, and
SendCloudToDevice.
9. Press F5. All three applications should start. Select the SendCloudToDevice windows, and press
Enter. You should see the message being received by the device app.

Receive delivery feedback


It is possible to request delivery (or expiration) acknowledgements from IoT Hub for each cloud-to-device
message. This option enables the solution back end to easily inform retry or compensation logic. For more
information about cloud-to-device feedback, see the IoT Hub developer guide.
In this section, you modify the SendCloudToDevice app to request feedback, and receive it from IoT Hub.
1. In Visual Studio, in the SendCloudToDevice project, add the following method to the Program class.

private async static void ReceiveFeedbackAsync()


{
var feedbackReceiver = serviceClient.GetFeedbackReceiver();

Console.WriteLine("\nReceiving c2d feedback from service");


while (true)
{
var feedbackBatch = await feedbackReceiver.ReceiveAsync();
if (feedbackBatch == null) continue;

Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Received feedback: {0}", string.Join(", ",
feedbackBatch.Records.Select(f => f.StatusCode)));
Console.ResetColor();

await feedbackReceiver.CompleteAsync(feedbackBatch);
}
}

Note this receive pattern is the same one used to receive cloud-to-device messages from the device app.
2. Add the following method in the Main method, right after the
serviceClient = ServiceClient.CreateFromConnectionString(connectionString) line:
ReceiveFeedbackAsync();

3. To request feedback for the delivery of your cloud-to-device message, you have to specify a property in
the SendCloudToDeviceMessageAsync method. Add the following line, right after the
var commandMessage = new Message(...); line:

commandMessage.Ack = DeliveryAcknowledgement.Full;

4. Run the apps by pressing F5. You should see all three applications start. Select the
SendCloudToDevice windows, and press Enter. You should see the message being received by the
device app, and after a few seconds, the feedback message being received by your
SendCloudToDevice application.

NOTE
For simplicity's sake, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Next steps
In this tutorial, you learned how to send and receive cloud-to-device messages.
To see examples of complete end-to-end solutions that use IoT Hub, see Azure IoT Remote Monitoring
solution accelerator.
To learn more about developing solutions with IoT Hub, see the IoT Hub developer guide.
Send cloud-to-device messages with IoT Hub (Java)
6/6/2018 • 5 min to read • Edit Online

Azure IoT Hub is a fully managed service that helps enable reliable and secure bi-directional communications
between millions of devices and a solution back end. The Get started with IoT Hub tutorial shows how to create
an IoT hub, provision a device identity in it, and code a simulated device app that sends device-to-cloud
messages.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial builds on Get started with IoT Hub. It shows you how to:
From your solution back end, send cloud-to-device messages to a single device through IoT Hub.
Receive cloud-to-device messages on a device.
From your solution back end, request delivery acknowledgement (feedback) for messages sent to a device
from IoT Hub.
You can find more information on cloud-to-device messages in the IoT Hub developer guide.
At the end of this tutorial, you run two Java console apps:
simulated-device, a modified version of the app created in Get started with IoT Hub, which connects to
your IoT hub and receives cloud-to-device messages.
send-c2d-messages, which sends a cloud-to-device message to the simulated device app through IoT Hub,
and then receives its delivery acknowledgement.

NOTE
IoT Hub has SDK support for many device platforms and languages (including C, Java, and Javascript) through Azure IoT
device SDKs. For step-by-step instructions on how to connect your device to this tutorial's code, and generally to Azure
IoT Hub, see the Azure IoT Developer Center.

To complete this tutorial, you need the following:


A complete working version of the Get started with IoT Hub or Process IoT Hub device-to-cloud messages
tutorial.
The latest Java SE Development Kit 8
Maven 3
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Receive messages in the simulated device app


In this section, you modify the simulated device app you created in Get started with IoT Hub to receive cloud-to-
device messages from the IoT hub.
1. Using a text editor, open the simulated-device\src\main\java\com\mycompany\app\App.java file.
2. Add the following MessageCallback class as a nested class inside the App class. The execute method is
invoked when the device receives a message from IoT Hub. In this example, the device always notifies the
IoT hub that it has completed the message:

private static class AppMessageCallback implements MessageCallback {


public IotHubMessageResult execute(Message msg, Object context) {
System.out.println("Received message from hub: "
+ new String(msg.getBytes(), Message.DEFAULT_IOTHUB_MESSAGE_CHARSET));

return IotHubMessageResult.COMPLETE;
}
}

3. Modify the main method to create an AppMessageCallback instance and call the
setMessageCallback method before it opens the client as follows:

client = new DeviceClient(connString, protocol);

MessageCallback callback = new AppMessageCallback();


client.setMessageCallback(callback, null);
client.open();

NOTE
If you use HTTPS instead of MQTT or AMQP as the transport, the DeviceClient instance checks for messages from
IoT Hub infrequently (less than every 25 minutes). For more information about the differences between MQTT,
AMQP and HTTPS support, and IoT Hub throttling, see the IoT Hub developer guide.

4. To build the simulated-device app using Maven, execute the following command at the command
prompt in the simulated-device folder:

mvn clean package -DskipTests

Send a cloud-to-device message


In this section, you create a Java console app that sends cloud-to-device messages to the simulated device app.
You need the device ID of the device you added in the Get started with IoT Hub tutorial. You also need the IoT
Hub connection string for your hub that you can find in the Azure portal.
1. Create a Maven project called send-c2d-messages using the following command at your command
prompt. Note this command is a single, long command:

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=send-c2d-messages -


DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2. At your command prompt, navigate to the new send-c2d-messages folder.


3. Using a text editor, open the pom.xml file in the send-c2d-messages folder and add the following
dependency to the dependencies node. Adding the dependency enables you to use the iothub-java-
service-client package in your application to communicate with your IoT hub service:
<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-service-client</artifactId>
<version>1.7.23</version>
</dependency>

NOTE
You can check for the latest version of iot-service-client using Maven search.

4. Save and close the pom.xml file.


5. Using a text editor, open the send-c2d-messages\src\main\java\com\mycompany\app\App.java file.
6. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.service.*;
import java.io.IOException;
import java.net.URISyntaxException;

7. Add the following class-level variables to the App class, replacing {yourhubconnectionstring} and
{yourdeviceid} with the values your noted earlier:

private static final String connectionString = "{yourhubconnectionstring}";


private static final String deviceId = "{yourdeviceid}";
private static final IotHubServiceClientProtocol protocol = IotHubServiceClientProtocol.AMQPS;

8. Replace the main method with the following code. This code connects to your IoT hub, sends a message
to your device, and then waits for an acknowledgment that the device received and processed the
message:

public static void main(String[] args) throws IOException,


URISyntaxException, Exception {
ServiceClient serviceClient = ServiceClient.createFromConnectionString(
connectionString, protocol);

if (serviceClient != null) {
serviceClient.open();
FeedbackReceiver feedbackReceiver = serviceClient
.getFeedbackReceiver();
if (feedbackReceiver != null) feedbackReceiver.open();

Message messageToSend = new Message("Cloud to device message.");


messageToSend.setDeliveryAcknowledgement(DeliveryAcknowledgement.Full);

serviceClient.send(deviceId, messageToSend);
System.out.println("Message sent to device");

FeedbackBatch feedbackBatch = feedbackReceiver.receive(10000);


if (feedbackBatch != null) {
System.out.println("Message feedback received, feedback time: "
+ feedbackBatch.getEnqueuedTimeUtc().toString());
}

if (feedbackReceiver != null) feedbackReceiver.close();


serviceClient.close();
}
}
NOTE
For simplicity's sake, this tutorial does not implement any retry policy. In production code, you should implement
retry policies (such as exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

9. To build the simulated-device app using Maven, execute the following command at the command
prompt in the simulated-device folder:

mvn clean package -DskipTests

Run the applications


You are now ready to run the applications.
1. At a command prompt in the simulated-device folder, run the following command to begin sending
telemetry to your IoT hub and to listen for cloud-to-device messages sent from your hub:

mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

2. At a command prompt in the send-c2d-messages folder, run the following command to send a cloud-to-
device message and wait for a feedback acknowledgment:

mvn exec:java -Dexec.mainClass="com.mycompany.app.App"


Next steps
In this tutorial, you learned how to send and receive cloud-to-device messages.
To see examples of complete end-to-end solutions that use IoT Hub, see Azure IoT Remote Monitoring solution
accelerator.
To learn more about developing solutions with IoT Hub, see the IoT Hub developer guide.
Send cloud-to-device messages with IoT Hub
(Node)
5/29/2018 • 5 min to read • Edit Online

Introduction
Azure IoT Hub is a fully managed service that helps enable reliable and secure bi-directional communications
between millions of devices and a solution back end. The Get started with IoT Hub tutorial shows how to create
an IoT hub, provision a device identity in it, and code a simulated device app that sends device-to-cloud
messages.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial builds on Get started with IoT Hub. It shows you how to:
From your solution back end, send cloud-to-device messages to a single device through IoT Hub.
Receive cloud-to-device messages on a device.
From your solution back end, request delivery acknowledgement (feedback) for messages sent to a device
from IoT Hub.
You can find more information on cloud-to-device messages in the IoT Hub developer guide.
At the end of this tutorial, you run two Node.js console apps:
SimulatedDevice, a modified version of the app created in Get started with IoT Hub, which connects to
your IoT hub and receives cloud-to-device messages.
SendCloudToDeviceMessage, which sends a cloud-to-device message to the simulated device app
through IoT Hub, and then receives its delivery acknowledgement.

NOTE
IoT Hub has SDK support for many device platforms and languages (including C, Java, and Javascript) through Azure IoT
device SDKs. For step-by-step instructions on how to connect your device to this tutorial's code, and generally to Azure
IoT Hub, see the Azure IoT Developer Center.

To complete this tutorial, you need the following:


Node.js version 4.0.x or later.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Receive messages in the simulated device app


In this section, you modify the simulated device app you created in Get started with IoT Hub to receive cloud-to-
device messages from the IoT hub.
1. Using a text editor, open the SimulatedDevice.js file.
2. Modify the connectCallback function to handle messages sent from IoT Hub. In this example, the device
always invokes the complete function to notify IoT Hub that it has processed the message. Your new
version of the connectCallback function looks like the following snippet:

var connectCallback = function (err) {


if (err) {
console.log('Could not connect: ' + err);
} else {
console.log('Client connected');
client.on('message', function (msg) {
console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);
client.complete(msg, printResultFor('completed'));
});
// Create a message and send it to the IoT Hub every second
setInterval(function(){
var temperature = 20 + (Math.random() * 15);
var humidity = 60 + (Math.random() * 20);
var data = JSON.stringify({ deviceId: 'myFirstNodeDevice', temperature: temperature,
humidity: humidity });
var message = new Message(data);
message.properties.add('temperatureAlert', (temperature > 30) ? 'true' : 'false');
console.log("Sending message: " + message.getData());
client.sendEvent(message, printResultFor('send'));
}, 1000);
}
};

NOTE
If you use HTTPS instead of MQTT or AMQP as the transport, the DeviceClient instance checks for messages
from IoT Hub infrequently (less than every 25 minutes). For more information about the differences between
MQTT, AMQP and HTTPS support, and IoT Hub throttling, see the IoT Hub developer guide.

Send a cloud-to-device message


In this section, you create a Node.js console app that sends cloud-to-device messages to the simulated device
app. You need the device ID of the device you added in the Get started with IoT Hub tutorial. You also need the
IoT Hub connection string for your hub that you can find in the Azure portal.
1. Create an empty folder called sendcloudtodevicemessage. In the sendcloudtodevicemessage folder,
create a package.json file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the sendcloudtodevicemessage folder, run the following command to
install the azure-iothub package:

npm install azure-iothub --save

3. Using a text editor, create a SendCloudToDeviceMessage.js file in the sendcloudtodevicemessage


folder.
4. Add the following require statements at the start of the SendCloudToDeviceMessage.js file:
'use strict';

var Client = require('azure-iothub').Client;


var Message = require('azure-iot-common').Message;

5. Add the following code to SendCloudToDeviceMessage.js file. Replace the "{iot hub connection
string}" placeholder value with the IoT Hub connection string for the hub you created in the Get started
with IoT Hub tutorial. Replace the "{device id}" placeholder with the device ID of the device you added in
the Get started with IoT Hub tutorial:

var connectionString = '{iot hub connection string}';


var targetDevice = '{device id}';

var serviceClient = Client.fromConnectionString(connectionString);

6. Add the following function to print operation results to the console:

function printResultFor(op) {
return function printResult(err, res) {
if (err) console.log(op + ' error: ' + err.toString());
if (res) console.log(op + ' status: ' + res.constructor.name);
};
}

7. Add the following function to print delivery feedback messages to the console:

function receiveFeedback(err, receiver){


receiver.on('message', function (msg) {
console.log('Feedback message:')
console.log(msg.getData().toString('utf-8'));
});
}

8. Add the following code to send a message to your device and handle the feedback message when the
device acknowledges the cloud-to-device message:

serviceClient.open(function (err) {
if (err) {
console.error('Could not connect: ' + err.message);
} else {
console.log('Service client connected');
serviceClient.getFeedbackReceiver(receiveFeedback);
var message = new Message('Cloud to device message.');
message.ack = 'full';
message.messageId = "My Message ID";
console.log('Sending message: ' + message.getData());
serviceClient.send(targetDevice, message, printResultFor('send'));
}
});

9. Save and close SendCloudToDeviceMessage.js file.

Run the applications


You are now ready to run the applications.
1. At the command prompt in the simulateddevice folder, run the following command to send telemetry
to IoT Hub and to listen for cloud-to-device messages:

node SimulatedDevice.js

2. At a command prompt in the sendcloudtodevicemessage folder, run the following command to send a
cloud-to-device message and wait for the acknowledgment feedback:

node SendCloudToDeviceMessage.js

NOTE
For simplicity's sake, this tutorial does not implement any retry policy. In production code, you should implement
retry policies (such as exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Next steps
In this tutorial, you learned how to send and receive cloud-to-device messages.
To see examples of complete end-to-end solutions that use IoT Hub, see Azure IoT Remote Monitoring solution
accelerator.
To learn more about developing solutions with IoT Hub, see the IoT Hub developer guide.
Send cloud-to-device messages with IoT Hub
(Python)
5/29/2018 • 6 min to read • Edit Online

Introduction
Azure IoT Hub is a fully managed service that helps enable reliable and secure bi-directional communications
between millions of devices and a solution back end. The Get started with IoT Hub tutorial shows how to create
an IoT hub, provision a device identity in it, and code a simulated device app that sends device-to-cloud
messages.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial builds on Get started with IoT Hub. It shows you how to:
From your solution back end, send cloud-to-device messages to a single device through IoT Hub.
Receive cloud-to-device messages on a device.
From your solution back end, request delivery acknowledgement (feedback) for messages sent to a device
from IoT Hub.
You can find more information on cloud-to-device messages in the IoT Hub developer guide.
At the end of this tutorial, you run two Python console apps:
SimulatedDevice.py, a modified version of the app created in Get started with IoT Hub, which connects to
your IoT hub and receives cloud-to-device messages.
SendCloudToDeviceMessage.py, which sends a cloud-to-device message to the simulated device app
through IoT Hub, and then receives its delivery acknowledgement.

NOTE
IoT Hub has SDK support for many device platforms and languages (including C, Java, and Javascript) through Azure IoT
device SDKs. For step-by-step instructions on how to connect your device to this tutorial's code, and generally to Azure IoT
Hub, see the Azure IoT Developer Center.

To complete this tutorial, you need the following:


Python 2.x or 3.x. Make sure to use the 32-bit or 64-bit installation as required by your setup. When
prompted during the installation, make sure to add Python to your platform-specific environment variable. If
you are using Python 2.x, you may need to install or upgrade pip, the Python package management system.
If you are using Windows OS, then Visual C++ redistributable package to allow the use of native DLLs from
Python.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)
NOTE
The pip packages for azure-iothub-service-client and azure-iothub-device-client are currently available only for
Windows OS. For Linux/Mac OS, please refer to the Linux and Mac OS-specific sections on the [Prepare your development
environment for Python][lnk-python-devbox] post.

Receive messages in the simulated device app


In this section, you create a Python console app to simulate the device and receive cloud-to-device messages
from the IoT hub.
1. Using a text editor, create a SimulatedDevice.py file.
2. Add the following import statements and variables at the start of the SimulatedDevice.py file:

import time
import sys
import iothub_client
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult
from iothub_client import IoTHubMessage, IoTHubMessageDispositionResult, IoTHubError

RECEIVE_CONTEXT = 0
WAIT_COUNT = 10
RECEIVED_COUNT = 0
RECEIVE_CALLBACKS = 0

3. Add the following code to SimulatedDevice.py file. Replace the "{deviceConnectionString}" placeholder
value with the device connection string for the device you created in the Get started with IoT Hub tutorial:

# choose AMQP or AMQP_WS as transport protocol


PROTOCOL = IoTHubTransportProvider.AMQP
CONNECTION_STRING = "{deviceConnectionString}"

4. Add the following function to print received messages to the console:


def receive_message_callback(message, counter):
global RECEIVE_CALLBACKS
message_buffer = message.get_bytearray()
size = len(message_buffer)
print ( "Received Message [%d]:" % counter )
print ( " Data: <<<%s>>> & Size=%d" % (message_buffer[:size].decode('utf-8'), size) )
map_properties = message.properties()
key_value_pair = map_properties.get_internals()
print ( " Properties: %s" % key_value_pair )
counter += 1
RECEIVE_CALLBACKS += 1
print ( " Total calls received: %d" % RECEIVE_CALLBACKS )
return IoTHubMessageDispositionResult.ACCEPTED

def iothub_client_init():
client = IoTHubClient(CONNECTION_STRING, PROTOCOL)

client.set_message_callback(receive_message_callback, RECEIVE_CONTEXT)

return client

def print_last_message_time(client):
try:
last_message = client.get_last_message_receive_time()
print ( "Last Message: %s" % time.asctime(time.localtime(last_message)) )
print ( "Actual time : %s" % time.asctime() )
except IoTHubClientError as iothub_client_error:
if iothub_client_error.args[0].result == IoTHubClientResult.INDEFINITE_TIME:
print ( "No message received" )
else:
print ( iothub_client_error )

5. Add the following code to initialize the client and wait to recieve the cloud-to-device message:

def iothub_client_init():
client = IoTHubClient(CONNECTION_STRING, PROTOCOL)

client.set_message_callback(receive_message_callback, RECEIVE_CONTEXT)

return client

def iothub_client_sample_run():
try:
client = iothub_client_init()

while True:
print ( "IoTHubClient waiting for commands, press Ctrl-C to exit" )

status_counter = 0
while status_counter <= WAIT_COUNT:
status = client.get_send_status()
print ( "Send status: %s" % status )
time.sleep(10)
status_counter += 1

except IoTHubError as iothub_error:


print ( "Unexpected error %s from IoTHub" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubClient sample stopped" )

print_last_message_time(client)

6. Add the following main function:


if __name__ == '__main__':
print ( "Starting the IoT Hub Python sample..." )
print ( " Protocol %s" % PROTOCOL )
print ( " Connection string=%s" % CONNECTION_STRING )

iothub_client_sample_run()

7. Save and close SimulatedDevice.py file.

Send a cloud-to-device message


In this section, you create a Python console app that sends cloud-to-device messages to the simulated device
app. You need the device ID of the device you added in the Get started with IoT Hub tutorial. You also need the
IoT Hub connection string for your hub that you can find in the Azure portal.
1. Using a text editor, create a SendCloudToDeviceMessage.py file.
2. Add the following import statements and variables at the start of the SendCloudToDeviceMessage.py
file:

import random
import sys
import iothub_service_client
from iothub_service_client import IoTHubMessaging, IoTHubMessage, IoTHubError

OPEN_CONTEXT = 0
FEEDBACK_CONTEXT = 1
MESSAGE_COUNT = 1
AVG_WIND_SPEED = 10.0
MSG_TXT = "{\"service client sent a message\": %.2f}"

3. Add the following code to SendCloudToDeviceMessage.py file. Replace the "


{IoTHubConnectionString}" placeholder value with the IoT Hub connection string for the hub you created
in the Get started with IoT Hub tutorial. Replace the "{deviceId}" placeholder with the device ID of the
device you added in the Get started with IoT Hub tutorial:

CONNECTION_STRING = "{IoTHubConnectionString}"
DEVICE_ID = "{deviceId}"

4. Add the following function to print feedback messages to the console:

def open_complete_callback(context):
print ( 'open_complete_callback called with context: {0}'.format(context) )

def send_complete_callback(context, messaging_result):


context = 0
print ( 'send_complete_callback called with context : {0}'.format(context) )
print ( 'messagingResult : {0}'.format(messaging_result) )

5. Add the following code to send a message to your device and handle the feedback message when the
device acknowledges the cloud-to-device message:
def iothub_messaging_sample_run():
try:
iothub_messaging = IoTHubMessaging(CONNECTION_STRING)

iothub_messaging.open(open_complete_callback, OPEN_CONTEXT)

for i in range(0, MESSAGE_COUNT):


print ( 'Sending message: {0}'.format(i) )
msg_txt_formatted = MSG_TXT % (AVG_WIND_SPEED + (random.random() * 4 + 2))
message = IoTHubMessage(bytearray(msg_txt_formatted, 'utf8'))

# optional: assign ids


message.message_id = "message_%d" % i
message.correlation_id = "correlation_%d" % i
# optional: assign properties
prop_map = message.properties()
prop_text = "PropMsg_%d" % i
prop_map.add("Property", prop_text)

iothub_messaging.send_async(DEVICE_ID, message, send_complete_callback, i)

try:
# Try Python 2.xx first
raw_input("Press Enter to continue...\n")
except:
pass
# Use Python 3.xx in the case of exception
input("Press Enter to continue...\n")

iothub_messaging.close()

except IoTHubError as iothub_error:


print ( "Unexpected error {0}" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubMessaging sample stopped" )

6. Add the following main function:

if __name__ == '__main__':
print ( "Starting the IoT Hub Service Client Messaging Python sample..." )
print ( " Connection string = {0}".format(CONNECTION_STRING) )
print ( " Device ID = {0}".format(DEVICE_ID) )

iothub_messaging_sample_run()

7. Save and close SendCloudToDeviceMessage.py file.

Run the applications


You are now ready to run the applications.
1. Open a command prompt and install the Azure IoT Hub Device SDK for Python.

pip install azure-iothub-device-client

2. At the command prompt, run the following command to listen for cloud-to-device messages:

python SimulatedDevice.py
3. Open a new command prompt and install the Azure IoT Hub Service SDK for Python.

pip install azure-iothub-service-client

4. At a command prompt, run the following command to send a cloud-to-device message and wait for the
message feedback:

python SendCloudToDeviceMessage.py

5. Note the message recieved by the device.

Next steps
In this tutorial, you learned how to send and receive cloud-to-device messages.
To see examples of complete end-to-end solutions that use IoT Hub, see Azure IoT Remote Monitoring solution
accelerator.
To learn more about developing solutions with IoT Hub, see the IoT Hub developer guide.
Send cloud-to-device messages with IoT Hub (iOS)
5/29/2018 • 5 min to read • Edit Online

Azure IoT Hub is a fully managed service that helps enable reliable and secure bi-directional communications
between millions of devices and a solution back end. The Send telemetry from a device to an IoT hub article
shows how to create an IoT hub, provision a device identity in it, and code a simulated device app that sends
device-to-cloud messages.
This article shows you how to:
From your solution back end, send cloud-to-device messages to a single device through IoT Hub.
Receive cloud-to-device messages on a device.
From your solution back end, request delivery acknowledgement (feedback) for messages sent to a device
from IoT Hub.
You can find more information on cloud-to-device messages in the IoT Hub developer guide.
At the end of this article, you run two Swift iOS projects:
sample-device, the same app created in Send telemetry from a device to an IoT hub, which connects to your
IoT hub and receives cloud-to-device messages.
sample-service, which sends a cloud-to-device message to the simulated device app through IoT Hub, and
then receives its delivery acknowledgement.

NOTE
IoT Hub has SDK support for many device platforms and languages (including C, Java, and Javascript) through Azure IoT
device SDKs. For step-by-step instructions on how to connect your device to this tutorial's code, and generally to Azure IoT
Hub, see the Azure IoT Developer Center.

To complete this tutorial, you need the following:


An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)
An active IoT hub in Azure.
The code sample from Azure samples .
The latest version of XCode, running the latest version of the iOS SDK. This quickstart was tested with XCode
9.3 and iOS 11.3.
The latest version of CocoaPods.

Simulate an IoT device


In this section, you simulate an iOS device running a Swift application to receive cloud-to-device messages from
the IoT hub.
This is the sample sample device that you create in the article Send telemetry from a device to an IoT hub. If you
already have that running, you can skip this section.
Install CocoaPods
CocoaPods manage dependencies for iOS projects that use third-party libraries.
In a terminal window, navigate to the Azure-IoT-Samples-iOS folder that you downloaded in the prerequisites.
Then, navigate to the sample project:

cd quickstart/sample-device

Make sure that XCode is closed, then run the following command to install the CocoaPods that are declared in
the podfile file:

pod install

Along with installing the pods required for your project, the installation command also created an XCode
workspace file that is already configured to use the pods for dependencies.
Run the sample device application
1. Retrieve the connection string for your device. You can copy this string from the Azure portal in the device
details blade, or retrieve it with the following CLI command:

az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id


{YourDeviceID} --output table

2. Open the sample workspace in XCode.

open "MQTT Client Sample.xcworkspace"

3. Expand the MQTT Client Sample project and then folder of the same name.
4. Open ViewController.swift for editing in XCode.
5. Search for the connectionString variable and update the value with the device connection string that you
copied in the first step.
6. Save your changes.
7. Run the project in the device emulator with the Build and run button or the key combo command + r.

Simulate a service device


In this section, you simulate a second iOS device with a Swift app that sends cloud-to-device messages through
the IoT hub. This configuration is useful for IoT scenarios where there is one iPhone or iPad functioning as a
controller for other iOS devices connected to an IoT hub.
Install CocoaPods
CocoaPods manage dependencies for iOS projects that use third-party libraries.
Navigate to the Azure IoT iOS Samples folder that you downloaded in the prerequisites. Then, navigate to the
sample service project:

cd quickstart/sample-service

Make sure that XCode is closed, then run the following command to install the CocoaPods that are declared in
the podfile file:

pod install

Along with installing the pods required for your project, the installation command also created an XCode
workspace file that is already configured to use the pods for dependencies.
Run the sample service application
1. Retrieve the service connection string for your IoT hub. You can copy this string from the Azure portal
from the iothubowner policy in the Shared access policies blade, or retrieve it with the following CLI
command:

az iot hub show-connection-string --hub-name {YourIoTHubName} --output table

2. Open the sample workspace in XCode.

open AzureIoTServiceSample.xcworkspace

3. Expand the AzureIoTServiceSample project and then expand the folder of the same name.
4. Open ViewController.swift for editing in XCode.
5. Search for the connectionString variable and update the value with the service connection string that you
copied previously.
6. Save your changes.
7. In Xcode, change the emulator settings to a different iOS device than you used to run the IoT device.
XCode cannot run multiple emulators of the same type.
8. Run the project in the device emulator with the Build and run button or the key combo Command + r.

Send a cloud-to-device message


You are now ready to use the two applications to send and receive cloud-to-device messages.
1. In the iOS App Sample app running on the simulated IoT device, click Start. The application starts
sending device-to-cloud messages, but also starts listening for cloud-to-device messages.
2. In the IoTHub Service Client Sample app running on the simulated service device, enter the ID for the
IoT device that you want a to send a message to.
3. Write a plaintext message, then click Send.
Several actions happen as soon as you click send. The service sample sends the message to your IoT hub, which
the app has access to because of the service connection string that you provided. Your IoT hub checks the device
ID, sends the message to the destination device, and sends a confirmation receipt to the source device. The app
running on your simulated IoT device checks for messages from IoT Hub and prints the text from the most
recent one on the screen.
Your output should look like the following example:
Next steps
In this tutorial, you learned how to send and receive cloud-to-device messages.
To see examples of complete end-to-end solutions that use IoT Hub, see Azure IoT Remote Monitoring solution
accelerator.
To learn more about developing solutions with IoT Hub, see the IoT Hub developer guide.
Get started with device twins (Node)
5/29/2018 • 9 min to read • Edit Online

Device twins are JSON documents that store device state information (metadata, configurations, and conditions).
IoT Hub persists a device twin for each device that connects to it.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use device twins to:


Store device metadata from your solution back end.
Report current state information such as available capabilities and conditions (for example, the connectivity
method used) from your device app.
Synchronize the state of long-running workflows (such as firmware and configuration updates) between a
device app and a back-end app.
Query your device metadata, configuration, or state.
Device twins are designed for synchronization and for querying device configurations and conditions. More
information on when to use device twins can be found in Understand device twins.
Device twins are stored in an IoT hub and contain:
tags, device metadata accessible only by the solution back end;
desired properties, JSON objects modifiable by the solution back end and observable by the device app; and
reported properties, JSON objects modifiable by the device app and readable by the solution back end. Tags and
properties cannot contain arrays, but objects can be nested.

Additionally, the solution back end can query device twins based on all the above data. Refer to Understand device
twins for more information about device twins, and to the IoT Hub query language reference for querying.
This tutorial shows you how to:
Create a back-end app that adds tags to a device twin, and a simulated device app that reports its connectivity
channel as a reported property on the device twin.
Query devices from your back-end app using filters on the tags and properties previously created.
At the end of this tutorial, you will have two Node.js console apps:
AddTagsAndQuery.js, a Node.js back-end app, which adds tags and queries device twins.
TwinSimulatedDevice.js, a Node.js app, which simulates a device that connects to your IoT hub with the
device identity created earlier, and reports its connectivity condition.

NOTE
The article Azure IoT SDKs provides information about the Azure IoT SDKs that you can use to build both device and back-
end apps.

To complete this tutorial you need the following:


Node.js version 4.0.x or later.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."
Create a device identity
In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device IDs
are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with the IoT
Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the device app
to connect to your IoT Hub as a device.

Refer to Getting started with IoT Hub to programmatically create device identities.

Create the service app


In this section, you create a Node.js console app that adds location metadata to the device twin associated with
myDeviceId. It then queries the device twins stored in the IoT hub selecting the devices located in the US, and
then the ones that are reporting a cellular connection.
1. Create a new empty folder called addtagsandqueryapp. In the addtagsandqueryapp folder, create a new
package.json file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the addtagsandqueryapp folder, run the following command to install the
azure-iothub package:
npm install azure-iothub --save

3. Using a text editor, create a new AddTagsAndQuery.js file in the addtagsandqueryapp folder.
4. Add the following code to the AddTagsAndQuery.js file, and substitute the {iot hub connection string}
placeholder with the IoT Hub connection string you copied when you created your hub:

'use strict';
var iothub = require('azure-iothub');
var connectionString = '{iot hub connection string}';
var registry = iothub.Registry.fromConnectionString(connectionString);

registry.getTwin('myDeviceId', function(err, twin){


if (err) {
console.error(err.constructor.name + ': ' + err.message);
} else {
var patch = {
tags: {
location: {
region: 'US',
plant: 'Redmond43'
}
}
};

twin.update(patch, function(err) {
if (err) {
console.error('Could not update twin: ' + err.constructor.name + ': ' + err.message);
} else {
console.log(twin.deviceId + ' twin updated successfully');
queryTwins();
}
});
}
});

The Registry object exposes all the methods required to interact with device twins from the service. The
previous code first initializes the Registry object, then retrieves the device twin for myDeviceId, and finally
updates its tags with the desired location information.
After updating the tags it calls the queryTwins function.
5. Add the following code at the end of AddTagsAndQuery.js to implement the queryTwins function:
var queryTwins = function() {
var query = registry.createQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43'",
100);
query.nextAsTwin(function(err, results) {
if (err) {
console.error('Failed to fetch the results: ' + err.message);
} else {
console.log("Devices in Redmond43: " + results.map(function(twin) {return
twin.deviceId}).join(','));
}
});

query = registry.createQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43' AND


properties.reported.connectivity.type = 'cellular'", 100);
query.nextAsTwin(function(err, results) {
if (err) {
console.error('Failed to fetch the results: ' + err.message);
} else {
console.log("Devices in Redmond43 using cellular network: " + results.map(function(twin)
{return twin.deviceId}).join(','));
}
});
};

The previous code executes two queries: the first selects only the device twins of devices located in the
Redmond43 plant, and the second refines the query to select only the devices that are also connected
through cellular network.
The previous code, when it creates the query object, specifies a maximum number of returned documents.
The query object contains a hasMoreResults boolean property that you can use to invoke the nextAsTwin
methods multiple times to retrieve all results. A method called next is available for results that are not
device twins, for example, results of aggregation queries.
6. Run the application with:

node AddTagsAndQuery.js

You should see one device in the results for the query asking for all devices located in Redmond43 and
none for the query that restricts the results to devices that use a cellular network.

In the next section, you create a device app that reports the connectivity information and changes the result of the
query in the previous section.

Create the device app


In this section, you create a Node.js console app that connects to your hub as myDeviceId, and then updates its
device twin's reported properties to contain the information that it is connected using a cellular network.
1. Create a new empty folder called reportconnectivity. In the reportconnectivity folder, create a new
package.json file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the reportconnectivity folder, run the following command to install the
azure-iot-device, and azure-iot-device-mqtt package:

npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a new ReportConnectivity.js file in the reportconnectivity folder.
4. Add the following code to the ReportConnectivity.js file, and substitute the {device connection string}
placeholder with the device connection string you copied when you created the myDeviceId device identity:

'use strict';
var Client = require('azure-iot-device').Client;
var Protocol = require('azure-iot-device-mqtt').Mqtt;

var connectionString = '{device connection string}';


var client = Client.fromConnectionString(connectionString, Protocol);

client.open(function(err) {
if (err) {
console.error('could not open IotHub client');
} else {
console.log('client opened');

client.getTwin(function(err, twin) {
if (err) {
console.error('could not get twin');
} else {
var patch = {
connectivity: {
type: 'cellular'
}
};

twin.properties.reported.update(patch, function(err) {
if (err) {
console.error('could not update twin');
} else {
console.log('twin state reported');
process.exit();
}
});
}
});
}
});

The Client object exposes all the methods you require to interact with device twins from the device. The
previous code, after it initializes the Client object, retrieves the device twin for myDeviceId and updates its
reported property with the connectivity information.
5. Run the device app

node ReportConnectivity.js

You should see the message twin state reported .


6. Now that the device reported its connectivity information, it should appear in both queries. Go back in the
addtagsandqueryapp folder and run the queries again:

node AddTagsAndQuery.js
This time myDeviceId should appear in both query results.

Next steps
In this tutorial, you configured a new IoT hub in the Azure portal, and then created a device identity in the IoT hub's
identity registry. You added device metadata as tags from a back-end app, and wrote a simulated device app to
report device connectivity information in the device twin. You also learned how to query this information using the
SQL -like IoT Hub query language.
Use the following resources to learn how to:
send telemetry from devices with the Get started with IoT Hub tutorial,
configure devices using device twin's desired properties with the Use desired properties to configure devices
tutorial,
control devices interactively (such as turning on a fan from a user-controlled app), with the Use direct methods
tutorial.
Get started with device twins (.NET/Node)
5/29/2018 • 9 min to read • Edit Online

Device twins are JSON documents that store device state information (metadata, configurations, and conditions).
IoT Hub persists a device twin for each device that connects to it.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use device twins to:


Store device metadata from your solution back end.
Report current state information such as available capabilities and conditions (for example, the connectivity
method used) from your device app.
Synchronize the state of long-running workflows (such as firmware and configuration updates) between a
device app and a back-end app.
Query your device metadata, configuration, or state.
Device twins are designed for synchronization and for querying device configurations and conditions. More
information on when to use device twins can be found in Understand device twins.
Device twins are stored in an IoT hub and contain:
tags, device metadata accessible only by the solution back end;
desired properties, JSON objects modifiable by the solution back end and observable by the device app; and
reported properties, JSON objects modifiable by the device app and readable by the solution back end. Tags and
properties cannot contain arrays, but objects can be nested.

Additionally, the solution back end can query device twins based on all the above data. Refer to Understand device
twins for more information about device twins, and to the IoT Hub query language reference for querying.
This tutorial shows you how to:
Create a back-end app that adds tags to a device twin, and a simulated device app that reports its connectivity
channel as a reported property on the device twin.
Query devices from your back-end app using filters on the tags and properties previously created.
At the end of this tutorial, you will have a .NET and a Node.js console app:
AddTagsAndQuery.sln, a .NET back-end app, which adds tags and queries device twins.
TwinSimulatedDevice.js, a Node.js app which simulates a device that connects to your IoT hub with the
device identity created earlier, and reports its connectivity condition.

NOTE
The article Azure IoT SDKs provides information about the Azure IoT SDKs that you can use to build both device and back-
end apps.

To complete this tutorial you need the following:


Visual Studio 2015 or Visual Studio 2017.
Node.js version 4.0.x or later.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."
Create a device identity
In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device IDs
are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with the IoT
Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the device app
to connect to your IoT Hub as a device.

Refer to Getting started with IoT Hub to programmatically create device identities.

Create the service app


In this section, you create a .NET console app (using C#) that adds location metadata to the device twin associated
with myDeviceId. It then queries the device twins stored in the IoT hub selecting the devices located in the US,
and then the ones that reported a cellular connection.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project AddTagsAndQuery.
2. In Solution Explorer, right-click the AddTagsAndQuery project, and then click Manage NuGet Packages....
3. In the NuGet Package Manager window, select Browse and search for microsoft.azure.devices. Select
Install to install the Microsoft.Azure.Devices package, and accept the terms of use. This procedure
downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package and its dependencies.

4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;

5. Add the following fields to the Program class. Replace the placeholder value with the IoT Hub connection
string for the hub that you created in the previous section.

static RegistryManager registryManager;


static string connectionString = "{iot hub connection string}";
6. Add the following method to the Program class:

public static async Task AddTagsAndQuery()


{
var twin = await registryManager.GetTwinAsync("myDeviceId");
var patch =
@"{
tags: {
location: {
region: 'US',
plant: 'Redmond43'
}
}
}";
await registryManager.UpdateTwinAsync(twin.DeviceId, patch, twin.ETag);

var query = registryManager.CreateQuery("SELECT * FROM devices WHERE tags.location.plant =


'Redmond43'", 100);
var twinsInRedmond43 = await query.GetNextAsTwinAsync();
Console.WriteLine("Devices in Redmond43: {0}", string.Join(", ", twinsInRedmond43.Select(t =>
t.DeviceId)));

query = registryManager.CreateQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43'


AND properties.reported.connectivity.type = 'cellular'", 100);
var twinsInRedmond43UsingCellular = await query.GetNextAsTwinAsync();
Console.WriteLine("Devices in Redmond43 using cellular network: {0}", string.Join(", ",
twinsInRedmond43UsingCellular.Select(t => t.DeviceId)));
}

The RegistryManager class exposes all the methods required to interact with device twins from the service.
The previous code first initializes the registryManager object, then retrieves the device twin for
myDeviceId, and finally updates its tags with the desired location information.
After updating, it executes two queries: the first selects only the device twins of devices located in the
Redmond43 plant, and the second refines the query to select only the devices that are also connected
through cellular network.
Note that the previous code, when it creates the query object, specifies a maximum number of returned
documents. The query object contains a HasMoreResults boolean property that you can use to invoke the
GetNextAsTwinAsync methods multiple times to retrieve all results. A method called GetNextAsJson is
available for results that are not device twins, for example, results of aggregation queries.
7. Finally, add the following lines to the Main method:

registryManager = RegistryManager.CreateFromConnectionString(connectionString);
AddTagsAndQuery().Wait();
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();

8. In the Solution Explorer, open the Set StartUp projects... and make sure the Action for
AddTagsAndQuery project is Start. Build the solution.
9. Run this application by right-clicking on the AddTagsAndQuery project and selecting Debug, followed by
Start new instance. You should see one device in the results for the query asking for all devices located in
Redmond43 and none for the query that restricts the results to devices that use a cellular network.
In the next section, you create a device app that reports the connectivity information and changes the result of the
query in the previous section.

Create the device app


In this section, you create a Node.js console app that connects to your hub as myDeviceId, and then updates its
reported properties to contain the information that it is connected using a cellular network.
1. Create a new empty folder called reportconnectivity. In the reportconnectivity folder, create a new
package.json file using the following command at your command prompt. Accept all the defaults.

npm init

2. At your command prompt in the reportconnectivity folder, run the following command to install the
azure-iot-device, and azure-iot-device-mqtt package:

npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a new ReportConnectivity.js file in the reportconnectivity folder.
4. Add the following code to the ReportConnectivity.js file, and substitute the placeholder for device
connection string with the one you copied when you created the myDeviceId device identity:
'use strict';
var Client = require('azure-iot-device').Client;
var Protocol = require('azure-iot-device-mqtt').Mqtt;

var connectionString = '{device connection string}';


var client = Client.fromConnectionString(connectionString, Protocol);

client.open(function(err) {
if (err) {
console.error('could not open IotHub client');
} else {
console.log('client opened');

client.getTwin(function(err, twin) {
if (err) {
console.error('could not get twin');
} else {
var patch = {
connectivity: {
type: 'cellular'
}
};

twin.properties.reported.update(patch, function(err) {
if (err) {
console.error('could not update twin');
} else {
console.log('twin state reported');
process.exit();
}
});
}
});
}
});

The Client object exposes all the methods you require to interact with device twins from the device. The
previous code, after it initializes the Client object, retrieves the device twin for myDeviceId and updates its
reported property with the connectivity information.
5. Run the device app

node ReportConnectivity.js

You should see the message twin state reported .


6. Now that the device reported its connectivity information, it should appear in both queries. Run the .NET
AddTagsAndQuery app to run the queries again. This time myDeviceId should appear in both query
results.

Next steps
In this tutorial, you configured a new IoT hub in the Azure portal, and then created a device identity in the IoT hub's
identity registry. You added device metadata as tags from a back-end app, and wrote a simulated device app to
report device connectivity information in the device twin. You also learned how to query this information using the
SQL -like IoT Hub query language.
Use the following resources to learn how to:
send telemetry from devices with the Get started with IoT Hub tutorial,
configure devices using device twin's desired properties with the Use desired properties to configure devices
tutorial,
control devices interactively (such as turning on a fan from a user-controlled app) with the Use direct methods
tutorial.
Get started with device twins (.NET/.NET)
5/29/2018 • 10 min to read • Edit Online

Device twins are JSON documents that store device state information (metadata, configurations, and conditions).
IoT Hub persists a device twin for each device that connects to it.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use device twins to:


Store device metadata from your solution back end.
Report current state information such as available capabilities and conditions (for example, the connectivity
method used) from your device app.
Synchronize the state of long-running workflows (such as firmware and configuration updates) between a
device app and a back-end app.
Query your device metadata, configuration, or state.
Device twins are designed for synchronization and for querying device configurations and conditions. More
information on when to use device twins can be found in Understand device twins.
Device twins are stored in an IoT hub and contain:
tags, device metadata accessible only by the solution back end;
desired properties, JSON objects modifiable by the solution back end and observable by the device app; and
reported properties, JSON objects modifiable by the device app and readable by the solution back end. Tags and
properties cannot contain arrays, but objects can be nested.

Additionally, the solution back end can query device twins based on all the above data. Refer to Understand device
twins for more information about device twins, and to the IoT Hub query language reference for querying.
This tutorial shows you how to:
Create a back-end app that adds tags to a device twin, and a simulated device app that reports its connectivity
channel as a reported property on the device twin.
Query devices from your back-end app using filters on the tags and properties previously created.
At the end of this tutorial, you will have these .NET console apps:
CreateDeviceIdentity, a .NET app which creates a device identity and associated security key to connect your
simulated device app.
AddTagsAndQuery, a .NET back-end app which adds tags and queries device twins.
ReportConnectivity, a .NET device app which simulates a device that connects to your IoT hub with the device
identity created earlier, and reports its connectivity condition.

NOTE
The article Azure IoT SDKs provides information about the Azure IoT SDKs that you can use to build both device and back-
end apps.

To complete this tutorial you need the following:


Visual Studio 2015 or Visual Studio 2017.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."
Create a device identity
In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A device
cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the "Identity
registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a unique
device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.

4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new device
identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.
5. In the device list, click the newly created device and copy the Connection string---primary key to use later.

NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and keys
to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device. If your
application needs to store other device-specific metadata, it should use an application-specific store. For more information,
see IoT Hub developer guide.

Create the service app


In this section, you create a .NET console app (using C#) that adds location metadata to the device twin associated
with myDeviceId. It then queries the device twins stored in the IoT hub selecting the devices located in the US,
and then the ones that reported a cellular connection.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project AddTagsAndQuery.
2. In Solution Explorer, right-click the AddTagsAndQuery project, and then click Manage NuGet Packages....
3. In the NuGet Package Manager window, select Browse and search for microsoft.azure.devices. Select
Install to install the Microsoft.Azure.Devices package, and accept the terms of use. This procedure
downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package and its dependencies.

4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;

5. Add the following fields to the Program class. Replace the placeholder value with the IoT Hub connection
string for the hub that you created in the previous section.

static RegistryManager registryManager;


static string connectionString = "{iot hub connection string}";
6. Add the following method to the Program class:

public static async Task AddTagsAndQuery()


{
var twin = await registryManager.GetTwinAsync("myDeviceId");
var patch =
@"{
tags: {
location: {
region: 'US',
plant: 'Redmond43'
}
}
}";
await registryManager.UpdateTwinAsync(twin.DeviceId, patch, twin.ETag);

var query = registryManager.CreateQuery("SELECT * FROM devices WHERE tags.location.plant =


'Redmond43'", 100);
var twinsInRedmond43 = await query.GetNextAsTwinAsync();
Console.WriteLine("Devices in Redmond43: {0}", string.Join(", ", twinsInRedmond43.Select(t =>
t.DeviceId)));

query = registryManager.CreateQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43'


AND properties.reported.connectivity.type = 'cellular'", 100);
var twinsInRedmond43UsingCellular = await query.GetNextAsTwinAsync();
Console.WriteLine("Devices in Redmond43 using cellular network: {0}", string.Join(", ",
twinsInRedmond43UsingCellular.Select(t => t.DeviceId)));
}

The RegistryManager class exposes all the methods required to interact with device twins from the service.
The previous code first initializes the registryManager object, then retrieves the device twin for
myDeviceId, and finally updates its tags with the desired location information.
After updating, it executes two queries: the first selects only the device twins of devices located in the
Redmond43 plant, and the second refines the query to select only the devices that are also connected
through cellular network.
Note that the previous code, when it creates the query object, specifies a maximum number of returned
documents. The query object contains a HasMoreResults boolean property that you can use to invoke the
GetNextAsTwinAsync methods multiple times to retrieve all results. A method called GetNextAsJson is
available for results that are not device twins, for example, results of aggregation queries.
7. Finally, add the following lines to the Main method:

registryManager = RegistryManager.CreateFromConnectionString(connectionString);
AddTagsAndQuery().Wait();
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();

8. In the Solution Explorer, open the Set StartUp projects... and make sure the Action for
AddTagsAndQuery project is Start. Build the solution.
9. Run this application by right-clicking on the AddTagsAndQuery project and selecting Debug, followed by
Start new instance. You should see one device in the results for the query asking for all devices located in
Redmond43 and none for the query that restricts the results to devices that use a cellular network.
In the next section, you create a device app that reports the connectivity information and changes the result of the
query in the previous section.

Create the device app


In this section, you create a .NET console app that connects to your hub as myDeviceId, and then updates its
reported properties to contain the information that it is connected using a cellular network.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project ReportConnectivity.

2. In Solution Explorer, right-click the ReportConnectivity project, and then click Manage NuGet
Packages....
3. In the NuGet Package Manager window, select Browse and search for microsoft.azure.devices.client.
Select Install to install the Microsoft.Azure.Devices.Client package, and accept the terms of use. This
procedure downloads, installs, and adds a reference to the Azure IoT device SDK NuGet package and its
dependencies.
4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;
using Newtonsoft.Json;

5. Add the following fields to the Program class. Replace the placeholder value with the device connection
string that you noted in the previous section.

static string DeviceConnectionString = "HostName=<yourIotHubName>.azure-devices.net;DeviceId=


<yourIotDeviceName>;SharedAccessKey=<yourIotDeviceAccessKey>";
static DeviceClient Client = null;

6. Add the following method to the Program class:

public static async void InitClient()


{
try
{
Console.WriteLine("Connecting to hub");
Client = DeviceClient.CreateFromConnectionString(DeviceConnectionString, TransportType.Mqtt);
Console.WriteLine("Retrieving twin");
await Client.GetTwinAsync();
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}
}

The Client object exposes all the methods you require to interact with device twins from the device. The
code shown above, initializes the Client object, and then retrieves the device twin for myDeviceId.
7. Add the following method to the Program class:
public static async void ReportConnectivity()
{
try
{
Console.WriteLine("Sending connectivity data as reported property");

TwinCollection reportedProperties, connectivity;


reportedProperties = new TwinCollection();
connectivity = new TwinCollection();
connectivity["type"] = "cellular";
reportedProperties["connectivity"] = connectivity;
await Client.UpdateReportedPropertiesAsync(reportedProperties);
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}
}

The code above updates myDeviceId's reported property with the connectivity information.
8. Finally, add the following lines to the Main method:

try
{
InitClient();
ReportConnectivity();
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();

9. In the Solution Explorer, open the Set StartUp projects... and make sure the Action for
ReportConnectivity project is Start. Build the solution.
10. Run this application by right-clicking on the ReportConnectivity project and selecting Debug, followed by
Start new instance. You should see it getting the twin information, and then sending connectivity as a
reported property.

11. Now that the device reported its connectivity information, it should appear in both queries. Run the .NET
AddTagsAndQuery app to run the queries again. This time myDeviceId should appear in both query
results.
Next steps
In this tutorial, you configured a new IoT hub in the Azure portal, and then created a device identity in the IoT hub's
identity registry. You added device metadata as tags from a back-end app, and wrote a simulated device app to
report device connectivity information in the device twin. You also learned how to query this information using the
SQL -like IoT Hub query language.
Use the following resources to learn how to:
send telemetry from devices with the Get started with IoT Hub tutorial,
configure devices using device twin's desired properties with the Use desired properties to configure devices
tutorial,
control devices interactively (such as turning on a fan from a user-controlled app) with the Use direct methods
tutorial.
Get started with device twins (Java)
5/29/2018 • 11 min to read • Edit Online

Device twins are JSON documents that store device state information (metadata, configurations, and conditions).
IoT Hub persists a device twin for each device that connects to it.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use device twins to:


Store device metadata from your solution back end.
Report current state information such as available capabilities and conditions (for example, the connectivity
method used) from your device app.
Synchronize the state of long-running workflows (such as firmware and configuration updates) between a
device app and a back-end app.
Query your device metadata, configuration, or state.
Device twins are designed for synchronization and for querying device configurations and conditions. More
information on when to use device twins can be found in Understand device twins.
Device twins are stored in an IoT hub and contain:
tags, device metadata accessible only by the solution back end;
desired properties, JSON objects modifiable by the solution back end and observable by the device app; and
reported properties, JSON objects modifiable by the device app and readable by the solution back end. Tags and
properties cannot contain arrays, but objects can be nested.

Additionally, the solution back end can query device twins based on all the above data. Refer to Understand device
twins for more information about device twins, and to the IoT Hub query language reference for querying.
This tutorial shows you how to:
Create a back-end app that adds tags to a device twin, and a simulated device app that reports its connectivity
channel as a reported property on the device twin.
Query devices from your back-end app using filters on the tags and properties previously created.
In this tutorial, you create two Java console apps:
add-tags-query, a Java back-end app that adds tags and queries device twins.
simulated-device, a Java device app that that connects to your IoT hub and reports its connectivity condition
using a reported property.

NOTE
The article Azure IoT SDKs provides information about the Azure IoT SDKs that you can use to build both device and back-
end apps.

To complete this tutorial, you need:


The latest Java SE Development Kit 8
Maven 3
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."
Create a device identity
In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A device
cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the "Identity
registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a unique
device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.

4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new device
identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.
5. In the device list, click the newly created device and copy the Connection string---primary key to use later.

NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and keys
to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device. If your
application needs to store other device-specific metadata, it should use an application-specific store. For more information,
see IoT Hub developer guide.

Create the service app


In this section, you create a Java app that adds location metadata as a tag to the device twin in IoT Hub associated
with myDeviceId. The app first queries IoT hub for devices located in the US, and then for devices that report a
cellular network connection.
1. On your development machine, create an empty folder called iot-java-twin-getstarted .
2. In the iot-java-twin-getstarted folder, create a Maven project called add-tags-query using the following
command at your command prompt. Note this is a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=add-tags-query -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
3. At your command prompt, navigate to the add-tags-query folder.
4. Using a text editor, open the pom.xml file in the add-tags-query folder and add the following dependency to
the dependencies node. This dependency enables you to use the iot-service-client package in your app to
communicate with your IoT hub:

<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-service-client</artifactId>
<version>1.7.23</version>
<type>jar</type>
</dependency>

NOTE
You can check for the latest version of iot-service-client using Maven search.

5. Add the following build node after the dependencies node. This configuration instructs Maven to use Java
1.8 to build the app:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

6. Save and close the pom.xml file.


7. Using a text editor, open the add-tags-query\src\main\java\com\mycompany\app\App.java file.
8. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.service.devicetwin.*;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

9. Add the following class-level variables to the App class. Replace {youriothubconnectionstring} with your IoT
hub connection string you noted in the Create an IoT Hub section:

public static final String iotHubConnectionString = "{youriothubconnectionstring}";


public static final String deviceId = "myDeviceId";

public static final String region = "US";


public static final String plant = "Redmond43";

10. Update the main method signature to include the following throws clause:
public static void main( String[] args ) throws IOException

11. Add the following code to the main method to create the DeviceTwin and DeviceTwinDevice objects.
The DeviceTwin object handles the communication with your IoT hub. The DeviceTwinDevice object
represents the device twin with its properties and tags:

// Get the DeviceTwin and DeviceTwinDevice objects


DeviceTwin twinClient = DeviceTwin.createFromConnectionString(iotHubConnectionString);
DeviceTwinDevice device = new DeviceTwinDevice(deviceId);

12. Add the following try/catch block to the main method:

try {
// Code goes here
} catch (IotHubException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}

13. To update the region and plant device twin tags in your device twin, add the following code in the try
block:

// Get the device twin from IoT Hub


System.out.println("Device twin before update:");
twinClient.getTwin(device);
System.out.println(device);

// Update device twin tags if they are different


// from the existing values
String currentTags = device.tagsToString();
if ((!currentTags.contains("region=" + region) && !currentTags.contains("plant=" + plant))) {
// Create the tags and attach them to the DeviceTwinDevice object
Set<Pair> tags = new HashSet<Pair>();
tags.add(new Pair("region", region));
tags.add(new Pair("plant", plant));
device.setTags(tags);

// Update the device twin in IoT Hub


System.out.println("Updating device twin");
twinClient.updateTwin(device);
}

// Retrieve the device twin with the tag values from IoT Hub
System.out.println("Device twin after update:");
twinClient.getTwin(device);
System.out.println(device);

14. To query the device twins in IoT hub, add the following code to the try block after the code you added in
the previous step. The code runs two queries. Each query returns a maximum of 100 devices:
// Query the device twins in IoT Hub
System.out.println("Devices in Redmond:");

// Construct the query


SqlQuery sqlQuery = SqlQuery.createSqlQuery("*", SqlQuery.FromType.DEVICES, "tags.plant='Redmond43'",
null);

// Run the query, returning a maximum of 100 devices


Query twinQuery = twinClient.queryTwin(sqlQuery.getQuery(), 100);
while (twinClient.hasNextDeviceTwin(twinQuery)) {
DeviceTwinDevice d = twinClient.getNextDeviceTwin(twinQuery);
System.out.println(d.getDeviceId());
}

System.out.println("Devices in Redmond using a cellular network:");

// Construct the query


sqlQuery = SqlQuery.createSqlQuery("*", SqlQuery.FromType.DEVICES, "tags.plant='Redmond43' AND
properties.reported.connectivityType = 'cellular'", null);

// Run the query, returning a maximum of 100 devices


twinQuery = twinClient.queryTwin(sqlQuery.getQuery(), 3);
while (twinClient.hasNextDeviceTwin(twinQuery)) {
DeviceTwinDevice d = twinClient.getNextDeviceTwin(twinQuery);
System.out.println(d.getDeviceId());
}

15. Save and close the add-tags-query\src\main\java\com\mycompany\app\App.java file


16. Build the add-tags-query app and correct any errors. At your command prompt, navigate to the
add-tags-query folder and run the following command:

mvn clean package -DskipTests

Create a device app


In this section, you create a Java console app that sets a reported property value that is sent to IoT Hub.
1. In the iot-java-twin-getstarted folder, create a Maven project called simulated-device using the following
command at your command prompt. Note this is a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=simulated-device -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2. At your command prompt, navigate to the simulated-device folder.


3. Using a text editor, open the pom.xml file in the simulated-device folder and add the following
dependencies to the dependencies node. This dependency enables you to use the iot-device-client
package in your app to communicate with your IoT hub:

<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-device-client</artifactId>
<version>1.3.32</version>
</dependency>

NOTE
You can check for the latest version of iot-device-client using Maven search.
4. Add the following build node after the dependencies node. This configuration instructs Maven to use Java
1.8 to build the app:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

5. Save and close the pom.xml file.


6. Using a text editor, open the simulated-device\src\main\java\com\mycompany\app\App.java file.
7. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.device.*;
import com.microsoft.azure.sdk.iot.device.DeviceTwin.*;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Scanner;

8. Add the following class-level variables to the App class. Replacing {youriothubname} with your IoT hub
name, and {yourdevicekey} with the device key value you generated in the Create a device identity section:

private static String connString = "HostName={youriothubname}.azure-


devices.net;DeviceId=myDeviceID;SharedAccessKey={yourdevicekey}";
private static IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
private static String deviceId = "myDeviceId";

This sample app uses the protocol variable when it instantiates a DeviceClient object.
9. Add the following code to the main method to:
Create a device client to communicate with IoT Hub.
Create a Device object to store the device twin properties.

DeviceClient client = new DeviceClient(connString, protocol);

// Create a Device object to store the device twin properties


Device dataCollector = new Device() {
// Print details when a property value changes
@Override
public void PropertyCall(String propertyKey, Object propertyValue, Object context) {
System.out.println(propertyKey + " changed to " + propertyValue);
}
};

10. Add the following code to the main method to create a connectivityType reported property and send it to
IoT Hub:
try {
// Open the DeviceClient and start the device twin services.
client.open();
client.startDeviceTwin(new DeviceTwinStatusCallBack(), null, dataCollector, null);

// Create a reported property and send it to your IoT hub.


dataCollector.setReportedProp(new Property("connectivityType", "cellular"));
client.sendReportedProperties(dataCollector.getReportedProp());
}
catch (Exception e) {
System.out.println("On exception, shutting down \n" + " Cause: " + e.getCause() + " \n" +
e.getMessage());
dataCollector.clean();
client.close();
System.out.println("Shutting down...");
}

11. Add the following code to the end of the main method. Waiting for the Enter key allows time for IoT Hub to
report the status of the device twin operations:

System.out.println("Press any key to exit...");

Scanner scanner = new Scanner(System.in);


scanner.nextLine();

dataCollector.clean();
client.close();

12. Save and close the simulated-device\src\main\java\com\mycompany\app\App.java file.


13. Build the simulated-device app and correct any errors. At your command prompt, navigate to the
simulated-device folder and run the following command:

mvn clean package -DskipTests

Run the apps


You are now ready to run the console apps.
1. At a command prompt in the add-tags-query folder, run the following command to run the add-tags-query
service app:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
You can see the plant and region tags added to the device twin. The first query returns your device, but the
second does not.
2. At a command prompt in the simulated-device folder, run the following command to add the
connectivityType reported property to the device twin:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

3. At a command prompt in the add-tags-query folder, run the following command to run the add-tags-query
service app a second time:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
Now your device has sent the connectivityType property to IoT Hub, the second query returns your
device.

Next steps
In this tutorial, you configured a new IoT hub in the Azure portal, and then created a device identity in the IoT hub's
identity registry. You added device metadata as tags from a back-end app, and wrote a device app to report device
connectivity information in the device twin. You also learned how to query the device twin information using the
SQL -like IoT Hub query language.
Use the following resources to learn how to:
Send telemetry from devices with the Get started with IoT Hub tutorial.
Control devices interactively (such as turning on a fan from a user-controlled app) with the Use direct methods
tutorial.
Get started with device twins (Python)
5/29/2018 • 10 min to read • Edit Online

Device twins are JSON documents that store device state information (metadata, configurations, and conditions).
IoT Hub persists a device twin for each device that connects to it.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use device twins to:


Store device metadata from your solution back end.
Report current state information such as available capabilities and conditions (for example, the connectivity
method used) from your device app.
Synchronize the state of long-running workflows (such as firmware and configuration updates) between a
device app and a back-end app.
Query your device metadata, configuration, or state.
Device twins are designed for synchronization and for querying device configurations and conditions. More
information on when to use device twins can be found in Understand device twins.
Device twins are stored in an IoT hub and contain:
tags, device metadata accessible only by the solution back end;
desired properties, JSON objects modifiable by the solution back end and observable by the device app; and
reported properties, JSON objects modifiable by the device app and readable by the solution back end. Tags and
properties cannot contain arrays, but objects can be nested.

Additionally, the solution back end can query device twins based on all the above data. Refer to Understand device
twins for more information about device twins, and to the IoT Hub query language reference for querying.
This tutorial shows you how to:
Create a back-end app that adds tags to a device twin, and a simulated device app that reports its connectivity
channel as a reported property on the device twin.
Query devices from your back-end app using filters on the tags and properties previously created.
At the end of this tutorial, you will have two Python console apps:
AddTagsAndQuery.py, a Python back-end app, which adds tags and queries device twins.
ReportConnectivity.py, a Python app, which simulates a device that connects to your IoT hub with the device
identity created earlier, and reports its connectivity condition.

NOTE
The article Azure IoT SDKs provides information about the Azure IoT SDKs that you can use to build both device and back-
end apps.

To complete this tutorial you need the following:


Python 2.x or 3.x. Make sure to use the 32-bit or 64-bit installation as required by your setup. When prompted
during the installation, make sure to add Python to your platform-specific environment variable. If you are using
Python 2.x, you may need to install or upgrade pip, the Python package management system.
If you are using Windows OS, then Visual C++ redistributable package to allow the use of native DLLs from
Python.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

NOTE
The pip packages for azure-iothub-service-client and azure-iothub-device-client are currently available only for
Windows OS. For Linux/Mac OS, please refer to the Linux and Mac OS-specific sections on the Prepare your development
environment for Python post.

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A device
cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the "Identity
registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a unique
device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new device
identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and keys
to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device. If your
application needs to store other device-specific metadata, it should use an application-specific store. For more information,
see IoT Hub developer guide.

Create the service app


In this section, you create a Python console app that adds location metadata to the device twin associated with your
{Device Id}. It then queries the device twins stored in the IoT hub selecting the devices located in Redmond, and
then the ones that are reporting a cellular connection.
1. Open a command prompt and install the Azure IoT Hub Service SDK for Python. Close the command
prompt after you install the SDK.

pip install azure-iothub-service-client

2. Using a text editor, create a new AddTagsAndQuery.py file.


3. Add the following code to import the required modules from the service SDK:

import sys
import iothub_service_client
from iothub_service_client import IoTHubRegistryManager, IoTHubRegistryManagerAuthMethod
from iothub_service_client import IoTHubDeviceTwin, IoTHubError

4. Add the following code, replacing the placeholder for [IoTHub Connection String] and [Device Id] with the
connection string for the IoT hub and the device id you created in the previous sections.

CONNECTION_STRING = "[IoTHub Connection String]"


DEVICE_ID = "[Device Id]"

UPDATE_JSON = "{\"properties\":{\"desired\":{\"location\":\"Redmond\"}}}"

UPDATE_JSON_SEARCH = "\"location\":\"Redmond\""
UPDATE_JSON_CLIENT_SEARCH = "\"connectivity\":\"cellular\""

5. Add the following code to the AddTagsAndQuery.py file:


def iothub_service_sample_run():
try:
iothub_registry_manager = IoTHubRegistryManager(CONNECTION_STRING)

iothub_registry_statistics = iothub_registry_manager.get_statistics()
print ( "Total device count :
{0}".format(iothub_registry_statistics.totalDeviceCount) )
print ( "Enabled device count :
{0}".format(iothub_registry_statistics.enabledDeviceCount) )
print ( "Disabled device count :
{0}".format(iothub_registry_statistics.disabledDeviceCount) )
print ( "" )

number_of_devices = iothub_registry_statistics.totalDeviceCount
dev_list = iothub_registry_manager.get_device_list(number_of_devices)

iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)

for device in range(0, number_of_devices):


if dev_list[device].deviceId == DEVICE_ID:
twin_info = iothub_twin_method.update_twin(dev_list[device].deviceId, UPDATE_JSON)

print ( "Devices in Redmond: " )


for device in range(0, number_of_devices):
twin_info = iothub_twin_method.get_twin(dev_list[device].deviceId)

if twin_info.find(UPDATE_JSON_SEARCH) > -1:


print ( dev_list[device].deviceId )

print ( "" )

print ( "Devices in Redmond using cellular network: " )


for device in range(0, number_of_devices):
twin_info = iothub_twin_method.get_twin(dev_list[device].deviceId)

if twin_info.find(UPDATE_JSON_SEARCH) > -1:


if twin_info.find(UPDATE_JSON_CLIENT_SEARCH) > -1:
print ( dev_list[device].deviceId )

except IoTHubError as iothub_error:


print ( "Unexpected error {0}".format(iothub_error) )
return
except KeyboardInterrupt:
print ( "IoTHub sample stopped" )

The Registry object exposes all the methods required to interact with device twins from the service. The
code first initializes the Registry object, then updates the device twin for deviceId, and finally runs two
queries. The first selects only the device twins of devices located in the Redmond43 plant, and the second
refines the query to select only the devices that are also connected through cellular network.
6. Add the following code at the end of AddTagsAndQuery.py to implement the
iothub_service_sample_run function:

if __name__ == '__main__':
print ( "Starting the IoT Hub Device Twins Python service sample..." )

iothub_service_sample_run()

7. Run the application with:

python AddTagsAndQuery.py
You should see one device in the results for the query asking for all devices located in Redmond43 and
none for the query that restricts the results to devices that use a cellular network.

In the next section, you create a device app that reports the connectivity information and changes the result of the
query in the previous section.

Create the device app


In this section, you create a Python console app that connects to your hub as your {Device Id}, and then updates
its device twin's reported properties to contain the information that it is connected using a cellular network.
1. Open a command prompt and install the Azure IoT Hub Service SDK for Python. Close the command
prompt after you install the SDK.

pip install azure-iothub-device-client

2. Using a text editor, create a new ReportConnectivity.py file.


3. Add the following code to import the required modules from the service SDK:

import time
import iothub_client
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult,
IoTHubError

4. Add the following code, replacing the placeholder for [IoTHub Device Connection String] with the
connection string for the IoT hub device you created in the previous sections.

CONNECTION_STRING = "[IoTHub Device Connection String]"

# choose HTTP, AMQP, AMQP_WS or MQTT as transport protocol


PROTOCOL = IoTHubTransportProvider.MQTT

TIMER_COUNT = 5
TWIN_CONTEXT = 0
SEND_REPORTED_STATE_CONTEXT = 0

5. Add the following code to the ReportConnectivity.py file to implement the device twins functionality:
def device_twin_callback(update_state, payload, user_context):
print ( "" )
print ( "Twin callback called with:" )
print ( " updateStatus: %s" % update_state )
print ( " payload: %s" % payload )

def send_reported_state_callback(status_code, user_context):


print ( "" )
print ( "Confirmation for reported state called with:" )
print ( " status_code: %d" % status_code )

def iothub_client_init():
client = IoTHubClient(CONNECTION_STRING, PROTOCOL)

if client.protocol == IoTHubTransportProvider.MQTT or client.protocol ==


IoTHubTransportProvider.MQTT_WS:
client.set_device_twin_callback(
device_twin_callback, TWIN_CONTEXT)

return client

def iothub_client_sample_run():
try:
client = iothub_client_init()

if client.protocol == IoTHubTransportProvider.MQTT:
print ( "Sending data as reported property..." )

reported_state = "{\"connectivity\":\"cellular\"}"

client.send_reported_state(reported_state, len(reported_state),
send_reported_state_callback, SEND_REPORTED_STATE_CONTEXT)

while True:
print ( "Press Ctrl-C to exit" )

status_counter = 0
while status_counter <= TIMER_COUNT:
status = client.get_send_status()
time.sleep(10)
status_counter += 1
except IoTHubError as iothub_error:
print ( "Unexpected error %s from IoTHub" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubClient sample stopped" )

The Client object exposes all the methods you require to interact with device twins from the device. The
previous code, after it initializes the Client object, retrieves the device twin for your device and updates its
reported property with the connectivity information.
6. Add the following code at the end of ReportConnectivity.py to implement the iothub_client_sample_run
function:

if __name__ == '__main__':
print ( "Starting the IoT Hub Device Twins Python client sample..." )

iothub_client_sample_run()

7. Run the device app

python ReportConnectivity.py
You should see confirmation the device twins were updated.

8. Now that the device reported its connectivity information, it should appear in both queries. Go back and run
the queries again:

python AddTagsAndQuery.py

This time your {Device Id} should appear in both query results.

Next steps
In this tutorial, you configured a new IoT hub in the Azure portal, and then created a device identity in the IoT hub's
identity registry. You added device metadata as tags from a back-end app, and wrote a simulated device app to
report device connectivity information in the device twin. You also learned how to query this information using the
registry.
Use the following resources to learn how to:
Send telemetry from devices with the Get started with IoT Hub tutorial,
Configure devices using device twin's desired properties with the Use desired properties to configure devices
tutorial,
Control devices interactively (such as turning on a fan from a user-controlled app), with the Use direct methods
tutorial.
Upload files from your device to the cloud with IoT
Hub using .NET
6/6/2018 • 5 min to read • Edit Online

This tutorial builds on the code in the Send Cloud-to-Device messages with IoT Hub tutorial to show you how to
use the file upload capabilities of IoT Hub. It shows you how to:
Securely provide a device with an Azure blob URI for uploading a file.
Use the IoT Hub file upload notifications to trigger processing the file in your app back end.
The Get started with IoT Hub and Send Cloud-to-Device messages with IoT Hub tutorials show the basic device-
to-cloud and cloud-to-device messaging functionality of IoT Hub. The Process Device-to-Cloud messages tutorial
describes a way to reliably store device-to-cloud messages in Azure blob storage. However, in some scenarios you
cannot easily map the data your devices send into the relatively small device-to-cloud messages that IoT Hub
accepts. For example:
Large files that contain images
Videos
Vibration data sampled at high frequency
Some form of preprocessed data
These files are typically batch processed in the cloud using tools such as Azure Data Factory or the Hadoop stack.
When you need to upload files from a device, you can still use the security and reliability of IoT Hub.
At the end of this tutorial you run two .NET console apps:
SimulatedDevice, a modified version of the app created in the Send Cloud-to-Device messages with IoT Hub
tutorial. This app uploads a file to storage using a SAS URI provided by your IoT hub.
ReadFileUploadNotification, which receives file upload notifications from your IoT hub.

NOTE
IoT Hub supports many device platforms and languages (including C, Java, and Javascript) through Azure IoT device SDKs.
Refer to the Azure IoT Developer Center for step-by-step instructions on how to connect your device to Azure IoT Hub.

To complete this tutorial, you need the following:


Visual Studio 2015 or Visual Studio 2017
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Associate an Azure Storage account to IoT Hub


Because the simulated device app uploads a file to a blob, you must have an Azure Storage account associated to
IoT Hub. When you associate an Azure Storage account with an IoT hub, the IoT hub generates a SAS URI. A
device can use this SAS URI to securely upload a file to a blob container. The IoT Hub service and the device SDKs
coordinate the process that generates the SAS URI and makes it available to a device to use to upload a file.
Follow the instructions in Configure file uploads using the Azure portal to associate an Azure Storage account to
your IoT hub. Make sure that a blob container is associated with your IoT hub and that file notifications are enabled.
Upload a file from a device app
In this section, you modify the device app you created in Send Cloud-to-Device messages with IoT Hub to receive
cloud-to-device messages from the IoT hub.
1. In Visual Studio, right-click the SimulatedDevice project, click Add, and then click Existing Item. Navigate
to an image file and include it in your project. This tutorial assumes the image is named image.jpg .
2. Right-click on the image, and then click Properties. Make sure that Copy to Output Directory is set to
Copy always.

3. In the Program.cs file, add the following statements at the top of the file:

using System.IO;

4. Add the following method to the Program class:


private static async void SendToBlobAsync()
{
string fileName = "image.jpg";
Console.WriteLine("Uploading file: {0}", fileName);
var watch = System.Diagnostics.Stopwatch.StartNew();

using (var sourceData = new FileStream(@"image.jpg", FileMode.Open))


{
await deviceClient.UploadToBlobAsync(fileName, sourceData);
}

watch.Stop();
Console.WriteLine("Time to upload file: {0}ms\n", watch.ElapsedMilliseconds);
}

The UploadToBlobAsync method takes in the file name and stream source of the file to be uploaded and
handles the upload to storage. The console app displays the time it takes to upload the file.
5. Add the following method in the Main method, right before the Console.ReadLine() line:

SendToBlobAsync();

NOTE
For simplicity's sake, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Receive a file upload notification


In this section, you write a .NET console app that receives file upload notification messages from IoT Hub.
1. In the current Visual Studio solution, create a Visual C# Windows project by using the Console
Application project template. Name the project ReadFileUploadNotification.
2. In Solution Explorer, right-click the ReadFileUploadNotification project, and then click Manage NuGet
Packages....
3. In the NuGet Package Manager window, search for Microsoft.Azure.Devices, click Install, and accept
the terms of use.
This action downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package in the
ReadFileUploadNotification project.
4. In the Program.cs file, add the following statements at the top of the file:

using Microsoft.Azure.Devices;

5. Add the following fields to the Program class. Substitute the placeholder value with the IoT hub connection
string from [Get started with IoT Hub]:

static ServiceClient serviceClient;


static string connectionString = "{iot hub connection string}";

6. Add the following method to the Program class:


private async static void ReceiveFileUploadNotificationAsync()
{
var notificationReceiver = serviceClient.GetFileNotificationReceiver();

Console.WriteLine("\nReceiving file upload notification from service");


while (true)
{
var fileUploadNotification = await notificationReceiver.ReceiveAsync();
if (fileUploadNotification == null) continue;

Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Received file upload noticiation: {0}", string.Join(", ",
fileUploadNotification.BlobName));
Console.ResetColor();

await notificationReceiver.CompleteAsync(fileUploadNotification);
}
}

Note this receive pattern is the same one used to receive cloud-to-device messages from the device app.
7. Finally, add the following lines to the Main method:

Console.WriteLine("Receive file upload notifications\n");


serviceClient = ServiceClient.CreateFromConnectionString(connectionString);
ReceiveFileUploadNotificationAsync();
Console.WriteLine("Press Enter to exit\n");
Console.ReadLine();

Run the applications


Now you are ready to run the applications.
1. In Visual Studio, right-click your solution, and select Set StartUp projects. Select Multiple startup
projects, then select the Start action for ReadFileUploadNotification and SimulatedDevice.
2. Press F5. Both applications should start. You should see the upload completed in one console app and the
upload notification message received by the other console app. You can use the Azure portal or Visual
Studio Server Explorer to check for the presence of the uploaded file in your Azure Storage account.
Next steps
In this tutorial, you learned how to use the file upload capabilities of IoT Hub to simplify file uploads from devices.
You can continue to explore IoT hub features and scenarios with the following articles:
Create an IoT hub programmatically
Introduction to C SDK
Azure IoT SDKs
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Upload files from your device to the cloud with IoT
Hub
6/6/2018 • 6 min to read • Edit Online

This tutorial builds on the code in the Send Cloud-to-Device messages with IoT Hub tutorial to show you how to
use the file upload capabilities of IoT Hub to upload a file to Azure blob storage. The tutorial shows you how to:
Securely provide a device with an Azure blob URI for uploading a file.
Use the IoT Hub file upload notifications to trigger processing the file in your app back end.
The Get started with IoT Hub and Send Cloud-to-Device messages with IoT Hub tutorials show the basic device-
to-cloud and cloud-to-device messaging functionality of IoT Hub. The Process Device-to-Cloud messages tutorial
describes a way to reliably store device-to-cloud messages in Azure blob storage. However, in some scenarios you
cannot easily map the data your devices send into the relatively small device-to-cloud messages that IoT Hub
accepts. For example:
Large files that contain images
Videos
Vibration data sampled at high frequency
Some form of preprocessed data.
These files are typically batch processed in the cloud using tools such as Azure Data Factory or the Hadoop stack.
When you need to upland files from a device, you can still use the security and reliability of IoT Hub.
At the end of this tutorial you run two Java console apps:
simulated-device, a modified version of the app created in the [Send Cloud-to-Device messages with IoT Hub]
tutorial. This app uploads a file to storage using a SAS URI provided by your IoT hub.
read-file-upload-notification, which receives file upload notifications from your IoT hub.

NOTE
IoT Hub supports many device platforms and languages (including C, .NET, and Javascript) through Azure IoT device SDKs.
Refer to the Azure IoT Developer Center for step-by-step instructions on how to connect your device to Azure IoT Hub.

To complete this tutorial, you need the following:


The latest Java SE Development Kit 8
Maven 3
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Associate an Azure Storage account to IoT Hub


Because the simulated device app uploads a file to a blob, you must have an Azure Storage account associated to
IoT Hub. When you associate an Azure Storage account with an IoT hub, the IoT hub generates a SAS URI. A
device can use this SAS URI to securely upload a file to a blob container. The IoT Hub service and the device SDKs
coordinate the process that generates the SAS URI and makes it available to a device to use to upload a file.
Follow the instructions in Configure file uploads using the Azure portal to associate an Azure Storage account to
your IoT hub. Make sure that a blob container is associated with your IoT hub and that file notifications are enabled.
Upload a file from a device app
In this section, you modify the device app you created in Send Cloud-to-Device messages with IoT Hub to upload a
file to IoT hub.
1. Copy an image file to the simulated-device folder and rename it myimage.png .
2. Using a text editor, open the simulated-device\src\main\java\com\mycompany\app\App.java file.
3. Add the variable declaration to the App class:

private static String fileName = "myimage.png";

4. To process file upload status callback messages, add the following nested class to the App class:

// Define a callback method to print status codes from IoT Hub.


protected static class FileUploadStatusCallBack implements IotHubEventCallback {
public void execute(IotHubStatusCode status, Object context) {
System.out.println("IoT Hub responded to file upload for " + fileName
+ " operation with status " + status.name());
}
}

5. To upload images to IoT Hub, add the following method to the App class to upload images to IoT Hub:
// Use IoT Hub to upload a file asynchronously to Azure blob storage.
private static void uploadFile(String fullFileName) throws FileNotFoundException, IOException
{
File file = new File(fullFileName);
InputStream inputStream = new FileInputStream(file);
long streamLength = file.length();

client.uploadToBlobAsync(fileName, inputStream, streamLength, new FileUploadStatusCallBack(), null);


}

6. Modify the main method to call the uploadFile method as shown in the following snippet:

client.open();

try
{
// Get the filename and start the upload.
String fullFileName = System.getProperty("user.dir") + File.separator + fileName;
uploadFile(fullFileName);
System.out.println("File upload started with success");
}
catch (Exception e)
{
System.out.println("Exception uploading file: " + e.getCause() + " \nERROR: " + e.getMessage());
}

MessageSender sender = new MessageSender();

7. Use the following command to build the simulated-device app and check for errors:

mvn clean package -DskipTests

Receive a file upload notification


In this section, you create a Java console app that receives file upload notification messages from IoT Hub.
You need the iothubowner connection string for your IoT Hub to complete this section. You can find the
connection string in the Azure portal on the Shared access policy blade.
1. Create a Maven project called read-file-upload-notification using the following command at your
command prompt. Note this command is a single, long command:

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=read-file-upload-notification -


DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2. At your command prompt, navigate to the new read-file-upload-notification folder.


3. Using a text editor, open the pom.xml file in the read-file-upload-notification folder and add the following
dependency to the dependencies node. Adding the dependency enables you to use the iothub-java-
service-client package in your application to communicate with your IoT hub service:

<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-service-client</artifactId>
<version>1.7.23</version>
</dependency>
NOTE
You can check for the latest version of iot-service-client using Maven search.

4. Save and close the pom.xml file.


5. Using a text editor, open the read-file-upload-notification\src\main\java\com\mycompany\app\App.java file.
6. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.service.*;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

7. Add the following class-level variables to the App class:

private static final String connectionString = "{Your IoT Hub connection string}";
private static final IotHubServiceClientProtocol protocol = IotHubServiceClientProtocol.AMQPS;
private static FileUploadNotificationReceiver fileUploadNotificationReceiver = null;

8. To print information about the file upload to the console, add the following nested class to the App class:

// Create a thread to receive file upload notifications.


private static class ShowFileUploadNotifications implements Runnable {
public void run() {
try {
while (true) {
System.out.println("Recieve file upload notifications...");
FileUploadNotification fileUploadNotification = fileUploadNotificationReceiver.receive();
if (fileUploadNotification != null) {
System.out.println("File Upload notification received");
System.out.println("Device Id : " + fileUploadNotification.getDeviceId());
System.out.println("Blob Uri: " + fileUploadNotification.getBlobUri());
System.out.println("Blob Name: " + fileUploadNotification.getBlobName());
System.out.println("Last Updated : " + fileUploadNotification.getLastUpdatedTimeDate());
System.out.println("Blob Size (Bytes): " + fileUploadNotification.getBlobSizeInBytes());
System.out.println("Enqueued Time: " + fileUploadNotification.getEnqueuedTimeUtcDate());
}
}
} catch (Exception ex) {
System.out.println("Exception reading reported properties: " + ex.getMessage());
}
}
}

9. To start the thread that listens for file upload notifications, add the following code to the main method:
public static void main(String[] args) throws IOException, URISyntaxException, Exception {
ServiceClient serviceClient = ServiceClient.createFromConnectionString(connectionString, protocol);

if (serviceClient != null) {
serviceClient.open();

// Get a file upload notification receiver from the ServiceClient.


fileUploadNotificationReceiver = serviceClient.getFileUploadNotificationReceiver();
fileUploadNotificationReceiver.open();

// Start the thread to receive file upload notifications.


ShowFileUploadNotifications showFileUploadNotifications = new ShowFileUploadNotifications();
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(showFileUploadNotifications);

System.out.println("Press ENTER to exit.");


System.in.read();
executor.shutdownNow();
System.out.println("Shutting down sample...");
fileUploadNotificationReceiver.close();
serviceClient.close();
}
}

10. Save and close the read-file-upload-notification\src\main\java\com\mycompany\app\App.java file.


11. Use the following command to build the read-file-upload-notification app and check for errors:

mvn clean package -DskipTests

Run the applications


Now you are ready to run the applications.
At a command prompt in the read-file-upload-notification folder, run the following command:

mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

At a command prompt in the simulated-device folder, run the following command:

mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

The following screenshot shows the output from the simulated-device app:
The following screenshot shows the output from the read-file-upload-notification app:

You can use the portal to view the uploaded file in the storage container you configured:
Next steps
In this tutorial, you learned how to use the file upload capabilities of IoT Hub to simplify file uploads from devices.
You can continue to explore IoT hub features and scenarios with the following articles:
Create an IoT hub programmatically
Introduction to C SDK
Azure IoT SDKs
To further explore the capabilities of IoT Hub, see:
Simulating a device with IoT Edge
Upload files from your device to the cloud with IoT
Hub
5/29/2018 • 5 min to read • Edit Online

This tutorial builds on the code in the Send Cloud-to-Device messages with IoT Hub tutorial to show you how to
use the file upload capabilities of IoT Hub to upload a file to Azure blob storage. The tutorial shows you how to:
Securely provide a device with an Azure blob URI for uploading a file.
Use the IoT Hub file upload notifications to trigger processing the file in your app back end.
The Get started with IoT Hub tutorial demonstrates the basic device-to-cloud messaging functionality of IoT Hub.
However, in some scenarios you cannot easily map the data your devices send into the relatively small device-to-
cloud messages that IoT Hub accepts. For example:
Large files that contain images
Videos
Vibration data sampled at high frequency
Some form of preprocessed data.
These files are typically batch processed in the cloud using tools such as Azure Data Factory or the Hadoop stack.
When you need to upland files from a device, you can still use the security and reliability of IoT Hub.
At the end of this tutorial you run two Node.js console apps:
SimulatedDevice.js, which uploads a file to storage using a SAS URI provided by your IoT hub.
ReadFileUploadNotification.js, which receives file upload notifications from your IoT hub.

NOTE
IoT Hub supports many device platforms and languages (including C, .NET, Javascript, Python, and Java) through Azure IoT
device SDKs. Refer to the Azure IoT Developer Center for step-by-step instructions on how to connect your device to Azure
IoT Hub.

To complete this tutorial, you need the following:


Node.js version 4.0.x or later.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Associate an Azure Storage account to IoT Hub


Because the simulated device app uploads a file to a blob, you must have an Azure Storage account associated to
IoT Hub. When you associate an Azure Storage account with an IoT hub, the IoT hub generates a SAS URI. A
device can use this SAS URI to securely upload a file to a blob container. The IoT Hub service and the device SDKs
coordinate the process that generates the SAS URI and makes it available to a device to use to upload a file.
Follow the instructions in Configure file uploads using the Azure portal to associate an Azure Storage account to
your IoT hub. Make sure that a blob container is associated with your IoT hub and that file notifications are enabled.
Upload a file from a device app
In this section, you create the device app to upload a file to IoT hub.
1. Create an empty folder called simulateddevice . In the simulateddevice folder, create a package.json file
using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the simulateddevice folder, run the following command to install the azure-
iot-device Device SDK package and azure-iot-device-mqtt package:

npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a SimulatedDevice.js file in the simulateddevice folder.


4. Add the following require statements at the start of the SimulatedDevice.js file:

'use strict';

var fs = require('fs');
var mqtt = require('azure-iot-device-mqtt').Mqtt;
var clientFromConnectionString = require('azure-iot-device-mqtt').clientFromConnectionString;

5. Add a deviceconnectionstring variable and use it to create a Client instance. Replace


{deviceconnectionstring} with the name of the device you created in the Create an IoT Hub section:
var connectionString = '{deviceconnectionstring}';
var filename = 'myimage.png';

NOTE
For the sake of simplicity the connection string is included in the code: this is not a recommended practice and
depending on your use-case and architecture you may want to consider more secure ways of storing this secret.

6. Add the following code to connect the client:

var client = clientFromConnectionString(connectionString);


console.log('Client connected');

7. Create a callback and use the uploadToBlob function to upload the file.

fs.stat(filename, function (err, stats) {


const rr = fs.createReadStream(filename);

client.uploadToBlob(filename, rr, stats.size, function (err) {


if (err) {
console.error('Error uploading file: ' + err.toString());
} else {
console.log('File uploaded');
}
});
});

8. Save and close the SimulatedDevice.js file.


9. Copy an image file to the simulateddevice folder and rename it myimage.png .

Receive a file upload notification


In this section, you create a Node.js console app that receives file upload notification messages from IoT Hub.
You can use the iothubowner connection string from your IoT Hub to complete this section. You will find the
connection string in the Azure portal on the Shared access policy blade.
1. Create an empty folder called fileuploadnotification . In the fileuploadnotification folder, create a
package.json file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the fileuploadnotification folder, run the following command to install the
azure-iothub SDK package:

npm install azure-iothub --save

3. Using a text editor, create a FileUploadNotification.js file in the fileuploadnotification folder.


4. Add the following require statements at the start of the FileUploadNotification.js file:
'use strict';

var Client = require('azure-iothub').Client;

5. Add a iothubconnectionstring variable and use it to create a Client instance. Replace


{iothubconnectionstring} with the connection string to the IoT hub you created in the Create an IoT Hub
section:

var connectionString = '{iothubconnectionstring}';

NOTE
For the sake of simplicity the connection string is included in the code: this is not a recommended practice and
depending on your use-case and architecture you may want to consider more secure ways of storing this secret.

6. Add the following code to connect the client:

var serviceClient = Client.fromConnectionString(connectionString);

7. Open the client and use the getFileNotificationReceiver function to receive status updates.

serviceClient.open(function (err) {
if (err) {
console.error('Could not connect: ' + err.message);
} else {
console.log('Service client connected');
serviceClient.getFileNotificationReceiver(function receiveFileUploadNotification(err, receiver){
if (err) {
console.error('error getting the file notification receiver: ' + err.toString());
} else {
receiver.on('message', function (msg) {
console.log('File upload from device:')
console.log(msg.getData().toString('utf-8'));
});
}
});
}
});

8. Save and close the FileUploadNotification.js file.

Run the applications


Now you are ready to run the applications.
At a command prompt in the fileuploadnotification folder, run the following command:

node FileUploadNotification.js

At a command prompt in the simulateddevice folder, run the following command:

node SimulatedDevice.js
The following screenshot shows the output from the SimulatedDevice app:

The following screenshot shows the output from the FileUploadNotification app:

You can use the portal to view the uploaded file in the storage container you configured:

Next steps
In this tutorial, you learned how to use the file upload capabilities of IoT Hub to simplify file uploads from devices.
You can continue to explore IoT hub features and scenarios with the following articles:
Create an IoT hub programmatically
Introduction to C SDK
Azure IoT SDKs
Upload files from your device to the cloud with IoT
Hub
5/29/2018 • 6 min to read • Edit Online

This tutorial follows how to use the file upload capabilities of IoT Hub to upload a file to Azure blob storage. The
tutorial shows you how to:
Securely provide a storage container for uploading a file.
Use the Python client to upload a file through your IoT hub.
The Get started with IoT Hub tutorial demonstrates the basic device-to-cloud messaging functionality of IoT Hub.
However, in some scenarios you cannot easily map the data your devices send into the relatively small device-to-
cloud messages that IoT Hub accepts. When you need to upland files from a device, you can still use the security
and reliability of IoT Hub.

NOTE
IoT Hub Python SDK currently only supports uploading character-based files such as .txt files.

At the end of this tutorial you run the Python console app:
FileUpload.py, which uploads a file to storage using the Python Device SDK.

NOTE
IoT Hub supports many device platforms and languages (including C, .NET, Javascript, Python, and Java) through Azure IoT
device SDKs. Refer to the Azure IoT Developer Center for step-by-step instructions on how to connect your device to Azure
IoT Hub.

To complete this tutorial, you need the following:


Python 2.x or 3.x. Make sure to use the 32-bit or 64-bit installation as required by your setup. When prompted
during the installation, make sure to add Python to your platform-specific environment variable. If you are using
Python 2.x, you may need to install or upgrade pip, the Python package management system.
If you are using Windows OS, then Visual C++ redistributable package to allow the use of native DLLs from
Python.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A device
cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the "Identity
registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a unique
device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new device
identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and keys
to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device. If your
application needs to store other device-specific metadata, it should use an application-specific store. For more information,
see IoT Hub developer guide.

Associate an Azure Storage account to IoT Hub


Because the simulated device app uploads a file to a blob, you must have an Azure Storage account associated to
IoT Hub. When you associate an Azure Storage account with an IoT hub, the IoT hub generates a SAS URI. A
device can use this SAS URI to securely upload a file to a blob container. The IoT Hub service and the device SDKs
coordinate the process that generates the SAS URI and makes it available to a device to use to upload a file.
Follow the instructions in Configure file uploads using the Azure portal to associate an Azure Storage account to
your IoT hub. Make sure that a blob container is associated with your IoT hub and that file notifications are enabled.
Upload a file from a device app
In this section, you create the device app to upload a file to IoT hub.
1. At your command prompt, run the following command to install the azure-iothub-device-client package:

pip install azure-iothub-device-client

2. Using a text editor, create a FileUpload.py file in your working folder.


3. Add the following import statements and variables at the start of the FileUpload.py file. Replace
deviceConnectionString with the connection string of your IoT hub device:

import time
import sys
import iothub_client
import os
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult,
IoTHubError

CONNECTION_STRING = "[Device Connection String]"


PROTOCOL = IoTHubTransportProvider.HTTP

PATHTOFILE = "[Full path to file]"


FILENAME = "[File name on storage after upload]"

4. Create a callback for the upload_blob function:


def blob_upload_conf_callback(result, user_context):
if str(result) == 'OK':
print ( "...file uploaded successfully." )
else:
print ( "...file upload callback returned: " + str(result) )

5. Add the following code to connect the client and upload the file. Also include the main routine:

def iothub_file_upload_sample_run():
try:
print ( "IoT Hub file upload sample, press Ctrl-C to exit" )

client = IoTHubClient(CONNECTION_STRING, PROTOCOL)

f = open(PATHTOFILE, "r")
content = f.read()

client.upload_blob_async(FILENAME, content, len(content), blob_upload_conf_callback, 0)

print ( "" )
print ( "File upload initiated..." )

while True:
time.sleep(30)

except IoTHubError as iothub_error:


print ( "Unexpected error %s from IoTHub" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubClient sample stopped" )
except:
print ( "generic error" )

if __name__ == '__main__':
print ( "Simulating a file upload using the Azure IoT Hub Device SDK for Python" )
print ( " Protocol %s" % PROTOCOL )
print ( " Connection string=%s" % CONNECTION_STRING )

iothub_file_upload_sample_run()

6. Save and close the UploadFile.py file.


7. Copy a sample text file to the working folder and rename it sample.txt .

NOTE
IoT Hub Python SDK currently only supports uploading character-based files such as .txt files.

Run the application


Now you are ready to run the application.
1. At a command prompt in your working folder, run the following command:

python FileUpload.py

2. The following screenshot shows the output from the FileUpload app:
3. You can use the portal to view the uploaded file in the storage container you configured:

Next steps
In this tutorial, you learned how to use the file upload capabilities of IoT Hub to simplify file uploads from devices.
You can continue to explore IoT hub features and scenarios with the following articles:
Create an IoT hub programmatically
Introduction to C SDK
Azure IoT SDKs
Get started with device twins (Node)
5/29/2018 • 9 min to read • Edit Online

Device twins are JSON documents that store device state information (metadata, configurations, and
conditions). IoT Hub persists a device twin for each device that connects to it.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use device twins to:


Store device metadata from your solution back end.
Report current state information such as available capabilities and conditions (for example, the connectivity
method used) from your device app.
Synchronize the state of long-running workflows (such as firmware and configuration updates) between a
device app and a back-end app.
Query your device metadata, configuration, or state.
Device twins are designed for synchronization and for querying device configurations and conditions. More
information on when to use device twins can be found in Understand device twins.
Device twins are stored in an IoT hub and contain:
tags, device metadata accessible only by the solution back end;
desired properties, JSON objects modifiable by the solution back end and observable by the device app; and
reported properties, JSON objects modifiable by the device app and readable by the solution back end. Tags
and properties cannot contain arrays, but objects can be nested.

Additionally, the solution back end can query device twins based on all the above data. Refer to Understand
device twins for more information about device twins, and to the IoT Hub query language reference for
querying.
This tutorial shows you how to:
Create a back-end app that adds tags to a device twin, and a simulated device app that reports its
connectivity channel as a reported property on the device twin.
Query devices from your back-end app using filters on the tags and properties previously created.
At the end of this tutorial, you will have two Node.js console apps:
AddTagsAndQuery.js, a Node.js back-end app, which adds tags and queries device twins.
TwinSimulatedDevice.js, a Node.js app, which simulates a device that connects to your IoT hub with the
device identity created earlier, and reports its connectivity condition.

NOTE
The article Azure IoT SDKs provides information about the Azure IoT SDKs that you can use to build both device and
back-end apps.

To complete this tutorial you need the following:


Node.js version 4.0.x or later.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create.
You can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."
Create a device identity
In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device
IDs are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with the
IoT Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to
avoid any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the device
app to connect to your IoT Hub as a device.

Refer to Getting started with IoT Hub to programmatically create device identities.

Create the service app


In this section, you create a Node.js console app that adds location metadata to the device twin associated with
myDeviceId. It then queries the device twins stored in the IoT hub selecting the devices located in the US, and
then the ones that are reporting a cellular connection.
1. Create a new empty folder called addtagsandqueryapp. In the addtagsandqueryapp folder, create a
new package.json file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the addtagsandqueryapp folder, run the following command to install the
azure-iothub package:
npm install azure-iothub --save

3. Using a text editor, create a new AddTagsAndQuery.js file in the addtagsandqueryapp folder.
4. Add the following code to the AddTagsAndQuery.js file, and substitute the {iot hub connection
string} placeholder with the IoT Hub connection string you copied when you created your hub:

'use strict';
var iothub = require('azure-iothub');
var connectionString = '{iot hub connection string}';
var registry = iothub.Registry.fromConnectionString(connectionString);

registry.getTwin('myDeviceId', function(err, twin){


if (err) {
console.error(err.constructor.name + ': ' + err.message);
} else {
var patch = {
tags: {
location: {
region: 'US',
plant: 'Redmond43'
}
}
};

twin.update(patch, function(err) {
if (err) {
console.error('Could not update twin: ' + err.constructor.name + ': ' + err.message);
} else {
console.log(twin.deviceId + ' twin updated successfully');
queryTwins();
}
});
}
});

The Registry object exposes all the methods required to interact with device twins from the service. The
previous code first initializes the Registry object, then retrieves the device twin for myDeviceId, and
finally updates its tags with the desired location information.
After updating the tags it calls the queryTwins function.
5. Add the following code at the end of AddTagsAndQuery.js to implement the queryTwins function:
var queryTwins = function() {
var query = registry.createQuery("SELECT * FROM devices WHERE tags.location.plant =
'Redmond43'", 100);
query.nextAsTwin(function(err, results) {
if (err) {
console.error('Failed to fetch the results: ' + err.message);
} else {
console.log("Devices in Redmond43: " + results.map(function(twin) {return
twin.deviceId}).join(','));
}
});

query = registry.createQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43' AND


properties.reported.connectivity.type = 'cellular'", 100);
query.nextAsTwin(function(err, results) {
if (err) {
console.error('Failed to fetch the results: ' + err.message);
} else {
console.log("Devices in Redmond43 using cellular network: " + results.map(function(twin)
{return twin.deviceId}).join(','));
}
});
};

The previous code executes two queries: the first selects only the device twins of devices located in the
Redmond43 plant, and the second refines the query to select only the devices that are also connected
through cellular network.
The previous code, when it creates the query object, specifies a maximum number of returned
documents. The query object contains a hasMoreResults boolean property that you can use to invoke
the nextAsTwin methods multiple times to retrieve all results. A method called next is available for
results that are not device twins, for example, results of aggregation queries.
6. Run the application with:

node AddTagsAndQuery.js

You should see one device in the results for the query asking for all devices located in Redmond43 and
none for the query that restricts the results to devices that use a cellular network.

In the next section, you create a device app that reports the connectivity information and changes the result of
the query in the previous section.

Create the device app


In this section, you create a Node.js console app that connects to your hub as myDeviceId, and then updates
its device twin's reported properties to contain the information that it is connected using a cellular network.
1. Create a new empty folder called reportconnectivity. In the reportconnectivity folder, create a new
package.json file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the reportconnectivity folder, run the following command to install the
azure-iot-device, and azure-iot-device-mqtt package:

npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a new ReportConnectivity.js file in the reportconnectivity folder.
4. Add the following code to the ReportConnectivity.js file, and substitute the {device connection
string} placeholder with the device connection string you copied when you created the myDeviceId
device identity:

'use strict';
var Client = require('azure-iot-device').Client;
var Protocol = require('azure-iot-device-mqtt').Mqtt;

var connectionString = '{device connection string}';


var client = Client.fromConnectionString(connectionString, Protocol);

client.open(function(err) {
if (err) {
console.error('could not open IotHub client');
} else {
console.log('client opened');

client.getTwin(function(err, twin) {
if (err) {
console.error('could not get twin');
} else {
var patch = {
connectivity: {
type: 'cellular'
}
};

twin.properties.reported.update(patch, function(err) {
if (err) {
console.error('could not update twin');
} else {
console.log('twin state reported');
process.exit();
}
});
}
});
}
});

The Client object exposes all the methods you require to interact with device twins from the device. The
previous code, after it initializes the Client object, retrieves the device twin for myDeviceId and updates
its reported property with the connectivity information.
5. Run the device app

node ReportConnectivity.js

You should see the message twin state reported .


6. Now that the device reported its connectivity information, it should appear in both queries. Go back in
the addtagsandqueryapp folder and run the queries again:

node AddTagsAndQuery.js
This time myDeviceId should appear in both query results.

Next steps
In this tutorial, you configured a new IoT hub in the Azure portal, and then created a device identity in the IoT
hub's identity registry. You added device metadata as tags from a back-end app, and wrote a simulated device
app to report device connectivity information in the device twin. You also learned how to query this information
using the SQL -like IoT Hub query language.
Use the following resources to learn how to:
send telemetry from devices with the Get started with IoT Hub tutorial,
configure devices using device twin's desired properties with the Use desired properties to configure devices
tutorial,
control devices interactively (such as turning on a fan from a user-controlled app), with the Use direct
methods tutorial.
Get started with device twins (.NET/Node)
5/29/2018 • 9 min to read • Edit Online

Device twins are JSON documents that store device state information (metadata, configurations, and conditions).
IoT Hub persists a device twin for each device that connects to it.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use device twins to:


Store device metadata from your solution back end.
Report current state information such as available capabilities and conditions (for example, the connectivity
method used) from your device app.
Synchronize the state of long-running workflows (such as firmware and configuration updates) between a
device app and a back-end app.
Query your device metadata, configuration, or state.
Device twins are designed for synchronization and for querying device configurations and conditions. More
information on when to use device twins can be found in Understand device twins.
Device twins are stored in an IoT hub and contain:
tags, device metadata accessible only by the solution back end;
desired properties, JSON objects modifiable by the solution back end and observable by the device app; and
reported properties, JSON objects modifiable by the device app and readable by the solution back end. Tags
and properties cannot contain arrays, but objects can be nested.

Additionally, the solution back end can query device twins based on all the above data. Refer to Understand
device twins for more information about device twins, and to the IoT Hub query language reference for querying.
This tutorial shows you how to:
Create a back-end app that adds tags to a device twin, and a simulated device app that reports its connectivity
channel as a reported property on the device twin.
Query devices from your back-end app using filters on the tags and properties previously created.
At the end of this tutorial, you will have a .NET and a Node.js console app:
AddTagsAndQuery.sln, a .NET back-end app, which adds tags and queries device twins.
TwinSimulatedDevice.js, a Node.js app which simulates a device that connects to your IoT hub with the
device identity created earlier, and reports its connectivity condition.

NOTE
The article Azure IoT SDKs provides information about the Azure IoT SDKs that you can use to build both device and back-
end apps.

To complete this tutorial you need the following:


Visual Studio 2015 or Visual Studio 2017.
Node.js version 4.0.x or later.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."
Create a device identity
In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device IDs
are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with the
IoT Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the device
app to connect to your IoT Hub as a device.

Refer to Getting started with IoT Hub to programmatically create device identities.

Create the service app


In this section, you create a .NET console app (using C#) that adds location metadata to the device twin
associated with myDeviceId. It then queries the device twins stored in the IoT hub selecting the devices located
in the US, and then the ones that reported a cellular connection.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project AddTagsAndQuery.
2. In Solution Explorer, right-click the AddTagsAndQuery project, and then click Manage NuGet Packages....
3. In the NuGet Package Manager window, select Browse and search for microsoft.azure.devices. Select
Install to install the Microsoft.Azure.Devices package, and accept the terms of use. This procedure
downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package and its
dependencies.

4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;

5. Add the following fields to the Program class. Replace the placeholder value with the IoT Hub connection
string for the hub that you created in the previous section.

static RegistryManager registryManager;


static string connectionString = "{iot hub connection string}";
6. Add the following method to the Program class:

public static async Task AddTagsAndQuery()


{
var twin = await registryManager.GetTwinAsync("myDeviceId");
var patch =
@"{
tags: {
location: {
region: 'US',
plant: 'Redmond43'
}
}
}";
await registryManager.UpdateTwinAsync(twin.DeviceId, patch, twin.ETag);

var query = registryManager.CreateQuery("SELECT * FROM devices WHERE tags.location.plant =


'Redmond43'", 100);
var twinsInRedmond43 = await query.GetNextAsTwinAsync();
Console.WriteLine("Devices in Redmond43: {0}", string.Join(", ", twinsInRedmond43.Select(t =>
t.DeviceId)));

query = registryManager.CreateQuery("SELECT * FROM devices WHERE tags.location.plant =


'Redmond43' AND properties.reported.connectivity.type = 'cellular'", 100);
var twinsInRedmond43UsingCellular = await query.GetNextAsTwinAsync();
Console.WriteLine("Devices in Redmond43 using cellular network: {0}", string.Join(", ",
twinsInRedmond43UsingCellular.Select(t => t.DeviceId)));
}

The RegistryManager class exposes all the methods required to interact with device twins from the
service. The previous code first initializes the registryManager object, then retrieves the device twin for
myDeviceId, and finally updates its tags with the desired location information.
After updating, it executes two queries: the first selects only the device twins of devices located in the
Redmond43 plant, and the second refines the query to select only the devices that are also connected
through cellular network.
Note that the previous code, when it creates the query object, specifies a maximum number of returned
documents. The query object contains a HasMoreResults boolean property that you can use to invoke
the GetNextAsTwinAsync methods multiple times to retrieve all results. A method called
GetNextAsJson is available for results that are not device twins, for example, results of aggregation
queries.
7. Finally, add the following lines to the Main method:

registryManager = RegistryManager.CreateFromConnectionString(connectionString);
AddTagsAndQuery().Wait();
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();

8. In the Solution Explorer, open the Set StartUp projects... and make sure the Action for
AddTagsAndQuery project is Start. Build the solution.
9. Run this application by right-clicking on the AddTagsAndQuery project and selecting Debug, followed
by Start new instance. You should see one device in the results for the query asking for all devices
located in Redmond43 and none for the query that restricts the results to devices that use a cellular
network.
In the next section, you create a device app that reports the connectivity information and changes the result of the
query in the previous section.

Create the device app


In this section, you create a Node.js console app that connects to your hub as myDeviceId, and then updates its
reported properties to contain the information that it is connected using a cellular network.
1. Create a new empty folder called reportconnectivity. In the reportconnectivity folder, create a new
package.json file using the following command at your command prompt. Accept all the defaults.

npm init

2. At your command prompt in the reportconnectivity folder, run the following command to install the
azure-iot-device, and azure-iot-device-mqtt package:

npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a new ReportConnectivity.js file in the reportconnectivity folder.
4. Add the following code to the ReportConnectivity.js file, and substitute the placeholder for device
connection string with the one you copied when you created the myDeviceId device identity:
'use strict';
var Client = require('azure-iot-device').Client;
var Protocol = require('azure-iot-device-mqtt').Mqtt;

var connectionString = '{device connection string}';


var client = Client.fromConnectionString(connectionString, Protocol);

client.open(function(err) {
if (err) {
console.error('could not open IotHub client');
} else {
console.log('client opened');

client.getTwin(function(err, twin) {
if (err) {
console.error('could not get twin');
} else {
var patch = {
connectivity: {
type: 'cellular'
}
};

twin.properties.reported.update(patch, function(err) {
if (err) {
console.error('could not update twin');
} else {
console.log('twin state reported');
process.exit();
}
});
}
});
}
});

The Client object exposes all the methods you require to interact with device twins from the device. The
previous code, after it initializes the Client object, retrieves the device twin for myDeviceId and updates
its reported property with the connectivity information.
5. Run the device app

node ReportConnectivity.js

You should see the message twin state reported .


6. Now that the device reported its connectivity information, it should appear in both queries. Run the .NET
AddTagsAndQuery app to run the queries again. This time myDeviceId should appear in both query
results.

Next steps
In this tutorial, you configured a new IoT hub in the Azure portal, and then created a device identity in the IoT
hub's identity registry. You added device metadata as tags from a back-end app, and wrote a simulated device
app to report device connectivity information in the device twin. You also learned how to query this information
using the SQL -like IoT Hub query language.
Use the following resources to learn how to:
send telemetry from devices with the Get started with IoT Hub tutorial,
configure devices using device twin's desired properties with the Use desired properties to configure devices
tutorial,
control devices interactively (such as turning on a fan from a user-controlled app) with the Use direct methods
tutorial.
Get started with device twins (.NET/.NET)
5/29/2018 • 10 min to read • Edit Online

Device twins are JSON documents that store device state information (metadata, configurations, and conditions).
IoT Hub persists a device twin for each device that connects to it.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use device twins to:


Store device metadata from your solution back end.
Report current state information such as available capabilities and conditions (for example, the connectivity
method used) from your device app.
Synchronize the state of long-running workflows (such as firmware and configuration updates) between a
device app and a back-end app.
Query your device metadata, configuration, or state.
Device twins are designed for synchronization and for querying device configurations and conditions. More
information on when to use device twins can be found in Understand device twins.
Device twins are stored in an IoT hub and contain:
tags, device metadata accessible only by the solution back end;
desired properties, JSON objects modifiable by the solution back end and observable by the device app; and
reported properties, JSON objects modifiable by the device app and readable by the solution back end. Tags
and properties cannot contain arrays, but objects can be nested.

Additionally, the solution back end can query device twins based on all the above data. Refer to Understand
device twins for more information about device twins, and to the IoT Hub query language reference for
querying.
This tutorial shows you how to:
Create a back-end app that adds tags to a device twin, and a simulated device app that reports its connectivity
channel as a reported property on the device twin.
Query devices from your back-end app using filters on the tags and properties previously created.
At the end of this tutorial, you will have these .NET console apps:
CreateDeviceIdentity, a .NET app which creates a device identity and associated security key to connect
your simulated device app.
AddTagsAndQuery, a .NET back-end app which adds tags and queries device twins.
ReportConnectivity, a .NET device app which simulates a device that connects to your IoT hub with the
device identity created earlier, and reports its connectivity condition.

NOTE
The article Azure IoT SDKs provides information about the Azure IoT SDKs that you can use to build both device and back-
end apps.

To complete this tutorial you need the following:


Visual Studio 2015 or Visual Studio 2017.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A
device cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the
"Identity registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a
unique device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new
device identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use
later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and
keys to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device.
If your application needs to store other device-specific metadata, it should use an application-specific store. For more
information, see IoT Hub developer guide.

Create the service app


In this section, you create a .NET console app (using C#) that adds location metadata to the device twin
associated with myDeviceId. It then queries the device twins stored in the IoT hub selecting the devices located
in the US, and then the ones that reported a cellular connection.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project AddTagsAndQuery.

2. In Solution Explorer, right-click the AddTagsAndQuery project, and then click Manage NuGet Packages....
3. In the NuGet Package Manager window, select Browse and search for microsoft.azure.devices.
Select Install to install the Microsoft.Azure.Devices package, and accept the terms of use. This
procedure downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package and its
dependencies.

4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;

5. Add the following fields to the Program class. Replace the placeholder value with the IoT Hub connection
string for the hub that you created in the previous section.

static RegistryManager registryManager;


static string connectionString = "{iot hub connection string}";

6. Add the following method to the Program class:

public static async Task AddTagsAndQuery()


{
var twin = await registryManager.GetTwinAsync("myDeviceId");
var patch =
@"{
tags: {
location: {
region: 'US',
plant: 'Redmond43'
}
}
}";
await registryManager.UpdateTwinAsync(twin.DeviceId, patch, twin.ETag);

var query = registryManager.CreateQuery("SELECT * FROM devices WHERE tags.location.plant =


'Redmond43'", 100);
var twinsInRedmond43 = await query.GetNextAsTwinAsync();
Console.WriteLine("Devices in Redmond43: {0}", string.Join(", ", twinsInRedmond43.Select(t =>
t.DeviceId)));

query = registryManager.CreateQuery("SELECT * FROM devices WHERE tags.location.plant =


'Redmond43' AND properties.reported.connectivity.type = 'cellular'", 100);
var twinsInRedmond43UsingCellular = await query.GetNextAsTwinAsync();
Console.WriteLine("Devices in Redmond43 using cellular network: {0}", string.Join(", ",
twinsInRedmond43UsingCellular.Select(t => t.DeviceId)));
}

The RegistryManager class exposes all the methods required to interact with device twins from the
service. The previous code first initializes the registryManager object, then retrieves the device twin for
myDeviceId, and finally updates its tags with the desired location information.
After updating, it executes two queries: the first selects only the device twins of devices located in the
Redmond43 plant, and the second refines the query to select only the devices that are also connected
through cellular network.
Note that the previous code, when it creates the query object, specifies a maximum number of returned
documents. The query object contains a HasMoreResults boolean property that you can use to invoke
the GetNextAsTwinAsync methods multiple times to retrieve all results. A method called
GetNextAsJson is available for results that are not device twins, for example, results of aggregation
queries.
7. Finally, add the following lines to the Main method:

registryManager = RegistryManager.CreateFromConnectionString(connectionString);
AddTagsAndQuery().Wait();
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();

8. In the Solution Explorer, open the Set StartUp projects... and make sure the Action for
AddTagsAndQuery project is Start. Build the solution.
9. Run this application by right-clicking on the AddTagsAndQuery project and selecting Debug, followed
by Start new instance. You should see one device in the results for the query asking for all devices
located in Redmond43 and none for the query that restricts the results to devices that use a cellular
network.

In the next section, you create a device app that reports the connectivity information and changes the result of
the query in the previous section.

Create the device app


In this section, you create a .NET console app that connects to your hub as myDeviceId, and then updates its
reported properties to contain the information that it is connected using a cellular network.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project ReportConnectivity.
2. In Solution Explorer, right-click the ReportConnectivity project, and then click Manage NuGet
Packages....
3. In the NuGet Package Manager window, select Browse and search for
microsoft.azure.devices.client. Select Install to install the Microsoft.Azure.Devices.Client package,
and accept the terms of use. This procedure downloads, installs, and adds a reference to the Azure IoT
device SDK NuGet package and its dependencies.

4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;
using Newtonsoft.Json;

5. Add the following fields to the Program class. Replace the placeholder value with the device connection
string that you noted in the previous section.

static string DeviceConnectionString = "HostName=<yourIotHubName>.azure-devices.net;DeviceId=


<yourIotDeviceName>;SharedAccessKey=<yourIotDeviceAccessKey>";
static DeviceClient Client = null;

6. Add the following method to the Program class:


public static async void InitClient()
{
try
{
Console.WriteLine("Connecting to hub");
Client = DeviceClient.CreateFromConnectionString(DeviceConnectionString, TransportType.Mqtt);
Console.WriteLine("Retrieving twin");
await Client.GetTwinAsync();
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}
}

The Client object exposes all the methods you require to interact with device twins from the device. The
code shown above, initializes the Client object, and then retrieves the device twin for myDeviceId.
7. Add the following method to the Program class:

public static async void ReportConnectivity()


{
try
{
Console.WriteLine("Sending connectivity data as reported property");

TwinCollection reportedProperties, connectivity;


reportedProperties = new TwinCollection();
connectivity = new TwinCollection();
connectivity["type"] = "cellular";
reportedProperties["connectivity"] = connectivity;
await Client.UpdateReportedPropertiesAsync(reportedProperties);
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}
}

The code above updates myDeviceId's reported property with the connectivity information.
8. Finally, add the following lines to the Main method:

try
{
InitClient();
ReportConnectivity();
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();

9. In the Solution Explorer, open the Set StartUp projects... and make sure the Action for
ReportConnectivity project is Start. Build the solution.
10. Run this application by right-clicking on the ReportConnectivity project and selecting Debug, followed
by Start new instance. You should see it getting the twin information, and then sending connectivity as a
reported property.

11. Now that the device reported its connectivity information, it should appear in both queries. Run the .NET
AddTagsAndQuery app to run the queries again. This time myDeviceId should appear in both query
results.

Next steps
In this tutorial, you configured a new IoT hub in the Azure portal, and then created a device identity in the IoT
hub's identity registry. You added device metadata as tags from a back-end app, and wrote a simulated device
app to report device connectivity information in the device twin. You also learned how to query this information
using the SQL -like IoT Hub query language.
Use the following resources to learn how to:
send telemetry from devices with the Get started with IoT Hub tutorial,
configure devices using device twin's desired properties with the Use desired properties to configure devices
tutorial,
control devices interactively (such as turning on a fan from a user-controlled app) with the Use direct methods
tutorial.
Get started with device twins (Java)
5/29/2018 • 11 min to read • Edit Online

Device twins are JSON documents that store device state information (metadata, configurations, and conditions).
IoT Hub persists a device twin for each device that connects to it.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use device twins to:


Store device metadata from your solution back end.
Report current state information such as available capabilities and conditions (for example, the connectivity
method used) from your device app.
Synchronize the state of long-running workflows (such as firmware and configuration updates) between a
device app and a back-end app.
Query your device metadata, configuration, or state.
Device twins are designed for synchronization and for querying device configurations and conditions. More
information on when to use device twins can be found in Understand device twins.
Device twins are stored in an IoT hub and contain:
tags, device metadata accessible only by the solution back end;
desired properties, JSON objects modifiable by the solution back end and observable by the device app; and
reported properties, JSON objects modifiable by the device app and readable by the solution back end. Tags
and properties cannot contain arrays, but objects can be nested.

Additionally, the solution back end can query device twins based on all the above data. Refer to Understand
device twins for more information about device twins, and to the IoT Hub query language reference for
querying.
This tutorial shows you how to:
Create a back-end app that adds tags to a device twin, and a simulated device app that reports its connectivity
channel as a reported property on the device twin.
Query devices from your back-end app using filters on the tags and properties previously created.
In this tutorial, you create two Java console apps:
add-tags-query, a Java back-end app that adds tags and queries device twins.
simulated-device, a Java device app that that connects to your IoT hub and reports its connectivity
condition using a reported property.

NOTE
The article Azure IoT SDKs provides information about the Azure IoT SDKs that you can use to build both device and back-
end apps.

To complete this tutorial, you need:


The latest Java SE Development Kit 8
Maven 3
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."
Create a device identity
In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A
device cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the
"Identity registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a
unique device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.

4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new
device identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.
5. In the device list, click the newly created device and copy the Connection string---primary key to use
later.

NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and
keys to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device.
If your application needs to store other device-specific metadata, it should use an application-specific store. For more
information, see IoT Hub developer guide.

Create the service app


In this section, you create a Java app that adds location metadata as a tag to the device twin in IoT Hub
associated with myDeviceId. The app first queries IoT hub for devices located in the US, and then for devices
that report a cellular network connection.
1. On your development machine, create an empty folder called iot-java-twin-getstarted .
2. In the iot-java-twin-getstarted folder, create a Maven project called add-tags-query using the
following command at your command prompt. Note this is a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=add-tags-query -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
3. At your command prompt, navigate to the add-tags-query folder.
4. Using a text editor, open the pom.xml file in the add-tags-query folder and add the following dependency
to the dependencies node. This dependency enables you to use the iot-service-client package in your
app to communicate with your IoT hub:

<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-service-client</artifactId>
<version>1.7.23</version>
<type>jar</type>
</dependency>

NOTE
You can check for the latest version of iot-service-client using Maven search.

5. Add the following build node after the dependencies node. This configuration instructs Maven to use
Java 1.8 to build the app:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

6. Save and close the pom.xml file.


7. Using a text editor, open the add-tags-query\src\main\java\com\mycompany\app\App.java file.
8. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.service.devicetwin.*;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

9. Add the following class-level variables to the App class. Replace {youriothubconnectionstring} with your
IoT hub connection string you noted in the Create an IoT Hub section:

public static final String iotHubConnectionString = "{youriothubconnectionstring}";


public static final String deviceId = "myDeviceId";

public static final String region = "US";


public static final String plant = "Redmond43";

10. Update the main method signature to include the following throws clause:
public static void main( String[] args ) throws IOException

11. Add the following code to the main method to create the DeviceTwin and DeviceTwinDevice objects.
The DeviceTwin object handles the communication with your IoT hub. The DeviceTwinDevice object
represents the device twin with its properties and tags:

// Get the DeviceTwin and DeviceTwinDevice objects


DeviceTwin twinClient = DeviceTwin.createFromConnectionString(iotHubConnectionString);
DeviceTwinDevice device = new DeviceTwinDevice(deviceId);

12. Add the following try/catch block to the main method:

try {
// Code goes here
} catch (IotHubException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}

13. To update the region and plant device twin tags in your device twin, add the following code in the try
block:

// Get the device twin from IoT Hub


System.out.println("Device twin before update:");
twinClient.getTwin(device);
System.out.println(device);

// Update device twin tags if they are different


// from the existing values
String currentTags = device.tagsToString();
if ((!currentTags.contains("region=" + region) && !currentTags.contains("plant=" + plant))) {
// Create the tags and attach them to the DeviceTwinDevice object
Set<Pair> tags = new HashSet<Pair>();
tags.add(new Pair("region", region));
tags.add(new Pair("plant", plant));
device.setTags(tags);

// Update the device twin in IoT Hub


System.out.println("Updating device twin");
twinClient.updateTwin(device);
}

// Retrieve the device twin with the tag values from IoT Hub
System.out.println("Device twin after update:");
twinClient.getTwin(device);
System.out.println(device);

14. To query the device twins in IoT hub, add the following code to the try block after the code you added in
the previous step. The code runs two queries. Each query returns a maximum of 100 devices:
// Query the device twins in IoT Hub
System.out.println("Devices in Redmond:");

// Construct the query


SqlQuery sqlQuery = SqlQuery.createSqlQuery("*", SqlQuery.FromType.DEVICES, "tags.plant='Redmond43'",
null);

// Run the query, returning a maximum of 100 devices


Query twinQuery = twinClient.queryTwin(sqlQuery.getQuery(), 100);
while (twinClient.hasNextDeviceTwin(twinQuery)) {
DeviceTwinDevice d = twinClient.getNextDeviceTwin(twinQuery);
System.out.println(d.getDeviceId());
}

System.out.println("Devices in Redmond using a cellular network:");

// Construct the query


sqlQuery = SqlQuery.createSqlQuery("*", SqlQuery.FromType.DEVICES, "tags.plant='Redmond43' AND
properties.reported.connectivityType = 'cellular'", null);

// Run the query, returning a maximum of 100 devices


twinQuery = twinClient.queryTwin(sqlQuery.getQuery(), 3);
while (twinClient.hasNextDeviceTwin(twinQuery)) {
DeviceTwinDevice d = twinClient.getNextDeviceTwin(twinQuery);
System.out.println(d.getDeviceId());
}

15. Save and close the add-tags-query\src\main\java\com\mycompany\app\App.java file


16. Build the add-tags-query app and correct any errors. At your command prompt, navigate to the
add-tags-query folder and run the following command:

mvn clean package -DskipTests

Create a device app


In this section, you create a Java console app that sets a reported property value that is sent to IoT Hub.
1. In the iot-java-twin-getstarted folder, create a Maven project called simulated-device using the
following command at your command prompt. Note this is a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=simulated-device -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2. At your command prompt, navigate to the simulated-device folder.


3. Using a text editor, open the pom.xml file in the simulated-device folder and add the following
dependencies to the dependencies node. This dependency enables you to use the iot-device-client
package in your app to communicate with your IoT hub:

<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-device-client</artifactId>
<version>1.3.32</version>
</dependency>

NOTE
You can check for the latest version of iot-device-client using Maven search.
4. Add the following build node after the dependencies node. This configuration instructs Maven to use
Java 1.8 to build the app:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

5. Save and close the pom.xml file.


6. Using a text editor, open the simulated-device\src\main\java\com\mycompany\app\App.java file.
7. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.device.*;
import com.microsoft.azure.sdk.iot.device.DeviceTwin.*;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Scanner;

8. Add the following class-level variables to the App class. Replacing {youriothubname} with your IoT hub
name, and {yourdevicekey} with the device key value you generated in the Create a device identity
section:

private static String connString = "HostName={youriothubname}.azure-


devices.net;DeviceId=myDeviceID;SharedAccessKey={yourdevicekey}";
private static IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
private static String deviceId = "myDeviceId";

This sample app uses the protocol variable when it instantiates a DeviceClient object.
9. Add the following code to the main method to:
Create a device client to communicate with IoT Hub.
Create a Device object to store the device twin properties.

DeviceClient client = new DeviceClient(connString, protocol);

// Create a Device object to store the device twin properties


Device dataCollector = new Device() {
// Print details when a property value changes
@Override
public void PropertyCall(String propertyKey, Object propertyValue, Object context) {
System.out.println(propertyKey + " changed to " + propertyValue);
}
};

10. Add the following code to the main method to create a connectivityType reported property and send it
to IoT Hub:
try {
// Open the DeviceClient and start the device twin services.
client.open();
client.startDeviceTwin(new DeviceTwinStatusCallBack(), null, dataCollector, null);

// Create a reported property and send it to your IoT hub.


dataCollector.setReportedProp(new Property("connectivityType", "cellular"));
client.sendReportedProperties(dataCollector.getReportedProp());
}
catch (Exception e) {
System.out.println("On exception, shutting down \n" + " Cause: " + e.getCause() + " \n" +
e.getMessage());
dataCollector.clean();
client.close();
System.out.println("Shutting down...");
}

11. Add the following code to the end of the main method. Waiting for the Enter key allows time for IoT Hub
to report the status of the device twin operations:

System.out.println("Press any key to exit...");

Scanner scanner = new Scanner(System.in);


scanner.nextLine();

dataCollector.clean();
client.close();

12. Save and close the simulated-device\src\main\java\com\mycompany\app\App.java file.


13. Build the simulated-device app and correct any errors. At your command prompt, navigate to the
simulated-device folder and run the following command:

mvn clean package -DskipTests

Run the apps


You are now ready to run the console apps.
1. At a command prompt in the add-tags-query folder, run the following command to run the add-tags-
query service app:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
You can see the plant and region tags added to the device twin. The first query returns your device, but
the second does not.
2. At a command prompt in the simulated-device folder, run the following command to add the
connectivityType reported property to the device twin:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

3. At a command prompt in the add-tags-query folder, run the following command to run the add-tags-
query service app a second time:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
Now your device has sent the connectivityType property to IoT Hub, the second query returns your
device.

Next steps
In this tutorial, you configured a new IoT hub in the Azure portal, and then created a device identity in the IoT
hub's identity registry. You added device metadata as tags from a back-end app, and wrote a device app to report
device connectivity information in the device twin. You also learned how to query the device twin information
using the SQL -like IoT Hub query language.
Use the following resources to learn how to:
Send telemetry from devices with the Get started with IoT Hub tutorial.
Control devices interactively (such as turning on a fan from a user-controlled app) with the Use direct
methods tutorial.
Get started with device twins (Python)
5/29/2018 • 10 min to read • Edit Online

Device twins are JSON documents that store device state information (metadata, configurations, and
conditions). IoT Hub persists a device twin for each device that connects to it.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use device twins to:


Store device metadata from your solution back end.
Report current state information such as available capabilities and conditions (for example, the connectivity
method used) from your device app.
Synchronize the state of long-running workflows (such as firmware and configuration updates) between a
device app and a back-end app.
Query your device metadata, configuration, or state.
Device twins are designed for synchronization and for querying device configurations and conditions. More
information on when to use device twins can be found in Understand device twins.
Device twins are stored in an IoT hub and contain:
tags, device metadata accessible only by the solution back end;
desired properties, JSON objects modifiable by the solution back end and observable by the device app; and
reported properties, JSON objects modifiable by the device app and readable by the solution back end. Tags
and properties cannot contain arrays, but objects can be nested.

Additionally, the solution back end can query device twins based on all the above data. Refer to Understand
device twins for more information about device twins, and to the IoT Hub query language reference for
querying.
This tutorial shows you how to:
Create a back-end app that adds tags to a device twin, and a simulated device app that reports its connectivity
channel as a reported property on the device twin.
Query devices from your back-end app using filters on the tags and properties previously created.
At the end of this tutorial, you will have two Python console apps:
AddTagsAndQuery.py, a Python back-end app, which adds tags and queries device twins.
ReportConnectivity.py, a Python app, which simulates a device that connects to your IoT hub with the
device identity created earlier, and reports its connectivity condition.

NOTE
The article Azure IoT SDKs provides information about the Azure IoT SDKs that you can use to build both device and back-
end apps.

To complete this tutorial you need the following:


Python 2.x or 3.x. Make sure to use the 32-bit or 64-bit installation as required by your setup. When
prompted during the installation, make sure to add Python to your platform-specific environment variable. If
you are using Python 2.x, you may need to install or upgrade pip, the Python package management system.
If you are using Windows OS, then Visual C++ redistributable package to allow the use of native DLLs from
Python.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

NOTE
The pip packages for azure-iothub-service-client and azure-iothub-device-client are currently available only for
Windows OS. For Linux/Mac OS, please refer to the Linux and Mac OS-specific sections on the Prepare your development
environment for Python post.

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A
device cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the
"Identity registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a
unique device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new
device identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use
later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and
keys to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device.
If your application needs to store other device-specific metadata, it should use an application-specific store. For more
information, see IoT Hub developer guide.

Create the service app


In this section, you create a Python console app that adds location metadata to the device twin associated with
your {Device Id}. It then queries the device twins stored in the IoT hub selecting the devices located in
Redmond, and then the ones that are reporting a cellular connection.
1. Open a command prompt and install the Azure IoT Hub Service SDK for Python. Close the command
prompt after you install the SDK.

pip install azure-iothub-service-client

2. Using a text editor, create a new AddTagsAndQuery.py file.


3. Add the following code to import the required modules from the service SDK:

import sys
import iothub_service_client
from iothub_service_client import IoTHubRegistryManager, IoTHubRegistryManagerAuthMethod
from iothub_service_client import IoTHubDeviceTwin, IoTHubError

4. Add the following code, replacing the placeholder for [IoTHub Connection String] and [Device Id] with
the connection string for the IoT hub and the device id you created in the previous sections.

CONNECTION_STRING = "[IoTHub Connection String]"


DEVICE_ID = "[Device Id]"

UPDATE_JSON = "{\"properties\":{\"desired\":{\"location\":\"Redmond\"}}}"

UPDATE_JSON_SEARCH = "\"location\":\"Redmond\""
UPDATE_JSON_CLIENT_SEARCH = "\"connectivity\":\"cellular\""

5. Add the following code to the AddTagsAndQuery.py file:


def iothub_service_sample_run():
try:
iothub_registry_manager = IoTHubRegistryManager(CONNECTION_STRING)

iothub_registry_statistics = iothub_registry_manager.get_statistics()
print ( "Total device count :
{0}".format(iothub_registry_statistics.totalDeviceCount) )
print ( "Enabled device count :
{0}".format(iothub_registry_statistics.enabledDeviceCount) )
print ( "Disabled device count :
{0}".format(iothub_registry_statistics.disabledDeviceCount) )
print ( "" )

number_of_devices = iothub_registry_statistics.totalDeviceCount
dev_list = iothub_registry_manager.get_device_list(number_of_devices)

iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)

for device in range(0, number_of_devices):


if dev_list[device].deviceId == DEVICE_ID:
twin_info = iothub_twin_method.update_twin(dev_list[device].deviceId, UPDATE_JSON)

print ( "Devices in Redmond: " )


for device in range(0, number_of_devices):
twin_info = iothub_twin_method.get_twin(dev_list[device].deviceId)

if twin_info.find(UPDATE_JSON_SEARCH) > -1:


print ( dev_list[device].deviceId )

print ( "" )

print ( "Devices in Redmond using cellular network: " )


for device in range(0, number_of_devices):
twin_info = iothub_twin_method.get_twin(dev_list[device].deviceId)

if twin_info.find(UPDATE_JSON_SEARCH) > -1:


if twin_info.find(UPDATE_JSON_CLIENT_SEARCH) > -1:
print ( dev_list[device].deviceId )

except IoTHubError as iothub_error:


print ( "Unexpected error {0}".format(iothub_error) )
return
except KeyboardInterrupt:
print ( "IoTHub sample stopped" )

The Registry object exposes all the methods required to interact with device twins from the service. The
code first initializes the Registry object, then updates the device twin for deviceId, and finally runs two
queries. The first selects only the device twins of devices located in the Redmond43 plant, and the second
refines the query to select only the devices that are also connected through cellular network.
6. Add the following code at the end of AddTagsAndQuery.py to implement the
iothub_service_sample_run function:

if __name__ == '__main__':
print ( "Starting the IoT Hub Device Twins Python service sample..." )

iothub_service_sample_run()

7. Run the application with:

python AddTagsAndQuery.py
You should see one device in the results for the query asking for all devices located in Redmond43 and
none for the query that restricts the results to devices that use a cellular network.

In the next section, you create a device app that reports the connectivity information and changes the result of
the query in the previous section.

Create the device app


In this section, you create a Python console app that connects to your hub as your {Device Id}, and then updates
its device twin's reported properties to contain the information that it is connected using a cellular network.
1. Open a command prompt and install the Azure IoT Hub Service SDK for Python. Close the command
prompt after you install the SDK.

pip install azure-iothub-device-client

2. Using a text editor, create a new ReportConnectivity.py file.


3. Add the following code to import the required modules from the service SDK:

import time
import iothub_client
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider,
IoTHubClientResult, IoTHubError

4. Add the following code, replacing the placeholder for [IoTHub Device Connection String] with the
connection string for the IoT hub device you created in the previous sections.

CONNECTION_STRING = "[IoTHub Device Connection String]"

# choose HTTP, AMQP, AMQP_WS or MQTT as transport protocol


PROTOCOL = IoTHubTransportProvider.MQTT

TIMER_COUNT = 5
TWIN_CONTEXT = 0
SEND_REPORTED_STATE_CONTEXT = 0

5. Add the following code to the ReportConnectivity.py file to implement the device twins functionality:
def device_twin_callback(update_state, payload, user_context):
print ( "" )
print ( "Twin callback called with:" )
print ( " updateStatus: %s" % update_state )
print ( " payload: %s" % payload )

def send_reported_state_callback(status_code, user_context):


print ( "" )
print ( "Confirmation for reported state called with:" )
print ( " status_code: %d" % status_code )

def iothub_client_init():
client = IoTHubClient(CONNECTION_STRING, PROTOCOL)

if client.protocol == IoTHubTransportProvider.MQTT or client.protocol ==


IoTHubTransportProvider.MQTT_WS:
client.set_device_twin_callback(
device_twin_callback, TWIN_CONTEXT)

return client

def iothub_client_sample_run():
try:
client = iothub_client_init()

if client.protocol == IoTHubTransportProvider.MQTT:
print ( "Sending data as reported property..." )

reported_state = "{\"connectivity\":\"cellular\"}"

client.send_reported_state(reported_state, len(reported_state),
send_reported_state_callback, SEND_REPORTED_STATE_CONTEXT)

while True:
print ( "Press Ctrl-C to exit" )

status_counter = 0
while status_counter <= TIMER_COUNT:
status = client.get_send_status()
time.sleep(10)
status_counter += 1
except IoTHubError as iothub_error:
print ( "Unexpected error %s from IoTHub" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubClient sample stopped" )

The Client object exposes all the methods you require to interact with device twins from the device. The
previous code, after it initializes the Client object, retrieves the device twin for your device and updates its
reported property with the connectivity information.
6. Add the following code at the end of ReportConnectivity.py to implement the
iothub_client_sample_run function:

if __name__ == '__main__':
print ( "Starting the IoT Hub Device Twins Python client sample..." )

iothub_client_sample_run()

7. Run the device app

python ReportConnectivity.py
You should see confirmation the device twins were updated.

8. Now that the device reported its connectivity information, it should appear in both queries. Go back and
run the queries again:

python AddTagsAndQuery.py

This time your {Device Id} should appear in both query results.

Next steps
In this tutorial, you configured a new IoT hub in the Azure portal, and then created a device identity in the IoT
hub's identity registry. You added device metadata as tags from a back-end app, and wrote a simulated device
app to report device connectivity information in the device twin. You also learned how to query this information
using the registry.
Use the following resources to learn how to:
Send telemetry from devices with the Get started with IoT Hub tutorial,
Configure devices using device twin's desired properties with the Use desired properties to configure devices
tutorial,
Control devices interactively (such as turning on a fan from a user-controlled app), with the Use direct
methods tutorial.
Get started with IoT Hub module identity and module
twin using the portal and .NET device
5/29/2018 • 5 min to read • Edit Online

NOTE
Module identities and module twins are similar to Azure IoT Hub device identity and device twin, but provide finer granularity.
While Azure IoT Hub device identity and device twin enable the back-end application to configure a device and provides
visibility on the device’s conditions, a module identity and module twin provide these capabilities for individual components of
a device. On capable devices with multiple components, such as operating system based devices or firmware devices, it allows
for isolated configuration and conditions for each component.

In this tutorial, you will learn


1. how to create a module identity in the portal.
2. how to use .NET device SDK update the module twin from your device.

NOTE
For information about the Azure IoT SDKs that you can use to build both applications to run on devices, and your solution
back end, see Azure IoT SDKs.

To complete this tutorial, you need the following:


Visual Studio 2015 or Visual Studio 2017.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity in the portal


Now you have your IoT Hub. Open portal and navigate to your IoT Hub. Click on IoT Devices, and then click add to
create a device identity. Name it MyFirstDevice.
After save, in your device identity list, you can see MyFirstDevice identity is successfuly created.

Now click on the row. You will see device details.


Create a module identity in the portal
Within one device identity, you can create up to 20 module identities. Click the Add Module Identity button on
top to create your first module identity called myFirstModule.

Save and click the just created module identity. You can see the module identity details. Save the connect string -
primary key. It will be used in the next section where you set up your module on the device.

Update the module twin using .NET device SDK


You've successfully created the module identity in your IoT Hub. Let's try to communicate to the cloud from your
simulated device. Once a module identity is created, a module twin is implicitly created in IoT Hub. In this section,
you will create a .NET console app on your simulated device that updates the module twin reported properties.
1. Create a Visual Studio project - In Visual Studio, add a Visual C# Windows Classic Desktop project to the
existing solution by using the Console App (.NET Framework) project template. Make sure the .NET
Framework version is 4.6.1 or later. Name the project UpdateModuleTwinReportedProperties.

2. Install the latest Azure IoT Hub .NET device SDK - Module identity and module twin is in public
preview. It's only availble in the IoT Hub prerelease device SDKs. In Visual Studio, open tools > Nuget
package manager > manage Nuget packages for solution. Search Microsoft.Azure.Devices.Client. Make sure
you've checked include prerelease check box. Select the latest version and install. Now you have access to all
the module features.

3. Get your module connection string -- now if you login to Azure portal. Navigate to your IoT Hub and
click IoT Devices. Find myFirstDevice, open it and you see myFirstModule was successfuly created. Copy the
module connection string. It is needed in the next step.
4. Create UpdateModuleTwinReportedProperties console app Add the following using statements at
the top of the Program.cs file:

using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;

Add the following fields to the Program class. Replace the placeholder value with the module connection
string.

private const string ModuleConnectionString = "<Your module connection string>“;


private static ModuleClient Client = null;

Add the following method OnDesiredPropertyChanged to the Program class:

private static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext)


{
Console.WriteLine("desired property change:");
Console.WriteLine(JsonConvert.SerializeObject(desiredProperties));
Console.WriteLine("Sending current time as reported property");
TwinCollection reportedProperties = new TwinCollection
{
["DateTimeLastDesiredPropertyChangeReceived"] = DateTime.Now
};

await Client.UpdateReportedPropertiesAsync(reportedProperties).ConfigureAwait(false);
}

Finally, add the following lines to the Main method:


static void Main(string[] args)
{
Microsoft.Azure.Devices.Client.TransportType transport =
Microsoft.Azure.Devices.Client.TransportType.Amqp;

try
{
Client = ModuleClient.CreateFromConnectionString(ModuleConnectionString, transport);
Client.SetConnectionStatusChangesHandler(ConnectionStatusChangeHandler);
Client.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChanged, null).Wait();

Console.WriteLine("Retrieving twin");
var twinTask = Client.GetTwinAsync();
twinTask.Wait();
var twin = twinTask.Result;
Console.WriteLine(JsonConvert.SerializeObject(twin));

Console.WriteLine("Sending app start time as reported property");


TwinCollection reportedProperties = new TwinCollection();
reportedProperties["DateTimeLastAppLaunch"] = DateTime.Now;

Client.UpdateReportedPropertiesAsync(reportedProperties);
}
catch (AggregateException ex)
{
Console.WriteLine("Error in sample: {0}", ex);
}

Console.WriteLine("Waiting for Events. Press enter to exit...");


Client.CloseAsync().Wait();
}

This code sample shows you how to retrieve the module twin and update reported properties with AMQP
protocol. In public preview, we only support AMQP for module twin operations.

Run the apps


You are now ready to run the apps. In Visual Studio, in Solution Explorer, right-click your solution, and then click
Set StartUp projects. Select Multiple startup projects, and then select Start as the action for the console app.
And then press F5 to start both apps running.

Next steps
To continue getting started with IoT Hub and to explore other IoT scenarios, see:
Get started with IoT Hub module identity and module twin using .NET backup and .NET device
Getting started with IoT Edge
Get started with IoT Hub module identity and
module twin using .NET back end and .NET device
5/29/2018 • 8 min to read • Edit Online

NOTE
Module identities and module twins are similar to Azure IoT Hub device identity and device twin, but provide finer
granularity. While Azure IoT Hub device identity and device twin enable the back-end application to configure a device and
provides visibility on the device’s conditions, a module identity and module twin provide these capabilities for individual
components of a device. On capable devices with multiple components, such as operating system based devices or firmware
devices, it allows for isolated configuration and conditions for each component.

At the end of this tutorial, you have two .NET console apps:
CreateIdentities, which creates a device identity, a module identity and associated security key to connect your
device and module clients.
UpdateModuleTwinReportedProperties, which sends updated module twin reported properties to your IoT
Hub.

NOTE
For information about the Azure IoT SDKs that you can use to build both applications to run on devices, and your solution
back end, see Azure IoT SDKs.

To complete this tutorial, you need the following:


Visual Studio 2015 or Visual Studio 2017.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

You have now created your IoT hub, and you have the host name and IoT Hub connection string that you need to
complete the rest of this tutorial.

Create a module identity


In this section, you create a .NET console app that creates a device identity and a module identity in the identity
registry in your IoT hub. A device or module cannot connect to IoT hub unless it has an entry in the identity
registry. For more information, see the "Identity registry" section of the IoT Hub developer guide. When you run
this console app, it generates a unique ID and key for both device and module. Your device and module use these
values to identify itself when it sends device-to-cloud messages to IoT Hub. The IDs are case-sensitive.
1. Create a Visual Studio project - In Visual Studio, add a Visual C# Windows Classic Desktop project to a
new solution by using the Console App (.NET Framework) project template. Make sure the .NET
Framework version is 4.6.1 or later. Name the project CreateIdentities and name the solution
IoTHubGetStarted.
2. Install Azure IoT Hub .NET service SDK V1.16.0-preview-001 - Module identity and module twin is in
public preview. It's only availble in the IoT Hub prerelease service SDKs. In Visual Studio, open tools >
Nuget package manager > manage Nuget packages for solution. Search Microsoft.Azure.Devices. Make
sure you've checked include prerelease check box. Select version 1.16.0-preview -001 and install. Now you
have access to all the module features.

3. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Common.Exceptions;

4. Add the following fields to the Program class. Replace the placeholder value with the IoT Hub connection
string for the hub that you created in the previous section.

const string connectionString = "<replace_with_iothub_connection_string>";


const string deviceID = "myFirstDevice";
const string moduleID = "myFirstModule";

5. Add the following code to the Main class.


static void Main(string[] args)
{
AddDeviceAsync().Wait();
AddModuleAsync().Wait();
}

6. Add the following methods to the Program class:

private static async Task AddDeviceAsync()


{
RegistryManager registryManager = RegistryManager.CreateFromConnectionString(connectionString);
Device device;

try
{
device = await registryManager.AddDeviceAsync(new Device(deviceID));
}
catch (DeviceAlreadyExistsException)
{
device = await registryManager.GetDeviceAsync(deviceID);
}

Console.WriteLine("Generated device key: {0}", device.Authentication.SymmetricKey.PrimaryKey);


}

private static async Task AddModuleAsync()


{
RegistryManager registryManager = RegistryManager.CreateFromConnectionString(connectionString);
Module module;

try
{
module = await registryManager.AddModuleAsync(new Module(deviceID, moduleID));
}
catch (ModuleAlreadyExistsException)
{
module = await registryManager.GetModuleAsync(deviceID, moduleID);
}

Console.WriteLine("Generated module key: {0}", module.Authentication.SymmetricKey.PrimaryKey);


}

The AddDeviceAsync() method creates a device identity with ID myFirstDevice. (If that device ID already
exists in the identity registry, the code simply retrieves the existing device information.) The app then
displays the primary key for that identity. You use this key in the simulated device app to connect to your IoT
hub.
The AddModuleAsync() method creates a module identity with ID myFirstModule under device
myFirstDevice. (If that module ID already exists in the identity registry, the code simply retrieves the
existing module information.) The app then displays the primary key for that identity. You use this key in the
simulated module app to connect to your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid any
sensitive information while naming it.

1. Run this application, and make a note of the device key and module key.
NOTE
The IoT Hub identity registry only stores device and module identities to enable secure access to the IoT hub. The identity
registry stores device IDs and keys to use as security credentials. The identity registry also stores an enabled/disabled flag for
each device that you can use to disable access for that device. If your application needs to store other device-specific
metadata, it should use an application-specific store. There is no enabled/disabled flag for module identities. For more
information, see IoT Hub developer guide.

Update the module twin using .NET device SDK


In this section, you create a .NET console app on your simulated device that updates the module twin reported
properties.
1. Create a Visual Studio project - In Visual Studio, add a Visual C# Windows Classic Desktop project to the
existing solution by using the Console App (.NET Framework) project template. Make sure the .NET
Framework version is 4.6.1 or later. Name the project UpdateModuleTwinReportedProperties.

2. Install the latest Azure IoT Hub .NET device SDK - Module identity and module twin is in public
preview. It's only availble in the IoT Hub prerelease device SDKs. In Visual Studio, open tools > Nuget
package manager > manage Nuget packages for solution. Search Microsoft.Azure.Devices.Client. Make
sure you've checked include prerelease check box. Select the latest version and install. Now you have access
to all the module features.
3. Get your module connection string -- now if you login to Azure portal. Navigate to your IoT Hub and
click IoT Devices. Find myFirstDevice, open it and you see myFirstModule was successfuly created. Copy the
module connection string. It is needed in the next step.

4. Create UpdateModuleTwinReportedProperties console app Add the following using statements at


the top of the Program.cs file:

using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;
using System.Threading.Tasks;
using Newtonsoft.Json;

Add the following fields to the Program class. Replace the placeholder value with the module connection
string.

private const string ModuleConnectionString = "<Your module connection string>";


private static ModuleClient Client = null;
static void ConnectionStatusChangeHandler(ConnectionStatus status, ConnectionStatusChangeReason reason)
{
Console.WriteLine("Connection Status Changed to {0}; the reason is {1}", status, reason);
}

Add the following method OnDesiredPropertyChanged to the Program class:


private static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext)
{
Console.WriteLine("desired property change:");
Console.WriteLine(JsonConvert.SerializeObject(desiredProperties));
Console.WriteLine("Sending current time as reported property");
TwinCollection reportedProperties = new TwinCollection
{
["DateTimeLastDesiredPropertyChangeReceived"] = DateTime.Now
};

await Client.UpdateReportedPropertiesAsync(reportedProperties).ConfigureAwait(false);
}

Finally, add the following lines to the Main method:

static void Main(string[] args)


{
Microsoft.Azure.Devices.Client.TransportType transport =
Microsoft.Azure.Devices.Client.TransportType.Amqp;

try
{
Client = ModuleClient.CreateFromConnectionString(ModuleConnectionString, transport);
Client.SetConnectionStatusChangesHandler(ConnectionStatusChangeHandler);
Client.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChanged, null).Wait();

Console.WriteLine("Retrieving twin");
var twinTask = Client.GetTwinAsync();
twinTask.Wait();
var twin = twinTask.Result;
Console.WriteLine(JsonConvert.SerializeObject(twin.Properties));

Console.WriteLine("Sending app start time as reported property");


TwinCollection reportedProperties = new TwinCollection();
reportedProperties["DateTimeLastAppLaunch"] = DateTime.Now;

Client.UpdateReportedPropertiesAsync(reportedProperties);
}
catch (AggregateException ex)
{
Console.WriteLine("Error in sample: {0}", ex);
}

Console.WriteLine("Waiting for Events. Press enter to exit...");


Console.ReadLine();
Client.CloseAsync().Wait();
}

This code sample shows you how to retrieve the module twin and update reported properties with AMQP
protocol. In public preview, we only support AMQP for module twin operations.
5. In addition to the above Main method, you can add below code block to send event to IoT Hub from your
module:

Byte[] bytes = new Byte[2];


bytes[0] = 0;
bytes[1] = 1;
var sendEventsTask = Client.SendEventAsync(new Message(bytes));
sendEventsTask.Wait();
Console.WriteLine("Event sent to IoT Hub.");
Run the apps
You are now ready to run the apps. In Visual Studio, in Solution Explorer, right-click your solution, and then click
Set StartUp projects. Select Multiple startup projects, and then select Start as the action for the console app.
And then press F5 to start the app.

Next steps
To continue getting started with IoT Hub and to explore other IoT scenarios, see:
Getting started with device management
Getting started with IoT Edge
1 min to read •
Edit Online
1 min to read •
Edit Online
1 min to read •
Edit Online
1 min to read •
Edit Online
1 min to read •
Edit Online
Get started with device management (Node)
5/29/2018 • 9 min to read • Edit Online

Back-end apps can use Azure IoT Hub primitives, such as device twin and direct methods, to remotely start and
monitor device management actions on devices. This tutorial shows you how a back-end app and a device app
can work together to initiate and monitor a remote device reboot using IoT Hub.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use a direct method to initiate device management actions (such as reboot, factory reset, and firmware update)
from a back-end app in the cloud. The device is responsible for:
Handling the method request sent from IoT Hub.
Initiating the corresponding device-specific action on the device.
Providing status updates through reported properties to IoT Hub.
You can use a back-end app in the cloud to run device twin queries to report on the progress of your device
management actions.
This tutorial shows you how to:
Use the Azure portal to create an IoT Hub and create a device identity in your IoT hub.
Create a simulated device app that contains a direct method that reboots that device. Direct methods are
invoked from the cloud.
Create a Node.js console app that calls the reboot direct method in the simulated device app through your
IoT hub.
At the end of this tutorial, you have two Node.js console apps:
dmpatterns_getstarted_device.js, which connects to your IoT hub with the device identity created earlier,
receives a reboot direct method, simulates a physical reboot, and reports the time for the last reboot.
dmpatterns_getstarted_service.js, which calls a direct method in the simulated device app, displays the
response, and displays the updated reported properties.
To complete this tutorial, you need the following:
Node.js version 4.0.x or later,
Prepare your development environment describes how to install Node.js for this tutorial on either Windows
or Linux.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information
while naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create.
You can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now
that you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device
IDs are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with the
IoT Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to
avoid any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the device
app to connect to your IoT Hub as a device.
Refer to Getting started with IoT Hub to programmatically create device identities.

Create a simulated device app


In this section, you will
Create a Node.js console app that responds to a direct method called by the cloud
Trigger a simulated device reboot
Use the reported properties to enable device twin queries to identify devices and when they last rebooted
1. Create an empty folder called manageddevice. In the manageddevice folder, create a package.json
file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the manageddevice folder, run the following command to install the
azure-iot-device Device SDK package and azure-iot-device-mqtt package:

npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a dmpatterns_getstarted_device.js file in the manageddevice folder.


4. Add the following 'require' statements at the start of the dmpatterns_getstarted_device.js file:

'use strict';

var Client = require('azure-iot-device').Client;


var Protocol = require('azure-iot-device-mqtt').Mqtt;

5. Add a connectionString variable and use it to create a Client instance. Replace the connection string
with your device connection string.

var connectionString = 'HostName={youriothostname};DeviceId=myDeviceId;SharedAccessKey=


{yourdevicekey}';
var client = Client.fromConnectionString(connectionString, Protocol);

6. Add the following function to implement the direct method on the device
var onReboot = function(request, response) {

// Respond the cloud app for the direct method


response.send(200, 'Reboot started', function(err) {
if (err) {
console.error('An error occured when sending a method response:\n' + err.toString());
} else {
console.log('Response to method \'' + request.methodName + '\' sent successfully.');
}
});

// Report the reboot before the physical restart


var date = new Date();
var patch = {
iothubDM : {
reboot : {
lastReboot : date.toISOString(),
}
}
};

// Get device Twin


client.getTwin(function(err, twin) {
if (err) {
console.error('could not get twin');
} else {
console.log('twin acquired');
twin.properties.reported.update(patch, function(err) {
if (err) throw err;
console.log('Device reboot twin state reported')
});
}
});

// Add your device's reboot API for physical restart.


console.log('Rebooting!');
};

7. Open the connection to your IoT hub and start the direct method listener:

client.open(function(err) {
if (err) {
console.error('Could not open IotHub client');
} else {
console.log('Client opened. Waiting for reboot method.');
client.onDeviceMethod('reboot', onReboot);
}
});

8. Save and close the dmpatterns_getstarted_device.js file.

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Trigger a remote reboot on the device using a direct method


In this section, you create a Node.js console app that initiates a remote reboot on a device using a direct
method. The app uses device twin queries to discover the last reboot time for that device.
1. Create an empty folder called triggerrebootondevice. In the triggerrebootondevice folder, create a
package.json file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the triggerrebootondevice folder, run the following command to install
the azure-iothub Device SDK package and azure-iot-device-mqtt package:

npm install azure-iothub --save

3. Using a text editor, create a dmpatterns_getstarted_service.js file in the triggerrebootondevice folder.


4. Add the following 'require' statements at the start of the dmpatterns_getstarted_service.js file:

'use strict';

var Registry = require('azure-iothub').Registry;


var Client = require('azure-iothub').Client;

5. Add the following variable declarations and replace the placeholder values:

var connectionString = '{iothubconnectionstring}';


var registry = Registry.fromConnectionString(connectionString);
var client = Client.fromConnectionString(connectionString);
var deviceToReboot = 'myDeviceId';

6. Add the following function to invoke the device method to reboot the target device:

var startRebootDevice = function(twin) {

var methodName = "reboot";

var methodParams = {
methodName: methodName,
payload: null,
timeoutInSeconds: 30
};

client.invokeDeviceMethod(deviceToReboot, methodParams, function(err, result) {


if (err) {
console.error("Direct method error: "+err.message);
} else {
console.log("Successfully invoked the device to reboot.");
}
});
};

7. Add the following function to query for the device and get the last reboot time:
var queryTwinLastReboot = function() {

registry.getTwin(deviceToReboot, function(err, twin){

if (twin.properties.reported.iothubDM != null)
{
if (err) {
console.error('Could not query twins: ' + err.constructor.name + ': ' +
err.message);
} else {
var lastRebootTime = twin.properties.reported.iothubDM.reboot.lastReboot;
console.log('Last reboot time: ' + JSON.stringify(lastRebootTime, null, 2));
}
} else
console.log('Waiting for device to report last reboot time.');
});
};

8. Add the following code to call the functions that trigger the reboot direct method and query for the last
reboot time:

startRebootDevice();
setInterval(queryTwinLastReboot, 2000);

9. Save and close the dmpatterns_getstarted_service.js file.

Run the apps


You are now ready to run the apps.
1. At the command prompt in the manageddevice folder, run the following command to begin listening
for the reboot direct method.

node dmpatterns_getstarted_device.js

2. At the command prompt in the triggerrebootondevice folder, run the following command to trigger
the remote reboot and query for the device twin to find the last reboot time.

node dmpatterns_getstarted_service.js

3. You see the device response to the direct method in the console.

Customize and extend the device management actions


Your IoT solutions can expand the defined set of device management patterns or enable custom patterns by
using the device twin and cloud-to-device method primitives. Other examples of device management actions
include factory reset, firmware update, software update, power management, network and connectivity
management, and data encryption.

Device maintenance windows


Typically, you configure devices to perform actions at a time that minimizes interruptions and downtime.
Device maintenance windows are a commonly used pattern to define the time when a device should update its
configuration. Your back-end solutions can use the desired properties of the device twin to define and activate
a policy on your device that enables a maintenance window. When a device receives the maintenance window
policy, it can use the reported property of the device twin to report the status of the policy. The back-end app
can then use device twin queries to attest to compliance of devices and each policy.

Next steps
In this tutorial, you used a direct method to trigger a remote reboot on a device. You used the reported
properties to report the last reboot time from the device, and queried the device twin to discover the last
reboot time of the device from the cloud.
To continue getting started with IoT Hub and device management patterns such as remote over the air
firmware update, see:
Tutorial: How to do a firmware update
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
To continue getting started with IoT Hub, see Getting started with IoT Edge.
Get started with device management (.NET/Node)
5/29/2018 • 9 min to read • Edit Online

Back-end apps can use Azure IoT Hub primitives, such as device twin and direct methods, to remotely start and
monitor device management actions on devices. This tutorial shows you how a back-end app and a device app
can work together to initiate and monitor a remote device reboot using IoT Hub.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use a direct method to initiate device management actions (such as reboot, factory reset, and firmware update)
from a back-end app in the cloud. The device is responsible for:
Handling the method request sent from IoT Hub.
Initiating the corresponding device-specific action on the device.
Providing status updates through reported properties to IoT Hub.
You can use a back-end app in the cloud to run device twin queries to report on the progress of your device
management actions.
This tutorial shows you how to:
Use the Azure portal to create an IoT Hub and create a device identity in your IoT hub.
Create a simulated device app that contains a direct method that reboots that device. Direct methods are
invoked from the cloud.
Create a .NET console app that calls the reboot direct method in the simulated device app through your IoT
hub.
At the end of this tutorial, you have a Node.js console device app and a .NET (C#) console back-end app:
dmpatterns_getstarted_device.js, which connects to your IoT hub with the device identity created earlier,
receives a reboot direct method, simulates a physical reboot, and reports the time for the last reboot.
TriggerReboot, which calls a direct method in the simulated device app, displays the response, and displays the
updated reported properties.
To complete this tutorial, you need the following:
Visual Studio 2015 or Visual Studio 2017.
Node.js version 4.0.x or later,
Prepare your development environment describes how to install Node.js for this tutorial on either Windows
or Linux.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device
IDs are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with the
IoT Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the device
app to connect to your IoT Hub as a device.
Refer to Getting started with IoT Hub to programmatically create device identities.

Trigger a remote reboot on the device using a direct method


In this section, you create a .NET console app (using C#) that initiates a remote reboot on a device using a direct
method. The app uses device twin queries to discover the last reboot time for that device.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to a new solution by using the
Console App (.NET Framework) project template. Make sure the .NET Framework version is 4.5.1 or
later. Name the project TriggerReboot.

2. In Solution Explorer, right-click the TriggerReboot project, and then click Manage NuGet Packages.
3. In the NuGet Package Manager window, select Browse, search for microsoft.azure.devices, select
Install to install the Microsoft.Azure.Devices package, and accept the terms of use. This procedure
downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package and its
dependencies.
4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;

5. Add the following fields to the Program class. Replace the placeholder value with the IoT Hub connection
string for the hub that you created in the section "Create an IoT hub."

static RegistryManager registryManager;


static string connString = "{iot hub connection string}";
static ServiceClient client;
static JobClient jobClient;
static string targetDevice = "myDeviceId";

6. Add the following method to the Program class. This code gets the device twin for the rebooting device
and outputs the reported properties.

public static async Task QueryTwinRebootReported()


{
Twin twin = await registryManager.GetTwinAsync(targetDevice);
Console.WriteLine(twin.Properties.Reported.ToJson());
}

7. Add the following method to the Program class. This code initiates the reboot on the device using a
direct method.

public static async Task StartReboot()


{
client = ServiceClient.CreateFromConnectionString(connString);
CloudToDeviceMethod method = new CloudToDeviceMethod("reboot");
method.ResponseTimeout = TimeSpan.FromSeconds(30);

CloudToDeviceMethodResult result = await client.InvokeDeviceMethodAsync(targetDevice, method);

Console.WriteLine("Invoked firmware update on device.");


}
8. Finally, add the following lines to the Main method:

registryManager = RegistryManager.CreateFromConnectionString(connString);
StartReboot().Wait();
QueryTwinRebootReported().Wait();
Console.WriteLine("Press ENTER to exit.");
Console.ReadLine();

9. Build the solution.

Create a simulated device app


In this section, you will
Create a Node.js console app that responds to a direct method called by the cloud
Trigger a simulated device reboot
Use the reported properties to enable device twin queries to identify devices and when they last rebooted
1. Create a new empty folder called manageddevice. In the manageddevice folder, create a package.json
file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the manageddevice folder, run the following command to install the
azure-iot-device Device SDK package and azure-iot-device-mqtt package:

npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a new dmpatterns_getstarted_device.js file in the manageddevice folder.
4. Add the following 'require' statements at the start of the dmpatterns_getstarted_device.js file:

'use strict';

var Client = require('azure-iot-device').Client;


var Protocol = require('azure-iot-device-mqtt').Mqtt;

5. Add a connectionString variable and use it to create a Client instance. Replace the connection string
with your device connection string.

var connectionString = 'HostName={youriothostname};DeviceId=myDeviceId;SharedAccessKey=


{yourdevicekey}';
var client = Client.fromConnectionString(connectionString, Protocol);

6. Add the following function to implement the direct method on the device
var onReboot = function(request, response) {

// Respond the cloud app for the direct method


response.send(200, 'Reboot started', function(err) {
if (!err) {
console.error('An error occured when sending a method response:\n' + err.toString());
} else {
console.log('Response to method \'' + request.methodName + '\' sent successfully.');
}
});

// Report the reboot before the physical restart


var date = new Date();
var patch = {
iothubDM : {
reboot : {
lastReboot : date.toISOString(),
}
}
};

// Get device Twin


client.getTwin(function(err, twin) {
if (err) {
console.error('could not get twin');
} else {
console.log('twin acquired');
twin.properties.reported.update(patch, function(err) {
if (err) throw err;
console.log('Device reboot twin state reported')
});
}
});

// Add your device's reboot API for physical restart.


console.log('Rebooting!');
};

7. Add the following code to open the connection to your IoT hub and start the direct method listener:

client.open(function(err) {
if (err) {
console.error('Could not open IotHub client');
} else {
console.log('Client opened. Waiting for reboot method.');
client.onDeviceMethod('reboot', onReboot);
}
});

8. Save and close the dmpatterns_getstarted_device.js file.

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Run the apps


You are now ready to run the apps.
1. At the command prompt in the manageddevice folder, run the following command to begin listening for
the reboot direct method.

node dmpatterns_getstarted_device.js

2. Run the C# console app TriggerReboot. Right-click the TriggerReboot project, select Debug, and then
select Start new instance.
3. You see the device response to the direct method in the console.

Customize and extend the device management actions


Your IoT solutions can expand the defined set of device management patterns or enable custom patterns by
using the device twin and cloud-to-device method primitives. Other examples of device management actions
include factory reset, firmware update, software update, power management, network and connectivity
management, and data encryption.

Device maintenance windows


Typically, you configure devices to perform actions at a time that minimizes interruptions and downtime. Device
maintenance windows are a commonly used pattern to define the time when a device should update its
configuration. Your back-end solutions can use the desired properties of the device twin to define and activate a
policy on your device that enables a maintenance window. When a device receives the maintenance window
policy, it can use the reported property of the device twin to report the status of the policy. The back-end app can
then use device twin queries to attest to compliance of devices and each policy.

Next steps
In this tutorial, you used a direct method to trigger a remote reboot on a device. You used the reported
properties to report the last reboot time from the device, and queried the device twin to discover the last reboot
time of the device from the cloud.
To continue getting started with IoT Hub and device management patterns such as remote over the air firmware
update, see:
Tutorial: How to do a firmware update
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
To continue getting started with IoT Hub, see Getting started with IoT Edge.
Get started with device management (.NET/.NET)
5/29/2018 • 10 min to read • Edit Online

Back-end apps can use Azure IoT Hub primitives, such as device twin and direct methods, to remotely start and
monitor device management actions on devices. This tutorial shows you how a back-end app and a device app
can work together to initiate and monitor a remote device reboot using IoT Hub.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use a direct method to initiate device management actions (such as reboot, factory reset, and firmware update)
from a back-end app in the cloud. The device is responsible for:
Handling the method request sent from IoT Hub.
Initiating the corresponding device-specific action on the device.
Providing status updates through reported properties to IoT Hub.
You can use a back-end app in the cloud to run device twin queries to report on the progress of your device
management actions.
This tutorial shows you how to:
Use the Azure portal to create an IoT Hub and create a device identity in your IoT hub.
Create a simulated device app that contains a direct method that reboots that device. Direct methods are
invoked from the cloud.
Create a .NET console app that calls the reboot direct method in the simulated device app through your IoT
hub.
At the end of this tutorial, you have two .NET console apps:
SimulateManagedDevice, which connects to your IoT hub with the device identity created earlier, receives
a reboot direct method, simulates a physical reboot, and reports the time for the last reboot.
TriggerReboot, which calls a direct method in the simulated device app, displays the response, and displays
the updated reported properties.
To complete this tutorial, you need the following:
Visual Studio 2015 or Visual Studio 2017.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A
device cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the
"Identity registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate
a unique device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new
device identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to
avoid any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use
later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and
keys to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device.
If your application needs to store other device-specific metadata, it should use an application-specific store. For more
information, see IoT Hub developer guide.

Trigger a remote reboot on the device using a direct method


In this section, you create a .NET console app (using C#) that initiates a remote reboot on a device using a direct
method. The app uses device twin queries to discover the last reboot time for that device.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to a new solution by using the
Console App (.NET Framework) project template. Make sure the .NET Framework version is 4.5.1 or
later. Name the project TriggerReboot.

2. In Solution Explorer, right-click the TriggerReboot project, and then click Manage NuGet Packages.
3. In the NuGet Package Manager window, select Browse, search for microsoft.azure.devices, select
Install to install the Microsoft.Azure.Devices package, and accept the terms of use. This procedure
downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package and its
dependencies.
4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;

5. Add the following fields to the Program class. Replace the placeholder value with the IoT Hub
connection string for the hub that you created in the section "Create an IoT hub."

static RegistryManager registryManager;


static string connString = "{iot hub connection string}";
static ServiceClient client;
static string targetDevice = "myDeviceId";

6. Add the following method to the Program class. This code gets the device twin for the rebooting device
and outputs the reported properties.

public static async Task QueryTwinRebootReported()


{
Twin twin = await registryManager.GetTwinAsync(targetDevice);
Console.WriteLine(twin.Properties.Reported.ToJson());
}

7. Add the following method to the Program class. This code initiates the reboot on the device using a
direct method.

public static async Task StartReboot()


{
client = ServiceClient.CreateFromConnectionString(connString);
CloudToDeviceMethod method = new CloudToDeviceMethod("reboot");
method.ResponseTimeout = TimeSpan.FromSeconds(30);

CloudToDeviceMethodResult result = await client.InvokeDeviceMethodAsync(targetDevice, method);

Console.WriteLine("Invoked firmware update on device.");


}

8. Finally, add the following lines to the Main method:


registryManager = RegistryManager.CreateFromConnectionString(connString);
StartReboot().Wait();
QueryTwinRebootReported().Wait();
Console.WriteLine("Press ENTER to exit.");
Console.ReadLine();

9. Build the solution.

NOTE
This tutorial performs only a single query for the device's reported properties. In production code, we recommend polling
to detect changes in the reported properties.

Create a simulated device app


In this section, you will
Create a .NET console app that responds to a direct method called by the cloud
Trigger a simulated device reboot
Use the reported properties to enable device twin queries to identify devices and when they last rebooted
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project SimulateManagedDevice.

2. In Solution Explorer, right-click the SimulateManagedDevice project, and then click Manage NuGet
Packages....
3. In the NuGet Package Manager window, select Browse and search for
microsoft.azure.devices.client. Select Install to install the Microsoft.Azure.Devices.Client package,
and accept the terms of use. This procedure downloads, installs, and adds a reference to the Azure IoT
device SDK NuGet package and its dependencies.
4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;

5. Add the following fields to the Program class. Replace the placeholder value with the device connection
string that you noted in the previous section.

static string DeviceConnectionString = "HostName=<yourIotHubName>.azure-devices.net;DeviceId=


<yourIotDeviceName>;SharedAccessKey=<yourIotDeviceAccessKey>";
static DeviceClient Client = null;

6. Add the following to implement the direct method on the device:

static Task<MethodResponse> onReboot(MethodRequest methodRequest, object userContext)


{
// In a production device, you would trigger a reboot scheduled to start after this method
returns
// For this sample, we simulate the reboot by writing to the console and updating the reported
properties
try
{
Console.WriteLine("Rebooting!");

// Update device twin with reboot time.


TwinCollection reportedProperties, reboot, lastReboot;
lastReboot = new TwinCollection();
reboot = new TwinCollection();
reportedProperties = new TwinCollection();
lastReboot["lastReboot"] = DateTime.Now;
reboot["reboot"] = lastReboot;
reportedProperties["iothubDM"] = reboot;
Client.UpdateReportedPropertiesAsync(reportedProperties).Wait();
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}

string result = "'Reboot started.'";


return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200));
}

7. Finally, add the following code to the Main method to open the connection to your IoT hub and initialize
the method listener:
try
{
Console.WriteLine("Connecting to hub");
Client = DeviceClient.CreateFromConnectionString(DeviceConnectionString, TransportType.Mqtt);

// setup callback for "reboot" method


Client.SetMethodHandlerAsync("reboot", onReboot, null).Wait();
Console.WriteLine("Waiting for reboot method\n Press enter to exit.");
Console.ReadLine();

Console.WriteLine("Exiting...");

// as a good practice, remove the "reboot" handler


Client.SetMethodHandlerAsync("reboot", null, null).Wait();
Client.CloseAsync().Wait();
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}

8. In the Visual Studio Solution Explorer, right-click your solution, and then click Set StartUp Projects....
Select Single startup project, and then select the SimulateManagedDevice project in the dropdown
menu. Build the solution.

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Run the apps


You are now ready to run the apps.
1. Run the .NET device app SimulateManagedDevice. Right-click the SimulateManagedDevice
project, select Debug, and then select Start new instance. It should start listening for method calls from
your IoT Hub:
2. Now that the device is connected and waiting for method invocations, run the .NET TriggerReboot app
to invoke the reboot method in the simulated device app. Right-click the TriggerReboot project, select
Debug, and then select Start new instance. You should see "Rebooting!" written in the
SimulatedManagedDevice console and the reported properties of the device, which include the last
reboot time, written in the TriggerReboot console.

Customize and extend the device management actions


Your IoT solutions can expand the defined set of device management patterns or enable custom patterns by
using the device twin and cloud-to-device method primitives. Other examples of device management actions
include factory reset, firmware update, software update, power management, network and connectivity
management, and data encryption.

Device maintenance windows


Typically, you configure devices to perform actions at a time that minimizes interruptions and downtime. Device
maintenance windows are a commonly used pattern to define the time when a device should update its
configuration. Your back-end solutions can use the desired properties of the device twin to define and activate a
policy on your device that enables a maintenance window. When a device receives the maintenance window
policy, it can use the reported property of the device twin to report the status of the policy. The back-end app
can then use device twin queries to attest to compliance of devices and each policy.

Next steps
In this tutorial, you used a direct method to trigger a remote reboot on a device. You used the reported
properties to report the last reboot time from the device, and queried the device twin to discover the last reboot
time of the device from the cloud.
To continue getting started with IoT Hub and device management patterns such as remote over the air firmware
update, see:
Tutorial: How to do a firmware update
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
To continue getting started with IoT Hub, see Getting started with IoT Edge.
Get started with device management (Java)
5/29/2018 • 12 min to read • Edit Online

Back-end apps can use Azure IoT Hub primitives, such as device twin and direct methods, to remotely start and
monitor device management actions on devices. This tutorial shows you how a back-end app and a device app
can work together to initiate and monitor a remote device reboot using IoT Hub.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use a direct method to initiate device management actions (such as reboot, factory reset, and firmware update)
from a back-end app in the cloud. The device is responsible for:
Handling the method request sent from IoT Hub.
Initiating the corresponding device-specific action on the device.
Providing status updates through reported properties to IoT Hub.
You can use a back-end app in the cloud to run device twin queries to report on the progress of your device
management actions.
This tutorial shows you how to:
Use the Azure portal to create an IoT Hub and create a device identity in your IoT hub.
Create a simulated device app that implements a direct method to reboot the device. Direct methods are
invoked from the cloud.
Create an app that invokes the reboot direct method in the simulated device app through your IoT hub. This
app then monitors the reported properties from the device to see when the reboot operation is complete.
At the end of this tutorial, you have two Java console apps:
simulated-device. This app:
Connects to your IoT hub with the device identity created earlier.
Receives a reboot direct method call.
Simulates a physical reboot.
Reports the time of the last reboot through a reported property.
trigger-reboot. This app:
Calls a direct method in the simulated device app.
Displays the response to the direct method call sent by the simulated device
Displays the updated reported properties.

NOTE
For information about the SDKs that you can use to build applications to run on devices and your solution back end, see
Azure IoT SDKs.

To complete this tutorial, you need:


Java SE 8.
Prepare your development environment describes how to install Java for this tutorial on either Windows or
Linux.
Maven 3.
Prepare your development environment describes how to install Maven for this tutorial on either Windows
or Linux.
Node.js version 0.10.0 or later.

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device
IDs are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with the
IoT Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to
avoid any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the device
app to connect to your IoT Hub as a device.
Refer to Getting started with IoT Hub to programmatically create device identities.

Trigger a remote reboot on the device using a direct method


In this section, you create a Java console app that:
1. Invokes the reboot direct method in the simulated device app.
2. Displays the response.
3. Polls the reported properties sent from the device to determine when the reboot is complete.
This console app connects to your IoT Hub to invoke the direct method and read the reported properties.
1. Create an empty folder called dm-get-started.
2. In the dm-get-started folder, create a Maven project called trigger-reboot using the following command
at your command prompt. The following shows a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=trigger-reboot -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

3. At your command prompt, navigate to the trigger-reboot folder.


4. Using a text editor, open the pom.xml file in the trigger-reboot folder and add the following dependency
to the dependencies node. This dependency enables you to use the iot-service-client package in your
app to communicate with your IoT hub:

<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-service-client</artifactId>
<version>1.7.23</version>
<type>jar</type>
</dependency>

NOTE
You can check for the latest version of iot-service-client using Maven search.

5. Add the following build node after the dependencies node. This configuration instructs Maven to use
Java 1.8 to build the app:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

6. Save and close the pom.xml file.


7. Using a text editor, open the trigger-reboot\src\main\java\com\mycompany\app\App.java source file.
8. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceMethod;
import com.microsoft.azure.sdk.iot.service.devicetwin.MethodResult;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;
import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwin;
import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwinDevice;

import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;

9. Add the following class-level variables to the App class. Replace {youriothubconnectionstring} with your
IoT hub connection string you noted in the Create an IoT Hub section:

public static final String iotHubConnectionString = "{youriothubconnectionstring}";


public static final String deviceId = "myDeviceId";

private static final String methodName = "reboot";


private static final Long responseTimeout = TimeUnit.SECONDS.toSeconds(30);
private static final Long connectTimeout = TimeUnit.SECONDS.toSeconds(5);

10. To implement a thread that reads the reported properties from the device twin every 10 seconds, add the
following nested class to the App class:

private static class ShowReportedProperties implements Runnable {


public void run() {
try {
DeviceTwin deviceTwins = DeviceTwin.createFromConnectionString(iotHubConnectionString);
DeviceTwinDevice twinDevice = new DeviceTwinDevice(deviceId);
while (true) {
System.out.println("Get reported properties from device twin");
deviceTwins.getTwin(twinDevice);
System.out.println(twinDevice.reportedPropertiesToString());
Thread.sleep(10000);
}
} catch (Exception ex) {
System.out.println("Exception reading reported properties: " + ex.getMessage());
}
}
}
11. Modify the signature of the main method to throw the following exception:

public static void main(String[] args) throws IOException

12. To invoke the reboot direct method on the simulated device, add the following code to the main method:

System.out.println("Starting sample...");
DeviceMethod methodClient = DeviceMethod.createFromConnectionString(iotHubConnectionString);

try
{
System.out.println("Invoke reboot direct method");
MethodResult result = methodClient.invoke(deviceId, methodName, responseTimeout, connectTimeout,
null);

if(result == null)
{
throw new IOException("Invoke direct method reboot returns null");
}
System.out.println("Invoked reboot on device");
System.out.println("Status for device: " + result.getStatus());
System.out.println("Message from device: " + result.getPayload());
}
catch (IotHubException e)
{
System.out.println(e.getMessage());
}

13. To start the thread to poll the reported properties from the simulated device, add the following code to
the main method:

ShowReportedProperties showReportedProperties = new ShowReportedProperties();


ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(showReportedProperties);

14. To enable you to stop the app, add the following code to the main method:

System.out.println("Press ENTER to exit.");


System.in.read();
executor.shutdownNow();
System.out.println("Shutting down sample...");

15. Save and close the trigger-reboot\src\main\java\com\mycompany\app\App.java file.


16. Build the trigger-reboot back-end app and correct any errors. At your command prompt, navigate to the
trigger-reboot folder and run the following command:
mvn clean package -DskipTests

Create a simulated device app


In this section, you create a Java console app that simulates a device. The app listens for the reboot direct
method call from your IoT hub and immediately responds to that call. The app then sleeps for a while to
simulate the reboot process before it uses a reported property to notify the trigger-reboot back-end app that
the reboot is complete.
1. In the dm-get-started folder, create a Maven project called simulated-device using the following
command at your command prompt. The following is a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=simulated-device -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2. At your command prompt, navigate to the simulated-device folder.


3. Using a text editor, open the pom.xml file in the simulated-device folder and add the following
dependency to the dependencies node. This dependency enables you to use the iot-service-client
package in your app to communicate with your IoT hub:

<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-device-client</artifactId>
<version>1.3.32</version>
</dependency>

NOTE
You can check for the latest version of iot-device-client using Maven search.

4. Add the following build node after the dependencies node. This configuration instructs Maven to use
Java 1.8 to build the app:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

5. Save and close the pom.xml file.


6. Using a text editor, open the simulated-device\src\main\java\com\mycompany\app\App.java source file.
7. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.device.*;
import com.microsoft.azure.sdk.iot.device.DeviceTwin.*;

import java.io.IOException;
import java.net.URISyntaxException;
import java.time.LocalDateTime;
import java.util.Scanner;
import java.util.Set;
import java.util.HashSet;

8. Add the following class-level variables to the App class. Replace {yourdeviceconnectionstring} with the
device connection string you noted in the Create a device identity section:
private static final int METHOD_SUCCESS = 200;
private static final int METHOD_NOT_DEFINED = 404;

private static IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;


private static String connString = "{yourdeviceconnectionstring}";
private static DeviceClient client;

9. To implement a callback handler for direct method status events, add the following nested class to the
App class:

protected static class DirectMethodStatusCallback implements IotHubEventCallback


{
public void execute(IotHubStatusCode status, Object context)
{
System.out.println("IoT Hub responded to device method operation with status " + status.name());
}
}

10. To implement a callback handler for device twin status events, add the following nested class to the App
class:

protected static class DeviceTwinStatusCallback implements IotHubEventCallback


{
public void execute(IotHubStatusCode status, Object context)
{
System.out.println("IoT Hub responded to device twin operation with status " +
status.name());
}
}

11. To implement a callback handler for property events, add the following nested class to the App class:

protected static class PropertyCallback implements PropertyCallBack<String, String>


{
public void PropertyCall(String propertyKey, String propertyValue, Object context)
{
System.out.println("PropertyKey: " + propertyKey);
System.out.println("PropertyKvalue: " + propertyKey);
}
}

12. To implement a thread to simulate the device reboot, add the following nested class to the App class. The
thread sleeps for five seconds and then sets the lastReboot reported property:
protected static class RebootDeviceThread implements Runnable {
public void run() {
try {
System.out.println("Rebooting...");
Thread.sleep(5000);
Property property = new Property("lastReboot", LocalDateTime.now());
Set<Property> properties = new HashSet<Property>();
properties.add(property);
client.sendReportedProperties(properties);
System.out.println("Rebooted");
}
catch (Exception ex) {
System.out.println("Exception in reboot thread: " + ex.getMessage());
}
}
}

13. To implement the direct method on the device, add the following nested class to the App class. When the
simulated app receives a call to the reboot direct method, it returns an acknowledgement to the caller
and then starts a thread to process the reboot:

protected static class DirectMethodCallback implements


com.microsoft.azure.sdk.iot.device.DeviceTwin.DeviceMethodCallback
{
@Override
public DeviceMethodData call(String methodName, Object methodData, Object context)
{
DeviceMethodData deviceMethodData;
switch (methodName)
{
case "reboot" :
{
int status = METHOD_SUCCESS;
System.out.println("Received reboot request");
deviceMethodData = new DeviceMethodData(status, "Started reboot");
RebootDeviceThread rebootThread = new RebootDeviceThread();
Thread t = new Thread(rebootThread);
t.start();
break;
}
default:
{
int status = METHOD_NOT_DEFINED;
deviceMethodData = new DeviceMethodData(status, "Not defined direct method " + methodName);
}
}
return deviceMethodData;
}
}

14. Modify the signature of the main method to throw the following exceptions:

public static void main(String[] args) throws IOException, URISyntaxException

15. To instantiate a DeviceClient, add the following code to the main method:

System.out.println("Starting device client sample...");


client = new DeviceClient(connString, protocol);

16. To start listening for direct method calls, add the following code to the main method:
try
{
client.open();
client.subscribeToDeviceMethod(new DirectMethodCallback(), null, new DirectMethodStatusCallback(),
null);
client.startDeviceTwin(new DeviceTwinStatusCallback(), null, new PropertyCallback(), null);
System.out.println("Subscribed to direct methods and polling for reported properties. Waiting...");
}
catch (Exception e)
{
System.out.println("On exception, shutting down \n" + " Cause: " + e.getCause() + " \n" +
e.getMessage());
client.close();
System.out.println("Shutting down...");
}

17. To shut down the device simulator, add the following code to the main method:

System.out.println("Press any key to exit...");


Scanner scanner = new Scanner(System.in);
scanner.nextLine();
scanner.close();
client.close();
System.out.println("Shutting down...");

18. Save and close the simulated-device\src\main\java\com\mycompany\app\App.java file.


19. Build the simulated-device back-end app and correct any errors. At your command prompt, navigate to
the simulated-device folder and run the following command:
mvn clean package -DskipTests

Run the apps


You are now ready to run the apps.
1. At a command prompt in the simulated-device folder, run the following command to begin listening for
reboot method calls from your IoT hub:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
2. At a command prompt in the trigger-reboot folder, run the following command to call the reboot method
on your simulated device from your IoT hub:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

3. The simulated device responds to the reboot direct method call:

Customize and extend the device management actions


Your IoT solutions can expand the defined set of device management patterns or enable custom patterns by
using the device twin and cloud-to-device method primitives. Other examples of device management actions
include factory reset, firmware update, software update, power management, network and connectivity
management, and data encryption.

Device maintenance windows


Typically, you configure devices to perform actions at a time that minimizes interruptions and downtime. Device
maintenance windows are a commonly used pattern to define the time when a device should update its
configuration. Your back-end solutions can use the desired properties of the device twin to define and activate a
policy on your device that enables a maintenance window. When a device receives the maintenance window
policy, it can use the reported property of the device twin to report the status of the policy. The back-end app can
then use device twin queries to attest to compliance of devices and each policy.

Next steps
In this tutorial, you used a direct method to trigger a remote reboot on a device. You used the reported
properties to report the last reboot time from the device, and queried the device twin to discover the last reboot
time of the device from the cloud.
To continue getting started with IoT Hub and device management patterns such as remote over the air firmware
update, see:
Tutorial: How to do a firmware update
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
To continue getting started with IoT Hub, see Getting started with IoT Edge.
Get started with device management (Python)
5/29/2018 • 9 min to read • Edit Online

Back-end apps can use Azure IoT Hub primitives, such as device twin and direct methods, to remotely start and
monitor device management actions on devices. This tutorial shows you how a back-end app and a device app
can work together to initiate and monitor a remote device reboot using IoT Hub.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Use a direct method to initiate device management actions (such as reboot, factory reset, and firmware update)
from a back-end app in the cloud. The device is responsible for:
Handling the method request sent from IoT Hub.
Initiating the corresponding device-specific action on the device.
Providing status updates through reported properties to IoT Hub.
You can use a back-end app in the cloud to run device twin queries to report on the progress of your device
management actions.
This tutorial shows you how to:
Use the Azure portal to create an IoT Hub and create a device identity in your IoT hub.
Create a simulated device app that contains a direct method that reboots that device. Direct methods are
invoked from the cloud.
Create a Python console app that calls the reboot direct method in the simulated device app through your IoT
hub.
At the end of this tutorial, you have two Python console apps:
dmpatterns_getstarted_device.py, which connects to your IoT hub with the device identity created earlier,
receives a reboot direct method, simulates a physical reboot, and reports the time for the last reboot.
dmpatterns_getstarted_service.py, which calls a direct method in the simulated device app, displays the
response, and displays the updated reported properties.
To complete this tutorial, you need the following:
Python 2.x or 3.x. Make sure to use the 32-bit or 64-bit installation as required by your setup. When
prompted during the installation, make sure to add Python to your platform-specific environment variable. If
you are using Python 2.x, you may need to install or upgrade pip, the Python package management system.
Install the azure-iothub-device-client package, using the command
pip install azure-iothub-device-client
Install the azure-iothub-service-client package, using the command
pip install azure-iothub-service-client
If you are using Windows OS, then Visual C++ redistributable package to allow the use of native DLLs from
Python.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)
Create an IoT hub
Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A
device cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the
"Identity registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a
unique device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new
device identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use
later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and
keys to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device.
If your application needs to store other device-specific metadata, it should use an application-specific store. For more
information, see IoT Hub developer guide.

Create a simulated device app


In this section, you will:
Create a Python console app that responds to a direct method called by the cloud
Simulate a device reboot
Use the reported properties to enable device twin queries to identify devices and when they last rebooted
1. Using a text editor, create a dmpatterns_getstarted_device.py file.
2. Add the following import statements at the start of the dmpatterns_getstarted_device.py file.

import random
import time, datetime
import sys

import iothub_client
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider,
IoTHubClientResult, IoTHubError, DeviceMethodReturnValue

3. Add variables including a CONNECTION_STRING variable and the client intialization. Replace the
connection string with your device connection string.

CONNECTION_STRING = "{deviceConnectionString}"
PROTOCOL = IoTHubTransportProvider.MQTT

CLIENT = IoTHubClient(CONNECTION_STRING, PROTOCOL)

WAIT_COUNT = 5

SEND_REPORTED_STATE_CONTEXT = 0
METHOD_CONTEXT = 0

SEND_REPORTED_STATE_CALLBACKS = 0
METHOD_CALLBACKS = 0
4. Add the following function callbacks to implement the direct method on the device.

def send_reported_state_callback(status_code, user_context):


global SEND_REPORTED_STATE_CALLBACKS

print ( "Device twins updated." )

def device_method_callback(method_name, payload, user_context):


global METHOD_CALLBACKS

if method_name == "rebootDevice":
print ( "Rebooting device..." )

time.sleep(20)

print ( "Device rebooted." )

current_time = str(datetime.datetime.now())
reported_state = "{\"rebootTime\":\"" + current_time + "\"}"
CLIENT.send_reported_state(reported_state, len(reported_state), send_reported_state_callback,
SEND_REPORTED_STATE_CONTEXT)

print ( "Updating device twins: rebootTime" )

device_method_return_value = DeviceMethodReturnValue()
device_method_return_value.response = "{ \"Response\": \"This is the response from the device\" }"
device_method_return_value.status = 200

return device_method_return_value

5. Start the direct method listener and wait.

def iothub_client_init():
if CLIENT.protocol == IoTHubTransportProvider.MQTT or client.protocol ==
IoTHubTransportProvider.MQTT_WS:
CLIENT.set_device_method_callback(device_method_callback, METHOD_CONTEXT)

def iothub_client_sample_run():
try:
iothub_client_init()

while True:
print ( "IoTHubClient waiting for commands, press Ctrl-C to exit" )

status_counter = 0
while status_counter <= WAIT_COUNT:
time.sleep(10)
status_counter += 1

except IoTHubError as iothub_error:


print ( "Unexpected error %s from IoTHub" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubClient sample stopped" )

if __name__ == '__main__':
print ( "Starting the IoT Hub Python sample..." )
print ( " Protocol %s" % PROTOCOL )
print ( " Connection string=%s" % CONNECTION_STRING )

iothub_client_sample_run()

6. Save and close the dmpatterns_getstarted_device.py file.


NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Trigger a remote reboot on the device using a direct method


In this section, you create a Python console app that initiates a remote reboot on a device using a direct method.
The app uses device twin queries to discover the last reboot time for that device.
1. Using a text editor, create a dmpatterns_getstarted_service.py file.
2. Add the following import statements at the start of the dmpatterns_getstarted_service.py file.

import sys, time


import iothub_service_client

from iothub_service_client import IoTHubDeviceMethod, IoTHubError, IoTHubDeviceTwin

3. Add the following variable declarations. Only replace placeholder values for IoTHubConnectionString and
deviceId.

CONNECTION_STRING = "{IoTHubConnectionString}"
DEVICE_ID = "{deviceId}"

METHOD_NAME = "rebootDevice"
METHOD_PAYLOAD = "{\"method_number\":\"42\"}"
TIMEOUT = 60
WAIT_COUNT = 10

4. Add the following function to invoke the device method to reboot the target device, then query for the
device twins and get the last reboot time.
def iothub_devicemethod_sample_run():
try:
iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)
iothub_device_method = IoTHubDeviceMethod(CONNECTION_STRING)

print ( "" )
print ( "Invoking device to reboot..." )

response = iothub_device_method.invoke(DEVICE_ID, METHOD_NAME, METHOD_PAYLOAD, TIMEOUT)

print ( "" )
print ( "Successfully invoked the device to reboot." )

print ( "" )
print ( response.payload )

while True:
print ( "" )
print ( "IoTHubClient waiting for commands, press Ctrl-C to exit" )

status_counter = 0
while status_counter <= WAIT_COUNT:
twin_info = iothub_twin_method.get_twin(DEVICE_ID)

if twin_info.find("rebootTime") != -1:
print ( "Last reboot time: " +
twin_info[twin_info.find("rebootTime")+11:twin_info.find("rebootTime")+37])
else:
print ("Waiting for device to report last reboot time...")

time.sleep(5)
status_counter += 1

except IoTHubError as iothub_error:


print ( "" )
print ( "Unexpected error {0}".format(iothub_error) )
return
except KeyboardInterrupt:
print ( "" )
print ( "IoTHubDeviceMethod sample stopped" )

if __name__ == '__main__':
print ( "Starting the IoT Hub Service Client DeviceManagement Python sample..." )
print ( " Connection string = {0}".format(CONNECTION_STRING) )
print ( " Device ID = {0}".format(DEVICE_ID) )

iothub_devicemethod_sample_run()

5. Save and close the dmpatterns_getstarted_service.py file.

Run the apps


You are now ready to run the apps.
1. At the command prompt, run the following command to begin listening for the reboot direct method.

python dmpatterns_getstarted_device.py

2. At another command prompt, run the following command to trigger the remote reboot and query for the
device twin to find the last reboot time.
python dmpatterns_getstarted_service.py

3. You see the device response to the direct method in the console.

Customize and extend the device management actions


Your IoT solutions can expand the defined set of device management patterns or enable custom patterns by
using the device twin and cloud-to-device method primitives. Other examples of device management actions
include factory reset, firmware update, software update, power management, network and connectivity
management, and data encryption.

Device maintenance windows


Typically, you configure devices to perform actions at a time that minimizes interruptions and downtime. Device
maintenance windows are a commonly used pattern to define the time when a device should update its
configuration. Your back-end solutions can use the desired properties of the device twin to define and activate a
policy on your device that enables a maintenance window. When a device receives the maintenance window
policy, it can use the reported property of the device twin to report the status of the policy. The back-end app can
then use device twin queries to attest to compliance of devices and each policy.

Next steps
In this tutorial, you used a direct method to trigger a remote reboot on a device. You used the reported
properties to report the last reboot time from the device, and queried the device twin to discover the last reboot
time of the device from the cloud.
To continue getting started with IoT Hub and device management patterns such as remote over the air firmware
update, see:
Tutorial: How to do a firmware update
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
To continue getting started with IoT Hub, see Getting started with IoT Edge.
1 min to read •
Edit Online
1 min to read •
Edit Online
1 min to read •
Edit Online
1 min to read •
Edit Online
1 min to read •
Edit Online
Use device management to initiate a device
firmware update (Node/Node)
5/29/2018 • 10 min to read • Edit Online

In the Get started with device management tutorial, you saw how to use the device twin and direct methods
primitives to remotely reboot a device. This tutorial uses the same IoT Hub primitives and provides guidance
and shows you how to do an end-to-end simulated firmware update. This pattern is used in the firmware
update implementation for the Intel Edison device sample.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a Node.js console app that calls the firmwareUpdate direct method in the simulated device app
through your IoT hub.
Create a simulated device app that implements a firmwareUpdate direct method. This method initiates a
multi-stage process that waits to download the firmware image, downloads the firmware image, and finally
applies the firmware image. During each stage of the update, the device uses the reported properties to
report on progress.
At the end of this tutorial, you have two Node.js console apps:
dmpatterns_fwupdate_service.js, which calls a direct method in the simulated device app, displays the
response, and periodically (every 500ms) displays the updated reported properties.
dmpatterns_fwupdate_device.js, which connects to your IoT hub with the device identity created earlier,
receives a firmwareUpdate direct method, runs through a multi-state process to simulate a firmware update
including: waiting for the image download, downloading the new image, and finally applying the image.
To complete this tutorial, you need the following:
Node.js version 4.0.x or later,
Prepare your development environment describes how to install Node.js for this tutorial on either
Windows or Linux.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)
Follow the Get started with device management article to create your IoT hub and get your IoT Hub
connection string.

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information
while naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create.
You can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now
that you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device
IDs are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with
the IoT Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to
avoid any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the
device app to connect to your IoT Hub as a device.
Refer to Getting started with IoT Hub to programmatically create device identities.

Trigger a remote firmware update on the device using a direct


method
In this section, you create a Node.js console app that initiates a remote firmware update on a device. The app
uses a direct method to initiate the update and uses device twin queries to periodically get the status of the
active firmware update.
1. Create an empty folder called triggerfwupdateondevice. In the triggerfwupdateondevice folder,
create a package.json file using the following command at your command prompt. Accept all the
defaults:

npm init

2. At your command prompt in the triggerfwupdateondevice folder, run the following command to
install the azure-iot-hub package:

npm install azure-iothub --save

3. Using a text editor, create a dmpatterns_getstarted_service.js file in the triggerfwupdateondevice


folder.
4. Add the following 'require' statements at the start of the dmpatterns_getstarted_service.js file:

'use strict';

var Registry = require('azure-iothub').Registry;


var Client = require('azure-iothub').Client;

5. Add the following variable declarations and replace the placeholder values:

var connectionString = '{device_connectionstring}';


var registry = Registry.fromConnectionString(connectionString);
var client = Client.fromConnectionString(connectionString);
var deviceToUpdate = 'myDeviceId';

6. Add the following function to find and display the value of the firmwareUpdate reported property.
var queryTwinFWUpdateReported = function() {
registry.getTwin(deviceToUpdate, function(err, twin){
if (err) {
console.error('Could not query twins: ' + err.constructor.name + ': ' + err.message);
} else {
console.log((JSON.stringify(twin.properties.reported.iothubDM.firmwareUpdate)) + "\n");
}
});
};

7. Add the following function to invoke the firmwareUpdate method to reboot the target device:

var startFirmwareUpdateDevice = function() {


var params = {
fwPackageUri: 'https://secureurl'
};

var methodName = "firmwareUpdate";


var payloadData = JSON.stringify(params);

var methodParams = {
methodName: methodName,
payload: payloadData,
timeoutInSeconds: 30
};

client.invokeDeviceMethod(deviceToUpdate, methodParams, function(err, result) {


if (err) {
console.error('Could not start the firmware update on the device: ' + err.message)
}
});
};

8. Finally, Add the following function to code to start the firmware update sequence and start periodically
showing the reported properties:

startFirmwareUpdateDevice();
setInterval(queryTwinFWUpdateReported, 500);

9. Save and close the dmpatterns_fwupdate_service.js file.

Create a simulated device app


In this section, you:
Create a Node.js console app that responds to a direct method called by the cloud
Trigger a simulated firmware update
Use the reported properties to enable device twin queries to identify devices and when they last completed
a firmware update
1. Create an empty folder called manageddevice. In the manageddevice folder, create a package.json
file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the manageddevice folder, run the following command to install the
azure-iot-device and azure-iot-device-mqtt Device SDK packages:
npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a dmpatterns_fwupdate_device.js file in the manageddevice folder.


4. Add the following 'require' statements at the start of the dmpatterns_fwupdate_device.js file:

'use strict';

var Client = require('azure-iot-device').Client;


var Protocol = require('azure-iot-device-mqtt').Mqtt;

5. Add a connectionString variable and use it to create a Client instance. Replace the
{yourdeviceconnectionstring} placeholder with the connection string you previously made a note of in
the "Create a device identity" section previously:

var connectionString = '{yourdeviceconnectionstring}';


var client = Client.fromConnectionString(connectionString, Protocol);

6. Add the following function that is used to update reported properties:

var reportFWUpdateThroughTwin = function(twin, firmwareUpdateValue) {


var patch = {
iothubDM : {
firmwareUpdate : firmwareUpdateValue
}
};

twin.properties.reported.update(patch, function(err) {
if (err) throw err;
console.log('twin state reported: ' + firmwareUpdateValue.status);
});
};

7. Add the following functions that simulate downloading and applying the firmware image:

var simulateDownloadImage = function(imageUrl, callback) {


var error = null;
var image = "[fake image data]";

console.log("Downloading image from " + imageUrl);

callback(error, image);
}

var simulateApplyImage = function(imageData, callback) {


var error = null;

if (!imageData) {
error = {message: 'Apply image failed because of missing image data.'};
}

callback(error);
}

8. Add the following function that updates the firmware update status through the reported properties to
waiting. Typically, devices are informed of an available update and an administrator defined policy
causes the device to start downloading and applying the update. This function is where the logic to
enable that policy should run. For simplicity, the sample waits for four seconds before proceeding to
download the firmware image:

var waitToDownload = function(twin, fwPackageUriVal, callback) {


var now = new Date();

reportFWUpdateThroughTwin(twin, {
fwPackageUri: fwPackageUriVal,
status: 'waiting',
error : null,
startedWaitingTime : now.toISOString()
});
setTimeout(callback, 4000);
};

9. Add the following function that updates the firmware update status through the reported properties to
downloading. The function then simulates a firmware download and finally updates the firmware
update status to either downloadFailed or downloadComplete:

var downloadImage = function(twin, fwPackageUriVal, callback) {


var now = new Date();

reportFWUpdateThroughTwin(twin, {
status: 'downloading',
});

setTimeout(function() {
// Simulate download
simulateDownloadImage(fwPackageUriVal, function(err, image) {

if (err)
{
reportFWUpdateThroughTwin(twin, {
status: 'downloadfailed',
error: {
code: error_code,
message: error_message,
}
});
}
else {
reportFWUpdateThroughTwin(twin, {
status: 'downloadComplete',
downloadCompleteTime: now.toISOString(),
});

setTimeout(function() { callback(image); }, 4000);


}
});

}, 4000);
}

10. Add the following function that updates the firmware update status through the reported properties to
applying. The function then simulates applying the firmware image and finally updates the firmware
update status to either applyFailed or applyComplete:
var applyImage = function(twin, imageData, callback) {
var now = new Date();

reportFWUpdateThroughTwin(twin, {
status: 'applying',
startedApplyingImage : now.toISOString()
});

setTimeout(function() {

// Simulate apply firmware image


simulateApplyImage(imageData, function(err) {
if (err) {
reportFWUpdateThroughTwin(twin, {
status: 'applyFailed',
error: {
code: err.error_code,
message: err.error_message,
}
});
} else {
reportFWUpdateThroughTwin(twin, {
status: 'applyComplete',
lastFirmwareUpdate: now.toISOString()
});

}
});

setTimeout(callback, 4000);

}, 4000);
}

11. Add the following function that handles the firmwareUpdate direct method and initiates the multi-
stage firmware update process:
var onFirmwareUpdate = function(request, response) {

// Respond the cloud app for the direct method


response.send(200, 'FirmwareUpdate started', function(err) {
if (!err) {
console.error('An error occured when sending a method response:\n' + err.toString());
} else {
console.log('Response to method \'' + request.methodName + '\' sent successfully.');
}
});

// Get the parameter from the body of the method request


var fwPackageUri = request.payload.fwPackageUri;

// Obtain the device twin


client.getTwin(function(err, twin) {
if (err) {
console.error('Could not get device twin.');
} else {
console.log('Device twin acquired.');

// Start the multi-stage firmware update


waitToDownload(twin, fwPackageUri, function() {
downloadImage(twin, fwPackageUri, function(imageData) {
applyImage(twin, imageData, function() {});
});
});

}
});
}

12. Finally, add the following code that connects to your IoT hub:

client.open(function(err) {
if (err) {
console.error('Could not connect to IotHub client');
} else {
console.log('Client connected to IoT Hub. Waiting for firmwareUpdate direct method.');
}

client.onDeviceMethod('firmwareUpdate', onFirmwareUpdate);
});

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement
retry policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Run the apps


You are now ready to run the apps.
1. At the command prompt in the manageddevice folder, run the following command to begin listening
for the reboot direct method.

node dmpatterns_fwupdate_device.js

2. At the command prompt in the triggerfwupdateondevice folder, run the following command to
trigger the remote reboot and query for the device twin to find the last reboot time.

node dmpatterns_fwupdate_service.js

3. You see the device response to the direct method in the console.

Next steps
In this tutorial, you used a direct method to trigger a remote firmware update on a device and used the
reported properties to follow the progress of the firmware update.
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
Use device management to initiate a device
firmware update (.NET/Node)
5/29/2018 • 10 min to read • Edit Online

In the Get started with device management tutorial, you saw how to use the device twin and direct methods
primitives to remotely reboot a device. This tutorial uses the same IoT Hub primitives and shows you how to do
an end-to-end simulated firmware update. This pattern is used in the firmware update implementation for the
Raspberry Pi device implementation sample.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a .NET console app that calls the firmwareUpdate direct method in the simulated device app through
your IoT hub.
Create a simulated device app that implements a firmwareUpdate direct method. This method initiates a
multi-stage process that waits to download the firmware image, downloads the firmware image, and finally
applies the firmware image. During each stage of the update, the device uses the reported properties to
report on progress.
At the end of this tutorial, you have a Node.js console device app and a .NET (C#) console back-end app:
dmpatterns_fwupdate_service.js, which calls a direct method in the simulated device app, displays the
response, and periodically (every 500ms) displays the updated reported properties.
TriggerFWUpdate, which connects to your IoT hub with the device identity created earlier, receives a
firmwareUpdate direct method, runs through a multi-state process to simulate a firmware update including:
waiting for the image download, downloading the new image, and finally applying the image.
To complete this tutorial, you need the following:
Visual Studio 2015 or Visual Studio 2017.
Node.js version 4.0.x or later,
Prepare your development environment describes how to install Node.js for this tutorial on either Windows
or Linux.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)
Follow the Get started with device management article to create your IoT hub and get your IoT Hub connection
string.

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device IDs
are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with the
IoT Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the device
app to connect to your IoT Hub as a device.
Refer to Getting started with IoT Hub to programmatically create device identities.

Trigger a remote firmware update on the device using a direct method


In this section, you create a .NET console app (using C#) that initiates a remote firmware update on a device. The
app uses a direct method to initiate the update and uses device twin queries to periodically get the status of the
active firmware update.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project TriggerFWUpdate.

2. In Solution Explorer, right-click the TriggerFWUpdate project, and then click Manage NuGet
Packages....
3. In the NuGet Package Manager window, select Browse, search for microsoft.azure.devices, select
Install to install the Microsoft.Azure.Devices package, and accept the terms of use. This procedure
downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package and its
dependencies.
4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;

5. Add the following fields to the Program class. Replace the multiple placeholder values with the IoT Hub
connection string for the hub that you created in the previous section and the Id of your device.

static RegistryManager registryManager;


static string connString = "{iot hub connection string}";
static ServiceClient client;
static string targetDevice = "{deviceIdForTargetDevice}";

6. Add the following method to the Program class:

public static async Task QueryTwinFWUpdateReported()


{
Twin twin = await registryManager.GetTwinAsync(targetDevice);
Console.WriteLine(twin.Properties.Reported.ToJson());
}

7. Add the following method to the Program class:


public static async Task StartFirmwareUpdate()
{
client = ServiceClient.CreateFromConnectionString(connString);
CloudToDeviceMethod method = new CloudToDeviceMethod("firmwareUpdate");
method.ResponseTimeout = TimeSpan.FromSeconds(30);
method.SetPayloadJson(
@"{
fwPackageUri : 'https://someurl'
}");

CloudToDeviceMethodResult result = await client.InvokeDeviceMethodAsync(targetDevice, method);

Console.WriteLine("Invoked firmware update on device.");


}

8. Finally, add the following lines to the Main method:

registryManager = RegistryManager.CreateFromConnectionString(connString);
StartFirmwareUpdate().Wait();
QueryTwinFWUpdateReported().Wait();
Console.WriteLine("Press ENTER to exit.");
Console.ReadLine();

9. In the Solution Explorer, open the Set StartUp projects... and make sure the Action for
TriggerFWUpdate project is Start.
10. Build the solution.

Create a simulated device app


In this section, you:
Create a Node.js console app that responds to a direct method called by the cloud
Trigger a simulated firmware update
Use the reported properties to enable device twin queries to identify devices and when they last completed a
firmware update
1. Create an empty folder called manageddevice. In the manageddevice folder, create a package.json file
using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the manageddevice folder, run the following command to install the azure-
iot-device and azure-iot-device-mqtt Device SDK packages:

npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a dmpatterns_fwupdate_device.js file in the manageddevice folder.


4. Add the following 'require' statements at the start of the dmpatterns_fwupdate_device.js file:

'use strict';

var Client = require('azure-iot-device').Client;


var Protocol = require('azure-iot-device-mqtt').Mqtt;
5. Add a connectionString variable and use it to create a Client instance. Replace the
{yourdeviceconnectionstring} placeholder with the connection string you previously made a note of in the
"Create a device identity" section previously:

var connectionString = '{yourdeviceconnectionstring}';


var client = Client.fromConnectionString(connectionString, Protocol);

6. Add the following function that is used to update reported properties:

var reportFWUpdateThroughTwin = function(twin, firmwareUpdateValue) {


var patch = {
iothubDM : {
firmwareUpdate : firmwareUpdateValue
}
};

twin.properties.reported.update(patch, function(err) {
if (err) throw err;
console.log('twin state reported: ' + firmwareUpdateValue.status);
});
};

7. Add the following functions that simulate downloading and applying the firmware image:

var simulateDownloadImage = function(imageUrl, callback) {


var error = null;
var image = "[fake image data]";

console.log("Downloading image from " + imageUrl);

callback(error, image);
}

var simulateApplyImage = function(imageData, callback) {


var error = null;

if (!imageData) {
error = {message: 'Apply image failed because of missing image data.'};
}

callback(error);
}

8. Add the following function that updates the firmware update status through the reported properties to
waiting. Typically, devices are informed of an available update and an administrator defined policy causes
the device to start downloading and applying the update. This function is where the logic to enable that
policy should run. For simplicity, the sample waits for four seconds before proceeding to download the
firmware image:
var waitToDownload = function(twin, fwPackageUriVal, callback) {
var now = new Date();

reportFWUpdateThroughTwin(twin, {
fwPackageUri: fwPackageUriVal,
status: 'waiting',
error : null,
startedWaitingTime : now.toISOString()
});
setTimeout(callback, 4000);
};

9. Add the following function that updates the firmware update status through the reported properties to
downloading. The function then simulates a firmware download and finally updates the firmware update
status to either downloadFailed or downloadComplete:

var downloadImage = function(twin, fwPackageUriVal, callback) {


var now = new Date();

reportFWUpdateThroughTwin(twin, {
status: 'downloading',
});

setTimeout(function() {
// Simulate download
simulateDownloadImage(fwPackageUriVal, function(err, image) {

if (err)
{
reportFWUpdateThroughTwin(twin, {
status: 'downloadfailed',
error: {
code: error_code,
message: error_message,
}
});
}
else {
reportFWUpdateThroughTwin(twin, {
status: 'downloadComplete',
downloadCompleteTime: now.toISOString(),
});

setTimeout(function() { callback(image); }, 4000);


}
});

}, 4000);
}

10. Add the following function that updates the firmware update status through the reported properties to
applying. The function then simulates applying the firmware image and finally updates the firmware
update status to either applyFailed or applyComplete:
var applyImage = function(twin, imageData, callback) {
var now = new Date();

reportFWUpdateThroughTwin(twin, {
status: 'applying',
startedApplyingImage : now.toISOString()
});

setTimeout(function() {

// Simulate apply firmware image


simulateApplyImage(imageData, function(err) {
if (err) {
reportFWUpdateThroughTwin(twin, {
status: 'applyFailed',
error: {
code: err.error_code,
message: err.error_message,
}
});
} else {
reportFWUpdateThroughTwin(twin, {
status: 'applyComplete',
lastFirmwareUpdate: now.toISOString()
});

}
});

setTimeout(callback, 4000);

}, 4000);
}

11. Add the following function that handles the firmwareUpdate direct method and initiates the multi-stage
firmware update process:
var onFirmwareUpdate = function(request, response) {

// Respond the cloud app for the direct method


response.send(200, 'FirmwareUpdate started', function(err) {
if (!err) {
console.error('An error occured when sending a method response:\n' + err.toString());
} else {
console.log('Response to method \'' + request.methodName + '\' sent successfully.');
}
});

// Get the parameter from the body of the method request


var fwPackageUri = request.payload.fwPackageUri;

// Obtain the device twin


client.getTwin(function(err, twin) {
if (err) {
console.error('Could not get device twin.');
} else {
console.log('Device twin acquired.');

// Start the multi-stage firmware update


waitToDownload(twin, fwPackageUri, function() {
downloadImage(twin, fwPackageUri, function(imageData) {
applyImage(twin, imageData, function() {});
});
});

}
});
}

12. Finally, add the following code that connects to your IoT hub:

client.open(function(err) {
if (err) {
console.error('Could not connect to IotHub client');
} else {
console.log('Client connected to IoT Hub. Waiting for firmwareUpdate direct method.');
}

client.onDeviceMethod('firmwareUpdate', onFirmwareUpdate);
});

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Run the apps


You are now ready to run the apps.
1. At the command prompt in the manageddevice folder, run the following command to begin listening for
the reboot direct method.

node dmpatterns_fwupdate_device.js

2. In Visual Studio, right-click on the TriggerFWUpdate project, select Debug and Start new instance.
3. You see the device response to the direct method in the console.

Next steps
In this tutorial, you used a direct method to trigger a remote firmware update on a device and used the reported
properties to follow the progress of the firmware update.
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
Use device management to initiate a device
firmware update (.NET/.NET)
6/4/2018 • 12 min to read • Edit Online

Introduction
In the Get started with device management tutorial, you saw how to use the device twin and direct methods
primitives to remotely reboot a device. This tutorial uses the same IoT Hub primitives and shows you how to do
an end-to-end simulated firmware update. This pattern is used in the firmware update implementation for the
Raspberry Pi device implementation sample.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a .NET console app that calls the firmwareUpdate direct method in the simulated device app through
your IoT hub.
Create a simulated device app that implements a firmwareUpdate direct method. This method initiates a
multi-stage process that waits to download the firmware image, downloads the firmware image, and finally
applies the firmware image. During each stage of the update, the device uses the reported properties to
report on progress.
At the end of this tutorial, you have a .NET (C#) console device app and a .NET (C#) console back-end app:
SimulatedDeviceFwUpdate, which connects to your IoT hub with the device identity created earlier,
receives the firmwareUpdate direct method, runs through a multi-state process to simulate a firmware
update including: waiting for the image download, downloading the new image, and finally applying the
image.
TriggerFWUpdate, which uses the service SDK to remotely invoke the firmwareUpdate direct method
on the simulated device, displays the response, and periodically (every 500ms) displays the updated
reported properties.
To complete this tutorial, you need the following:
Visual Studio 2015 or Visual Studio 2017.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)
Follow the Get started with device management article to create your IoT hub and get your IoT Hub connection
string.

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A
device cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the
"Identity registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a
unique device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new
device identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use
later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and
keys to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device.
If your application needs to store other device-specific metadata, it should use an application-specific store. For more
information, see IoT Hub developer guide.

Trigger a remote firmware update on the device using a direct method


In this section, you create a .NET console app (using C#) that initiates a remote firmware update on a device. The
app uses a direct method to initiate the update and uses device twin queries to periodically get the status of the
active firmware update.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project TriggerFWUpdate.

2. In Solution Explorer, right-click the TriggerFWUpdate project, and then click Manage NuGet Packages.
3. In the NuGet Package Manager window, select Browse, search for microsoft.azure.devices, select
Install to install the Microsoft.Azure.Devices package, and accept the terms of use. This procedure
downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package and its
dependencies.
4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;

5. Add the following fields to the Program class. Replace the multiple placeholder values with the IoT Hub
connection string for the hub that you created in the previous section and the ID of your device.

static RegistryManager registryManager;


static string connString = "{iot hub connection string}";
static ServiceClient client;
static string targetDevice = "{deviceIdForTargetDevice}";

6. Add the following method to the Program class. This method polls the device twin for updated status
every 500 milliseconds. It writes to the console only when status has actually changed. For this sample, to
prevent consuming extra IoT Hub messages in your subscription, polling stops when the device reports a
status of applyComplete or an error.
public static async Task QueryTwinFWUpdateReported(DateTime startTime)
{
DateTime lastUpdated = startTime;

while (true)
{
Twin twin = await registryManager.GetTwinAsync(targetDevice);

if (twin.Properties.Reported.GetLastUpdated().ToUniversalTime() >
lastUpdated.ToUniversalTime())
{
lastUpdated = twin.Properties.Reported.GetLastUpdated().ToUniversalTime();
Console.WriteLine("\n" + twin.Properties.Reported["iothubDM"].ToJson());

var status = twin.Properties.Reported["iothubDM"]["firmwareUpdate"]["status"].Value;


if ((status == "downloadFailed") || (status == "applyFailed") || (status ==
"applyComplete"))
{
Console.WriteLine("\nStop polling.");
return;
}
}
await Task.Delay(500);
}
}

7. Add the following method to the Program class:

public static async Task StartFirmwareUpdate()


{
client = ServiceClient.CreateFromConnectionString(connString);
CloudToDeviceMethod method = new CloudToDeviceMethod("firmwareUpdate");
method.ResponseTimeout = TimeSpan.FromSeconds(30);
method.SetPayloadJson(
@"{
fwPackageUri : 'https://someurl'
}");

CloudToDeviceMethodResult result = await client.InvokeDeviceMethodAsync(targetDevice, method);

Console.WriteLine("Invoked firmware update on device.");


}

8. Finally, add the following lines to the Main method. This creates a registry manager to read the device
twin with, starts the polling task on a worker thread, and then triggers the firmware update.

registryManager = RegistryManager.CreateFromConnectionString(connString);

Task queryTask = Task.Run(() => (QueryTwinFWUpdateReported(DateTime.Now)));

StartFirmwareUpdate().Wait();
Console.WriteLine("Press ENTER to exit.");
Console.ReadLine();

9. Build the solution.

Create a simulated device app


In this section, you:
Create a .NET console app that responds to a direct method called by the cloud
Simulate a firmware update triggered by a backend service through a direct method
Use the reported properties to enable device twin queries to identify devices and when they last completed a
firmware update
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project SimulateDeviceFWUpdate.

2. In Solution Explorer, right-click the SimulateDeviceFWUpdate project, and then click Manage NuGet
Packages.
3. In the NuGet Package Manager window, select Browse and search for
microsoft.azure.devices.client. Select Install to install the Microsoft.Azure.Devices.Client package,
and accept the terms of use. This procedure downloads, installs, and adds a reference to the Azure IoT
device SDK NuGet package and its dependencies.

4. Add the following using statements at the top of the Program.cs file:

using Newtonsoft.Json.Linq;
using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;

5. Add the following fields to the Program class. Replace the placeholder value with the device connection
string that you noted in the Create a device identity section.
static string DeviceConnectionString = "HostName=<yourIotHubName>.azure-devices.net;DeviceId=
<yourIotDeviceName>;SharedAccessKey=<yourIotDeviceAccessKey>";
static DeviceClient Client = null;

6. Add the following method to report status back to the cloud through the device twin:

static async Task reportFwUpdateThroughTwin(Twin twin, TwinCollection fwUpdateValue)


{
try
{
TwinCollection patch = new TwinCollection();
TwinCollection iothubDM = new TwinCollection();

iothubDM["firmwareUpdate"] = fwUpdateValue;
patch["iothubDM"] = iothubDM;

await Client.UpdateReportedPropertiesAsync(patch);
Console.WriteLine("Twin state reported: {0}", fwUpdateValue["status"]);
}
catch
{
Console.WriteLine("Error updating device twin");
throw;
}
}

7. Add the following method to simulate downloading the firmware image:

static async Task<byte[]> simulateDownloadImage(string imageUrl)


{
var image = "[fake image data]";

Console.WriteLine("Downloading image from " + imageUrl);

await Task.Delay(4000);

return Encoding.ASCII.GetBytes(image);

8. Add the following method to simulate applying the firmware image to the device:

static async Task simulateApplyImage(byte[] imageData)


{
if (imageData == null)
{
throw new ArgumentNullException();
}

await Task.Delay(4000);

9. Add the following method to simulate waiting to download the firmware image. Update status to waiting
and clear other firmware update properties on the twin. These properties are cleared to remove any
existing values from prior firmware updates. This is necessary because reported properties are sent as a
PATCH operation (a delta) and not a PUT operation (a complete set of properties that replaces all of the
previous values). Typically, devices are informed of an available update and an administrator defined
policy causes the device to start downloading and applying the update. This function is where the logic to
enable that policy should run.

static async Task waitToDownload(Twin twin, string fwUpdateUri)


{
var now = DateTime.Now;
TwinCollection status = new TwinCollection();
status["fwPackageUri"] = fwUpdateUri;
status["status"] = "waiting";
status["error"] = null;
status["startedWaitingTime"] = DateTime.Now;
status["downloadCompleteTime"] = null;
status["startedApplyingImage"] = null;
status["lastFirmwareUpdate"] = null;

await reportFwUpdateThroughTwin(twin, status);

await Task.Delay(2000);
}

10. Add the following method to perform the download. It updates the status to downloading through the
device twin, calls the simulate download method, and reports a status of downloadComplete or
downloadFailed through the twin depending on the results of the download operation.

static async Task<byte[]> downloadImage(Twin twin, string fwUpdateUri)


{
try
{
TwinCollection statusUpdate = new TwinCollection();
statusUpdate["status"] = "downloading";
await reportFwUpdateThroughTwin(twin, statusUpdate);

byte[] imageData = await simulateDownloadImage(fwUpdateUri);

statusUpdate = new TwinCollection();


statusUpdate["status"] = "downloadComplete";
statusUpdate["downloadCompleteTime"] = DateTime.Now;
await reportFwUpdateThroughTwin(twin, statusUpdate);
return imageData;
}
catch (Exception ex)
{
TwinCollection statusUpdate = new TwinCollection();
statusUpdate["status"] = "downloadFailed";
statusUpdate["error"] = new TwinCollection();
statusUpdate["error"]["code"] = ex.GetType().ToString();
statusUpdate["error"]["message"] = ex.Message;
await reportFwUpdateThroughTwin(twin, statusUpdate);
throw;
}
}

11. Add the following method to apply the image. It updates the status to applying through the device twin,
calls the simulate apply image method, and updates status to applyComplete or applyFailed through
the twin depending on the results of the apply operation.
static async Task applyImage(Twin twin, byte[] imageData)
{
try
{
TwinCollection statusUpdate = new TwinCollection();
statusUpdate["status"] = "applying";
statusUpdate["startedApplyingImage"] = DateTime.Now;
await reportFwUpdateThroughTwin(twin, statusUpdate);

await simulateApplyImage(imageData);

statusUpdate = new TwinCollection();


statusUpdate["status"] = "applyComplete";
statusUpdate["lastFirmwareUpdate"] = DateTime.Now;
await reportFwUpdateThroughTwin(twin, statusUpdate);
}
catch (Exception ex)
{
TwinCollection statusUpdate = new TwinCollection();
statusUpdate["status"] = "applyFailed";
statusUpdate["error"] = new TwinCollection();
statusUpdate["error"]["code"] = ex.GetType().ToString();
statusUpdate["error"]["message"] = ex.Message;
await reportFwUpdateThroughTwin(twin, statusUpdate);
throw;
}
}

12. Add the following method to sequence the firmware update operation from waiting to download the
image through applying the image to the device:

static async Task doUpdate(string fwUpdateUrl)


{
try
{
Twin twin = await Client.GetTwinAsync();
await waitToDownload(twin, fwUpdateUrl);
byte[] imageData = await downloadImage(twin, fwUpdateUrl);
await applyImage(twin, imageData);
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error during update: {0}", ex.Message);
}
}

13. Add the following method to handle the updateFirmware direct method from the cloud. It extracts the
URL to the firmware update from the message payload and passes it to the doUpdate task, which it
starts on another threadpool thread. It then immediately returns the method response to the cloud.

static Task<MethodResponse> onFirmwareUpdate(MethodRequest methodRequest, object userContext)


{
string fwUpdateUrl = (string)JObject.Parse(methodRequest.DataAsJson)["fwPackageUri"];
Console.WriteLine("\nMethod: {0} triggered by service, URI is: {1}", methodRequest.Name,
fwUpdateUrl);

Task updateTask = Task.Run(() => (doUpdate(fwUpdateUrl)));

string result = "'FirmwareUpdate started.'";


return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200));
}
NOTE
This method triggers the simulated update to run as a Task and then immediately responds to the method call,
informing the service that the firmware update has been started. Update status and completion will be sent to the
service through the reported properties of the device twin. We respond to the method call when starting the
update, rather than after its completion, because:
A real update process is very likely to take longer than the method call timeout.
A real update process is very likely to require a reboot, which would re-launch this app making the
MethodRequest object unavailable. (Updating reported properties, however, is possible even after a reboot.)

14. Finally, add the following code to the Main method to open the connection to your IoT hub and initialize
the method listener:

try
{
Console.WriteLine("Connecting to hub");
Client = DeviceClient.CreateFromConnectionString(DeviceConnectionString, TransportType.Mqtt);

// setup callback for "firmware update" method


Client.SetMethodHandlerAsync("firmwareUpdate", onFirmwareUpdate, null).Wait();
Console.WriteLine("Waiting for firmware update direct method call\n Press enter to exit.");
Console.ReadLine();

Console.WriteLine("Exiting...");

// as a good practice, remove the firmware update handler


Client.SetMethodHandlerAsync("firmwareUpdate", null, null).Wait();
Client.CloseAsync().Wait();
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}

15. Build the solution.

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Run the apps


You are now ready to run the apps.
1. Run the .NET device app SimulatedDeviceFWUpdate. Right-click the SimulatedDeviceFWUpdate
project, select Debug, and then select Start new instance. It should start listening for method calls from
your IoT Hub:
2. Once the device is connected and waiting for method invocations, run the .NET TriggerFWUpdate app
to invoke the firmware update method in the simulated device app. Right-click the TriggerFWUpdate
project, select Debug, and then select Start new instance. You should see update sequence written in the
SimulatedDeviceFWUpdate console and also the sequence reported through the reported properties
of the device in the TriggerFWUpdate console. Note that the process takes several seconds to complete.
Next steps
In this tutorial, you used a direct method to trigger a remote firmware update on a device and used the reported
properties to follow the progress of the firmware update.
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
Use device management to initiate a device
firmware update (Java/Java)
5/29/2018 • 11 min to read • Edit Online

In the Get started with device management tutorial, you saw how to use the device twin and direct methods
primitives to remotely reboot a device. This tutorial uses the same IoT Hub primitives and shows you how to do
an end-to-end simulated firmware update. This pattern is used in the firmware update implementation for the
Raspberry Pi device implementation sample.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a Java console app that calls the firmwareUpdate direct method on the simulated device app
through your IoT hub.
Create a Java console app that simulates the device and implements the firmwareUpdate direct method.
This method initiates a multi-stage process that waits to download the firmware image, downloads the
firmware image, and finally applies the firmware image. During each stage of the update, the device uses the
reported properties to report on progress.
At the end of this tutorial, you have two Java console apps:
firmware-update, calls a direct method on the simulated device, displays the response, and periodically displays
reported property updates
simulated-device, connects to your IoT hub with the previously created device identity, receives the
firmwareUpdate direct method call, and runs through a firmware update simulation
To complete this tutorial, you need the following:
The latest Java SE Development Kit 8
Maven 3
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A
device cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the
"Identity registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a
unique device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new
device identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use
later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and
keys to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device.
If your application needs to store other device-specific metadata, it should use an application-specific store. For more
information, see IoT Hub developer guide.

Trigger a remote firmware update on the device using a direct method


In this section, you create a Java console app that initiates a remote firmware update on a device. The app uses a
direct method to initiate the update and uses device twin queries to periodically get the status of the active
firmware update.
1. Create an empty folder called fw -get-started.
2. In the fw -get-started folder, create a Maven project called firmware-update using the following
command at your command prompt. Note this is a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=firmware-update -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

3. At your command prompt, navigate to the firmware-update folder.


4. Using a text editor, open the pom.xml file in the firmware-update folder and add the following
dependency to the dependencies node. This dependency enables you to use the iot-service-client
package in your app to communicate with your IoT hub:

<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-service-client</artifactId>
<version>1.5.22</version>
<type>jar</type>
</dependency>

NOTE
You can check for the latest version of iot-service-client using Maven search.

5. Add the following build node after the dependencies node. This configuration instructs Maven to use
Java 1.8 to build the app:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

6. Save and close the pom.xml file.


7. Using a text editor, open the firmware-update\src\main\java\com\mycompany\app\App.java source file.
8. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceMethod;
import com.microsoft.azure.sdk.iot.service.devicetwin.MethodResult;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;
import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwin;
import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwinDevice;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

9. Add the following class-level variables to the App class. Replace {youriothubconnectionstring} with
your IoT hub connection string you noted in the Create an IoT Hub section:

public static final String iotHubConnectionString = "{youriothubconnectionstring}";


public static final String deviceId = "myDeviceId";

private static final String methodName = "firmwareUpdate";


private static final Long responseTimeout = TimeUnit.SECONDS.toSeconds(30);
private static final Long connectTimeout = TimeUnit.SECONDS.toSeconds(5);

10. To implement a method that reads the reported properties from the device twin, add the following to the
App class:
public static void ShowReportedProperties()
{
try
{
DeviceTwin deviceTwins = DeviceTwin.createFromConnectionString(iotHubConnectionString);
DeviceTwinDevice twinDevice = new DeviceTwinDevice(deviceId);

Boolean firmwareUpdated = false;


Integer timeoutCycle = 0;

while (!firmwareUpdated)
{
if (timeoutCycle > 5)
{
System.out.println("Operation timed out");
break;
}

Thread.sleep(1000);

deviceTwins.getTwin(twinDevice);

String reportedProperties = twinDevice.reportedPropertiesToString();

if(reportedProperties.contains("status=waiting"))
{
System.out.println("Waiting on device...");
}
else if(reportedProperties.contains("status=downloadComplete"))
{
System.out.println("Download complete, applying firmware...");
}
else if (reportedProperties.contains("status=applyComplete"))
{
System.out.println("Firmware applied");
System.out.println("Get reported properties from device twin");
System.out.println(twinDevice.reportedPropertiesToString());
firmwareUpdated = true;
}
else
{
timeoutCycle++;
}
}
} catch (Exception ex) {
System.out.println("Exception reading reported properties: " + ex.getMessage());
}
}

11. Modify the signature of the main method to throw the following exceptions:

public static void main( String[] args ) throws IOException

12. To invoke the firmwareUpdate direct method on the simulated device, add the following code to the main
method:
DeviceMethod methodClient = DeviceMethod.createFromConnectionString(iotHubConnectionString);

try
{
String payload = "https://someurl";

System.out.println("Invoked firmware update on device.");


System.out.println("Sent URL: " + payload);

MethodResult result = methodClient.invoke(deviceId, methodName, responseTimeout, connectTimeout,


payload);

if(result == null)
{
throw new IOException("Invoke direct method reboot returns null");
}

System.out.println("Status for device: " + result.getStatus());


System.out.println("Message from device: " + result.getPayload());
}
catch (IotHubException e)
{
System.out.println(e.getMessage());
}

13. To poll the reported properties from the simulated device, add the following code to the main method:

ShowReportedProperties();

14. To enable you to stop the app, add the following code to the main method:

System.out.println("Press ENTER to exit.");


System.in.read();
System.out.println("Shutting down sample...");

15. Save and close the firmware-update\src\main\java\com\mycompany\app\App.java file.


16. Build the firmware-update back-end app and correct any errors. At your command prompt, navigate to
the firmware-update folder and run the following command:
mvn clean package -DskipTests

Simulate a device to handle direct method calls


In this section, you create a Java console simulated device app that can receive the firmwareUpdate direct
method. The app then runs through a multi-state process to simulate the firmware update using
reportedProperties to communicate status.
1. In the fw -get-started folder, create a Maven project called simulated-device using the following
command at your command prompt. Note this is a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=simulated-device -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2. At your command prompt, navigate to the simulated-device folder.


3. Using a text editor, open the pom.xml file in the firmware-update folder and add the following
dependency to the dependencies node. This dependency enables you to use the iot-service-client
package in your app to communicate with your IoT hub:
<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-device-client</artifactId>
<version>1.3.32</version>
<type>jar</type>
</dependency>

NOTE
You can check for the latest version of iot-device-client using Maven search.

4. Add the following build node after the dependencies node. This configuration instructs Maven to use
Java 1.8 to build the app:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

5. Save and close the pom.xml file.


6. Using a text editor, open the simulated-device\src\main\java\com\mycompany\app\App.java source file.
7. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.device.*;
import com.microsoft.azure.sdk.iot.device.DeviceTwin.*;

import java.io.IOException;
import java.net.URISyntaxException;
import java.time.LocalDateTime;
import java.util.Scanner;
import java.util.Set;
import java.util.HashSet;
import java.util.HashMap;

8. Add the following class-level variables to the App class. Replace {yourdeviceconnectionstring} with
your device connection string you noted in the Create a Device Identity section:

private static final int METHOD_SUCCESS = 200;


private static final int METHOD_NOT_DEFINED = 404;

private static IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;


private static String connString = "{yourdeviceconnectionstring";
private static DeviceClient client;

private static String downloadURL = "unknown";

9. To implement direct method functionality, provide callbacks by adding the following nested classes to the
App class:

protected static class DirectMethodStatusCallback implements IotHubEventCallback


{
public void execute(IotHubStatusCode status, Object context)
{
System.out.println("IoT Hub responded to device method operation with status " + status.name());
}
}
protected static class DirectMethodCallback implements
com.microsoft.azure.sdk.iot.device.DeviceTwin.DeviceMethodCallback
{
@Override
public DeviceMethodData call(String methodName, Object methodData, Object context)
{
DeviceMethodData deviceMethodData;
switch (methodName)
{
case "firmwareUpdate" :
{
System.out.println("Response to method '" + methodName + "' sent successfully");

downloadURL = new String((byte[])methodData);

int status = METHOD_SUCCESS;


System.out.println("Starting firmware update");
deviceMethodData = new DeviceMethodData(status, "Started firmware update");
FirmwareUpdateThread firmwareUpdateThread = new FirmwareUpdateThread();
Thread t = new Thread(firmwareUpdateThread);
t.start();
break;
}
default:
{
int status = METHOD_NOT_DEFINED;
deviceMethodData = new DeviceMethodData(status, "Not defined direct method " + methodName);
}
}
return deviceMethodData;
}
}

10. To implement device twin functionality, provide callbacks by adding the following nested classes to the
App class:

protected static class DeviceTwinStatusCallback implements IotHubEventCallback


{
public void execute(IotHubStatusCode status, Object context)
{
System.out.println("IoT Hub responded to device twin operation with status " + status.name());
}
}
protected static class PropertyCallback implements PropertyCallBack<String, String>
{
public void PropertyCall(String propertyKey, String propertyValue, Object context)
{
System.out.println("PropertyKey: " + propertyKey);
System.out.println("PropertyKvalue: " + propertyKey);
}
}

11. To implement the firmware update, add the following nested class to the App class:
protected static class FirmwareUpdateThread implements Runnable {
public void run() {
try {
HashMap initialUpdate = new HashMap();
Property sentProperty = new Property("firmwareUpdate", initialUpdate);
Set<Property> sentPackage = new HashSet<Property>();

System.out.println("Downloading from " + downloadURL);

initialUpdate.put("status", "waiting");
initialUpdate.put("fwPackageUri", downloadURL);
initialUpdate.put("startedWaitingTime", LocalDateTime.now().toString());
sentPackage.add(sentProperty);

client.sendReportedProperties(sentPackage);

Thread.sleep(5000);

System.out.println("Download complete");

HashMap downloadUpdate = new HashMap();


downloadUpdate.put("status","downloadComplete");
downloadUpdate.put("downloadCompleteTime", LocalDateTime.now().toString());
downloadUpdate.put("startedApplyingImage", LocalDateTime.now().toString());
sentProperty.setValue(downloadUpdate);

client.sendReportedProperties(sentPackage);

Thread.sleep(5000);

System.out.println("Apply complete");

HashMap applyUpdate = new HashMap();


applyUpdate.put("status","applyComplete");
applyUpdate.put("lastFirmwareUpdate", LocalDateTime.now().toString());
sentProperty.setValue(applyUpdate);

client.sendReportedProperties(sentPackage);

Thread.sleep(5000);

HashMap resetUpdate = new HashMap();


applyUpdate.put("status","reset");
sentProperty.setValue(resetUpdate);

client.sendReportedProperties(sentPackage);
}
catch (Exception ex) {
System.out.println("Exception in reboot thread: " + ex.getMessage());
}
}
}

12. Modify the signature of the main method to throw the following exceptions:

public static void main(String[] args) throws IOException, URISyntaxException

13. To initiate the direct methods and device twins routine, add the following code to the main method:
client = new DeviceClient(connString, protocol);

try
{
client.open();
client.subscribeToDeviceMethod(new DirectMethodCallback(), null, new DirectMethodStatusCallback(),
null);
client.startDeviceTwin(new DeviceTwinStatusCallback(), null, new PropertyCallback(), null);
System.out.println("Client connected to IoT Hub. Waiting for firmwareUpdate direct method.");
}
catch (Exception e)
{
System.out.println("On exception, shutting down \n" + " Cause: " + e.getCause() + " \n" +
e.getMessage());
client.close();
System.out.println("Shutting down...");
}

14. To enable you to stop the app, add the following code to the end of the main method:

System.out.println("Press any key to exit...");


Scanner scanner = new Scanner(System.in);
scanner.nextLine();
scanner.close();
client.close();
System.out.println("Shutting down...");

15. Save and close the simulated-device\src\main\java\com\mycompany\app\App.java file.


16. Build the simulated-device app and correct any errors. At your command prompt, navigate to the
simulated-device folder and run the following command:
mvn clean package -DskipTests

Run the apps


You are now ready to run the apps.
1. At a command prompt in the simulated-device folder, run the following command to begin listening for
the firmware update direct method.
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

2. At a command prompt in the firmware-update folder, run the following command to invoke the
firmware update and query the device twins on your simulated device from your IoT hub:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

3. You can see the simulated device responding to the direct method in the console.
Next steps
In this tutorial, you used a direct method to trigger a remote firmware update on a device and used the reported
properties to follow the progress of the firmware update.
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
Use device management to initiate a device
firmware update (Python/Python)
5/29/2018 • 9 min to read • Edit Online

In the Get started with device management tutorial, you saw how to use the device twin and direct methods
primitives to remotely reboot a device. This tutorial uses the same IoT Hub primitives and provides guidance and
shows you how to do an end-to-end simulated firmware update. This pattern is used in the firmware update
implementation for the Intel Edison device sample.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a Python console app that calls the firmwareUpdate direct method in the simulated device app
through your IoT hub.
Create a simulated device app that implements a firmwareUpdate direct method. This method initiates a
multi-stage process that waits to download the firmware image, downloads the firmware image, and finally
applies the firmware image. During each stage of the update, the device uses the reported properties to
report on progress.
At the end of this tutorial, you have two Python console apps:
dmpatterns_fwupdate_service.py, which calls a direct method in the simulated device app, displays the
response, and periodically (every 500ms) displays the updated reported properties.
dmpatterns_fwupdate_device.py, which connects to your IoT hub with the device identity created earlier,
receives a firmwareUpdate direct method, runs through a multi-state process to simulate a firmware update
including: waiting for the image download, downloading the new image, and finally applying the image.
To complete this tutorial, you need the following:
Python 2.x or 3.x. Make sure to use the 32-bit or 64-bit installation as required by your setup. When
prompted during the installation, make sure to add Python to your platform-specific environment variable. If
you are using Python 2.x, you may need to install or upgrade pip, the Python package management system.
If you are using Windows OS, then Visual C++ redistributable package to allow the use of native DLLs from
Python.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A
device cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the
"Identity registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a
unique device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new
device identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use
later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and
keys to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device.
If your application needs to store other device-specific metadata, it should use an application-specific store. For more
information, see IoT Hub developer guide.

Trigger a remote firmware update on the device using a direct method


In this section, you create a Python console app that initiates a remote firmware update on a device. The app
uses a direct method to initiate the update and uses device twin queries to periodically get the status of the active
firmware update.
1. At your command prompt, run the following command to install the azure-iothub-service-client
package:

pip install azure-iothub-service-client

2. Using a text editor, in your working directory, create a dmpatterns_getstarted_service.py file.


3. Add the following 'import' statements and variables at the start of the
dmpatterns_getstarted_service.py file. Replace IoTHubConnectionString and deviceId with your values
noted previously:

import sys
import time

import iothub_service_client
from iothub_service_client import IoTHubDeviceTwin, IoTHubDeviceMethod, IoTHubError

CONNECTION_STRING = "{IoTHubConnectionString}"
DEVICE_ID = "{deviceId}"

METHOD_NAME = "firmwareUpdate"
METHOD_PAYLOAD = "{\"fwPackageUri\":\"test.com\"}"
TIMEOUT = 60
MESSAGE_COUNT = 5

4. Add the following function to call the direct method and display the value of the firmwareUpdate
reported property. Also add the main routine:
def iothub_firmware_sample_run():
try:
iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)

print ( "" )
print ( "Direct Method called." )
iothub_device_method = IoTHubDeviceMethod(CONNECTION_STRING)

response = iothub_device_method.invoke(DEVICE_ID, METHOD_NAME, METHOD_PAYLOAD, TIMEOUT)


print ( response.payload )

print ( "" )
print ( "Device Twin queried, press Ctrl-C to exit" )
while True:
twin_info = iothub_twin_method.get_twin(DEVICE_ID)

if "\"firmwareStatus\":\"standBy\"" in twin_info:
print ( "Waiting on device..." )
elif "\"firmwareStatus\":\"downloading\"" in twin_info:
print ( "Downloading firmware..." )
elif "\"firmwareStatus\":\"applying\"" in twin_info:
print ( "Download complete, applying firmware..." )
elif "\"firmwareStatus\":\"completed\"" in twin_info:
print ( "Firmware applied" )
print ( "" )
print ( "Get reported properties from device twin:" )
print ( twin_info )
break
else:
print ( "Unknown status" )

status_counter = 0
while status_counter <= MESSAGE_COUNT:
time.sleep(1)
status_counter += 1

except IoTHubError as iothub_error:


print ( "" )
print ( "Unexpected error {0}" % iothub_error )
return
except KeyboardInterrupt:
print ( "" )
print ( "IoTHubService sample stopped" )

if __name__ == '__main__':
print ( "Starting the IoT Hub firmware update Python sample..." )
print ( " Connection string = {0}".format(CONNECTION_STRING) )
print ( " Device ID = {0}".format(DEVICE_ID) )

iothub_firmware_sample_run()

5. Save and close the dmpatterns_fwupdate_service.py file.

Create a simulated device app


In this section, you:
Create a Python console app that responds to a direct method called by the cloud
Trigger a simulated firmware update
Use the reported properties to enable device twin queries to identify devices and when they last completed a
firmware update
1. At your command prompt, run the following command to install the azure-iothub-device-client
package:
pip install azure-iothub-device-client

2. Using a text editor, create a dmpatterns_fwupdate_device.py file.


3. Add the following 'import' statements and variables at the start of the
dmpatterns_fwupdate_device.py file. Replace deviceConnectionString with the device connection
string from your IoT hub:

import time, datetime


import sys
import threading

import iothub_client
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult
from iothub_client import IoTHubError, DeviceMethodReturnValue

SEND_REPORTED_STATE_CONTEXT = 0
METHOD_CONTEXT = 0

MESSAGE_COUNT = 10

PROTOCOL = IoTHubTransportProvider.MQTT
CONNECTION_STRING = "{deviceConnectionString}"
CLIENT = IoTHubClient(CONNECTION_STRING, PROTOCOL)

4. Add the following functions that are used to provide reported properties updates and implement the
direct method:

def send_reported_state_callback(status_code, user_context):


print ( "Reported state updated." )

def device_method_callback(method_name, payload, user_context):


if method_name == "firmwareUpdate":
print ( "Starting firmware update." )
image_url = payload
thr = threading.Thread(target=simulate_download_image, args=([payload]), kwargs={})
thr.start()

device_method_return_value = DeviceMethodReturnValue()
device_method_return_value.response = "{ \"Response\": \"Firmware update started\" }"
device_method_return_value.status = 200
return device_method_return_value

5. Add the following functions that simulate downloading and applying the firmware image:
def simulate_download_image(image_url):
time.sleep(15)
print ( "Downloading image from: " + image_url )

reported_state = "{\"firmwareStatus\":\"downloading\", \"downloadComplete\":\"" +


str(datetime.datetime.now()) + "\"}"
CLIENT.send_reported_state(reported_state, len(reported_state), send_reported_state_callback,
SEND_REPORTED_STATE_CONTEXT)
time.sleep(15)

simulate_apply_image(image_url)

def simulate_apply_image(image_url):
print ( "Applying image from: " + image_url )

reported_state = "{\"firmwareStatus\":\"applying\", \"startedApplyingImage\":\"" +


str(datetime.datetime.now()) + "\"}"
CLIENT.send_reported_state(reported_state, len(reported_state), send_reported_state_callback,
SEND_REPORTED_STATE_CONTEXT)
time.sleep(15)

simulate_complete_image()

def simulate_complete_image():
print ( "Image applied." )

reported_state = "{\"firmwareStatus\":\"completed\", \"lastFirmwareUpdate\":\"" +


str(datetime.datetime.now()) + "\"}"
CLIENT.send_reported_state(reported_state, len(reported_state), send_reported_state_callback,
SEND_REPORTED_STATE_CONTEXT)

6. Add the following function that initializes the device twin's reported properties and wait for the direct
method to be called. Also add the main routine:

def iothub_firmware_sample_run():
try:
CLIENT.set_device_method_callback(device_method_callback, METHOD_CONTEXT)

reported_state = "{\"firmwareStatus\":\"standBy\", \"logTime\":\"" +


str(datetime.datetime.now()) + "\"}"
CLIENT.send_reported_state(reported_state, len(reported_state), send_reported_state_callback,
SEND_REPORTED_STATE_CONTEXT)
print ( "Device twins initialized." )
print ( "IoTHubClient waiting for commands, press Ctrl-C to exit" )

while True:
status_counter = 0
while status_counter <= MESSAGE_COUNT:
time.sleep(10)
status_counter += 1

except IoTHubError as iothub_error:


print ( "Unexpected error %s from IoTHub" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubClient sample stopped" )

if __name__ == '__main__':
print ( "Starting the IoT Hub Python firmware update sample..." )
print ( " Protocol %s" % PROTOCOL )
print ( " Connection string=%s" % CONNECTION_STRING )

iothub_firmware_sample_run()
NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Run the apps


You are now ready to run the apps.
1. At the command prompt, run the following command to begin listening for the reboot direct method.

python dmpatterns_fwupdate_device.py

2. At another command prompt, run the following command to trigger the remote reboot and query for the
device twin to find the last reboot time.

python dmpatterns_fwupdate_service.py

3. You see the device response to the direct method in the console. Then note the change in reported
properties throughout the firmware update.

Next steps
In this tutorial, you used a direct method to trigger a remote firmware update on a device and used the reported
properties to follow the progress of the firmware update.
To learn how to extend your IoT solution and schedule method calls on multiple devices, see the Schedule and
broadcast jobs tutorial.
Schedule and broadcast jobs (Node)
5/29/2018 • 8 min to read • Edit Online

Azure IoT Hub is a fully managed service that enables a back-end app to create and track jobs that schedule
and update millions of devices. Jobs can be used for the following actions:
Update desired properties
Update tags
Invoke direct methods
Conceptually, a job wraps one of these actions and tracks the progress of execution against a set of devices,
which is defined by a device twin query. For example, a back-end app can use a job to invoke a reboot method
on 10,000 devices, specified by a device twin query and scheduled at a future time. That application can then
track progress as each of those devices receive and execute the reboot method.
Learn more about each of these capabilities in these articles:
Device twin and properties: Get started with device twins and Tutorial: How to use device twin properties
Direct methods: IoT Hub developer guide - direct methods and Tutorial: direct methods

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the
basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a Node.js simulated device app that has a direct method, which enables lockDoor, which can be
called by the solution back end.
Create a Node.js console app that calls the lockDoor direct method in the simulated device app using a
job and updates the desired properties using a device job.
At the end of this tutorial, you have two Node.js apps:
simDevice.js, which connects to your IoT hub with the device identity and receives a lockDoor direct
method.
scheduleJobService.js, which calls a direct method in the simulated device app and updates the device
twin's desired properties using a job.
To complete this tutorial, you need the following:
Node.js version 4.0.x or later,
Prepare your development environment describes how to install Node.js for this tutorial on either
Windows or Linux.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to
complete this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information
while naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on
your subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create.
You can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now
that you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device
IDs are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with
the IoT Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to
avoid any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the
device app to connect to your IoT Hub as a device.
Refer to Getting started with IoT Hub to programmatically create device identities.

Create a simulated device app


In this section, you create a Node.js console app that responds to a direct method called by the cloud, which
triggers a simulated lockDoor method.
1. Create a new empty folder called simDevice. In the simDevice folder, create a package.json file using
the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the simDevice folder, run the following command to install the azure-
iot-device Device SDK package and azure-iot-device-mqtt package:

npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a new simDevice.js file in the simDevice folder.
4. Add the following 'require' statements at the start of the simDevice.js file:

'use strict';

var Client = require('azure-iot-device').Client;


var Protocol = require('azure-iot-device-mqtt').Mqtt;

5. Add a connectionString variable and use it to create a Client instance.

var connectionString = 'HostName={youriothostname};DeviceId={yourdeviceid};SharedAccessKey=


{yourdevicekey}';
var client = Client.fromConnectionString(connectionString, Protocol);

6. Add the following function to handle the lockDoor method.


var onLockDoor = function(request, response) {

// Respond the cloud app for the direct method


response.send(200, function(err) {
if (!err) {
console.error('An error occured when sending a method response:\n' + err.toString());
} else {
console.log('Response to method \'' + request.methodName + '\' sent successfully.');
}
});

console.log('Locking Door!');
};

7. Add the following code to register the handler for the lockDoor method.

client.open(function(err) {
if (err) {
console.error('Could not connect to IotHub client.');
} else {
console.log('Client connected to IoT Hub. Register handler for lockDoor direct method.');
client.onDeviceMethod('lockDoor', onLockDoor);
}
});

8. Save and close the simDevice.js file.

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement
retry policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Schedule jobs for calling a direct method and updating a device


twin's properties
In this section, you create a Node.js console app that initiates a remote lockDoor on a device using a direct
method and update the device twin's properties.
1. Create a new empty folder called scheduleJobService. In the scheduleJobService folder, create a
package.json file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the scheduleJobService folder, run the following command to install
the azure-iothub Device SDK package and azure-iot-device-mqtt package:

npm install azure-iothub uuid --save

3. Using a text editor, create a new scheduleJobService.js file in the scheduleJobService folder.
4. Add the following 'require' statements at the start of the
dmpatterns_gscheduleJobServiceetstarted_service.js file:
'use strict';

var uuid = require('uuid');


var JobClient = require('azure-iothub').JobClient;

5. Add the following variable declarations and replace the placeholder values:

var connectionString = '{iothubconnectionstring}';


var queryCondition = "deviceId IN ['myDeviceId']";
var startTime = new Date();
var maxExecutionTimeInSeconds = 300;
var jobClient = JobClient.fromConnectionString(connectionString);

6. Add the following function that is used to monitor the execution of the job:

function monitorJob (jobId, callback) {


var jobMonitorInterval = setInterval(function() {
jobClient.getJob(jobId, function(err, result) {
if (err) {
console.error('Could not get job status: ' + err.message);
} else {
console.log('Job: ' + jobId + ' - status: ' + result.status);
if (result.status === 'completed' || result.status === 'failed' || result.status ===
'cancelled') {
clearInterval(jobMonitorInterval);
callback(null, result);
}
}
});
}, 5000);
}

7. Add the following code to schedule the job that calls the device method:

var methodParams = {
methodName: 'lockDoor',
payload: null,
responseTimeoutInSeconds: 15 // Timeout after 15 seconds if device is unable to process method
};

var methodJobId = uuid.v4();


console.log('scheduling Device Method job with id: ' + methodJobId);
jobClient.scheduleDeviceMethod(methodJobId,
queryCondition,
methodParams,
startTime,
maxExecutionTimeInSeconds,
function(err) {
if (err) {
console.error('Could not schedule device method job: ' + err.message);
} else {
monitorJob(methodJobId, function(err, result) {
if (err) {
console.error('Could not monitor device method job: ' + err.message);
} else {
console.log(JSON.stringify(result, null, 2));
}
});
}
});
8. Add the following code to schedule the job to update the device twin:

var twinPatch = {
etag: '*',
properties: {
desired: {
building: '43',
floor: 3
}
}
};

var twinJobId = uuid.v4();

console.log('scheduling Twin Update job with id: ' + twinJobId);


jobClient.scheduleTwinUpdate(twinJobId,
queryCondition,
twinPatch,
startTime,
maxExecutionTimeInSeconds,
function(err) {
if (err) {
console.error('Could not schedule twin update job: ' + err.message);
} else {
monitorJob(twinJobId, function(err, result) {
if (err) {
console.error('Could not monitor twin update job: ' + err.message);
} else {
console.log(JSON.stringify(result, null, 2));
}
});
}
});

9. Save and close the scheduleJobService.js file.

Run the applications


You are now ready to run the applications.
1. At the command prompt in the simDevice folder, run the following command to begin listening for
the reboot direct method.

node simDevice.js

2. At the command prompt in the scheduleJobService folder, run the following command to trigger the
jobs to lock the door and update the twin

node scheduleJobService.js

3. You see the device response to the direct method in the console.

Next steps
In this tutorial, you used a job to schedule a direct method to a device and the update of the device twin's
properties.
To continue getting started with IoT Hub and device management patterns such as remote over the air
firmware update, see:
Tutorial: How to do a firmware update
To continue getting started with IoT Hub, see Getting started with Azure IoT Edge.
Schedule and broadcast jobs (.NET/Node.js)
5/29/2018 • 8 min to read • Edit Online

Use Azure IoT Hub to schedule and track jobs that update millions of devices. Use jobs to:
Update desired properties
Update tags
Invoke direct methods
A job wraps one of these actions and tracks the execution against a set of devices that is defined by a device twin
query. For example, a back-end app can use a job to invoke a direct method on 10,000 devices that reboots the
devices. You specify the set of devices with a device twin query and schedule the job to run at a future time. The
job tracks progress as each of the devices receive and execute the reboot direct method.
To learn more about each of these capabilities, see:
Device twin and properties: Get started with device twins and Tutorial: How to use device twin properties
Direct methods: IoT Hub developer guide - direct methods and Tutorial: Use direct methods

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a device app that implements a direct method called lockDoor that can be called by the back-end app.
The device app also receives desired property changes from the back-end app.
Create a back-end app that creates a job to call the lockDoor direct method on multiple devices. Another job
sends desired property updates to multiple devices.
At the end of this tutorial, you have a Node.js console device app and a .NET (C#) console back-end app:
simDevice.js that connects to your IoT hub, implements the lockDoor direct method, and handles desired
property changes.
ScheduleJob that uses jobs to call the lockDoor direct method and update the device twin desired properties on
multiple devices.
To complete this tutorial, you need the following:
Visual Studio 2015 or Visual Studio 2017.
Node.js version 4.0.x or later. The article Prepare your development environment describes how to install
Node.js for this tutorial on either Windows or Linux.
An active Azure account. If you don't have an account, you can create a free account in just a couple of minutes.

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use a Node.js tool called iothub-explorer to create a device identity for this tutorial. Device IDs
are case sensitive.
1. Run the following in your command-line environment:
npm install -g iothub-explorer@latest

2. Then, run the following command to login to your hub. Substitute {iot hub connection string} with the
IoT Hub connection string you previously copied:
iothub-explorer login "{iot hub connection string}"

3. Finally, create a new device identity called myDeviceId with the command:
iothub-explorer create myDeviceId --connection-string

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

Make a note of the device connection string from the result. This device connection string is used by the device
app to connect to your IoT Hub as a device.
Refer to Getting started with IoT Hub to programmatically create device identities.

Schedule jobs for calling a direct method and sending device twin
updates
In this section, you create a .NET console app (using C#) that uses jobs to call the lockDoor direct method and
send desired property updates to multiple devices.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project ScheduleJob.

2. In Solution Explorer, right-click the ScheduleJob project, and then click Manage NuGet Packages....
3. In the NuGet Package Manager window, select Browse, search for microsoft.azure.devices, select
Install to install the Microsoft.Azure.Devices package, and accept the terms of use. This step downloads,
installs, and adds a reference to the Azure IoT service SDK NuGet package and its dependencies.
4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;

5. Add the following using statement if not already present in the default statements.

using System.Threading;
using System.Threading.Tasks;

6. Add the following fields to the Program class. Replace the placeholder with the IoT Hub connection string
for the hub that you created in the previous section.

static string connString = "{iot hub connection string}";


static ServiceClient client;
static JobClient jobClient;

7. Add the following method to the Program class:

public static async Task MonitorJob(string jobId)


{
JobResponse result;
do
{
result = await jobClient.GetJobAsync(jobId);
Console.WriteLine("Job Status : " + result.Status.ToString());
Thread.Sleep(2000);
} while ((result.Status != JobStatus.Completed) && (result.Status != JobStatus.Failed));
}

8. Add the following method to the Program class:


public static async Task StartMethodJob(string jobId)
{
CloudToDeviceMethod directMethod = new CloudToDeviceMethod("lockDoor", TimeSpan.FromSeconds(5),
TimeSpan.FromSeconds(5));

JobResponse result = await jobClient.ScheduleDeviceMethodAsync(jobId,


"deviceId='myDeviceId'",
directMethod,
DateTime.Now,
(long)TimeSpan.FromMinutes(2).TotalSeconds);

Console.WriteLine("Started Method Job");


}

9. Add the following method to the Program class:

public static async Task StartTwinUpdateJob(string jobId)


{
var twin = new Twin();
twin.Properties.Desired["Building"] = "43";
twin.Properties.Desired["Floor"] = "3";
twin.ETag = "*";

JobResponse result = await jobClient.ScheduleTwinUpdateAsync(jobId,


"deviceId='myDeviceId'",
twin,
DateTime.Now,
(long)TimeSpan.FromMinutes(2).TotalSeconds);

Console.WriteLine("Started Twin Update Job");


}

10. Finally, add the following lines to the Main method:

jobClient = JobClient.CreateFromConnectionString(connString);

string methodJobId = Guid.NewGuid().ToString();

StartMethodJob(methodJobId);
MonitorJob(methodJobId).Wait();
Console.WriteLine("Press ENTER to run the next job.");
Console.ReadLine();

string twinUpdateJobId = Guid.NewGuid().ToString();

StartTwinUpdateJob(twinUpdateJobId);
MonitorJob(twinUpdateJobId).Wait();
Console.WriteLine("Press ENTER to exit.");
Console.ReadLine();

11. In the Solution Explorer, open the Set StartUp projects... and make sure the Action for ScheduleJob
project is Start. Build the solution.

Create a simulated device app


In this section, you create a Node.js console app that responds to a direct method called by the cloud, which
triggers a simulated device reboot and uses the reported properties to enable device twin queries to identify
devices and when they last rebooted.
1. Create a new empty folder called simDevice. In the simDevice folder, create a package.json file using the
following command at your command prompt. Accept all the defaults:
npm init

2. At your command prompt in the simDevice folder, run the following command to install the azure-iot-
device and azure-iot-device-mqtt packages:

npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a new simDevice.js file in the simDevice folder.
4. Add the following 'require' statements at the start of the simDevice.js file:

'use strict';

var Client = require('azure-iot-device').Client;


var Protocol = require('azure-iot-device-mqtt').Mqtt;

5. Add a connectionString variable and use it to create a Client instance. Make sure to replace the
placeholders with values appropriate to your setup.

var connectionString = 'HostName={youriothostname};DeviceId={yourdeviceid};SharedAccessKey=


{yourdevicekey}';
var client = Client.fromConnectionString(connectionString, Protocol);

6. Add the following function to handle the lockDoor method.

var onLockDoor = function(request, response) {

// Respond the cloud app for the direct method


response.send(200, function(err) {
if (!err) {
console.error('An error occured when sending a method response:\n' + err.toString());
} else {
console.log('Response to method \'' + request.methodName + '\' sent successfully.');
}
});

console.log('Locking Door!');
};

7. Add the following code to register the handler for the lockDoor method.

client.open(function(err) {
if (err) {
console.error('Could not connect to IotHub client.');
} else {
console.log('Client connected to IoT Hub. Waiting for lockDoor direct method.');
client.onDeviceMethod('lockDoor', onLockDoor);
}
});

8. Save and close the simDevice.js file.


NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Run the apps


You are now ready to run the apps.
1. At the command prompt in the simDevice folder, run the following command to begin listening for the
reboot direct method.

node simDevice.js

2. Run the C# console app ScheduleJob by right-clicking on the ScheduleJob project, then selecting
Debug and Start new instance.
3. You see the output from both device and back-end apps.

Next steps
In this tutorial, you used a job to schedule a direct method to a device and the update of the device twin's
properties.
To continue getting started with IoT Hub and device management patterns such as remote over the air firmware
update, read Tutorial: How to do a firmware update.
To learn about deploying AI to edge devices with Azure IoT Edge, see Getting started with IoT Edge.
Schedule and broadcast jobs (.NET/.NET)
5/29/2018 • 8 min to read • Edit Online

Use Azure IoT Hub to schedule and track jobs that update millions of devices. Use jobs to:
Update desired properties
Update tags
Invoke direct methods
A job wraps one of these actions and tracks the execution against a set of devices that is defined by a device twin
query. For example, a back-end app can use a job to invoke a direct method on 10,000 devices that reboots the
devices. You specify the set of devices with a device twin query and schedule the job to run at a future time. The
job tracks progress as each of the devices receive and execute the reboot direct method.
To learn more about each of these capabilities, see:
Device twin and properties: Get started with device twins and Tutorial: How to use device twin properties
Direct methods: IoT Hub developer guide - direct methods and Tutorial: Use direct methods

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a device app that implements a direct method called LockDoor that can be called by the back-end app.
Create a back-end app that creates a job to call the LockDoor direct method on multiple devices. Another job
sends desired property updates to multiple devices.
At the end of this tutorial, you have two .NET (C#) console apps:
SimulateDeviceMethods that connects to your IoT hub and implements the LockDoor direct method.
ScheduleJob that uses jobs to call the LockDoor direct method and update the device twin desired properties on
multiple devices.
To complete this tutorial, you need the following:
Visual Studio 2015 or Visual Studio 2017.
An active Azure account. If you don't have an account, you can create a free account in just a couple of minutes.

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A device
cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the "Identity
registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a unique
device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new device
identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use
later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and
keys to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device. If
your application needs to store other device-specific metadata, it should use an application-specific store. For more
information, see IoT Hub developer guide.

Create a simulated device app


In this section, you create a .NET console app that responds to a direct method called by the solution back end.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project SimulateDeviceMethods.

2. In Solution Explorer, right-click the SimulateDeviceMethods project, and then click Manage NuGet
Packages....
3. In the NuGet Package Manager window, select Browse and search for microsoft.azure.devices.client.
Select Install to install the Microsoft.Azure.Devices.Client package, and accept the terms of use. This
procedure downloads, installs, and adds a reference to the Azure IoT device SDK NuGet package and its
dependencies.

4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;

using Newtonsoft.Json;

5. Add the following fields to the Program class. Replace the placeholder value with the device connection
string that you noted in the previous section:

static string DeviceConnectionString = "<yourDeviceConnectionString>";


static DeviceClient Client = null;

6. Add the following to implement the direct method on the device:

static Task<MethodResponse> LockDoor(MethodRequest methodRequest, object userContext)


{
Console.WriteLine();
Console.WriteLine("Locking Door!");
Console.WriteLine("\nReturning response for method {0}", methodRequest.Name);

string result = "'Door was locked.'";


return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200));
}

7. Add the following to implement the device twins listener on the device:

private static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object


userContext)
{
Console.WriteLine("Desired property change:");
Console.WriteLine(JsonConvert.SerializeObject(desiredProperties));
}

8. Finally, add the following code to the Main method to open the connection to your IoT hub and initialize
the method listener:
try
{
Console.WriteLine("Connecting to hub");
Client = DeviceClient.CreateFromConnectionString(DeviceConnectionString, TransportType.Mqtt);

Client.SetMethodHandlerAsync("LockDoor", LockDoor, null);


Client.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChanged, null);

Console.WriteLine("Waiting for direct method call and device twin update\n Press enter to exit.");
Console.ReadLine();

Console.WriteLine("Exiting...");

Client.SetMethodHandlerAsync("LockDoor", null, null);


Client.CloseAsync().Wait();
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}

9. Save your work and build your solution.

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as connection retry), as suggested in the MSDN article Transient Fault Handling.

Schedule jobs for calling a direct method and sending device twin
updates
In this section, you create a .NET console app (using C#) that uses jobs to call the LockDoor direct method and
send desired property updates to multiple devices.
1. In Visual Studio, add a Visual C# Windows Classic Desktop project to the current solution by using the
Console Application project template. Name the project ScheduleJob.
2. In Solution Explorer, right-click the ScheduleJob project, and then click Manage NuGet Packages....
3. In the NuGet Package Manager window, select Browse, search for microsoft.azure.devices, select
Install to install the Microsoft.Azure.Devices package, and accept the terms of use. This step downloads,
installs, and adds a reference to the Azure IoT service SDK NuGet package and its dependencies.

4. Add the following using statements at the top of the Program.cs file:

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;

5. Add the following using statement if not already present in the default statements.

using System.Threading;
using System.Threading.Tasks;
6. Add the following fields to the Program class. Replace the placeholders with the IoT Hub connection string
for the hub that you created in the previous section and the name of your device.

static string connString = "<yourIotHubConnectionString>";


static string deviceId = "<yourDeviceId>";

7. Add the following method to the Program class:

public static async Task MonitorJob(string jobId)


{
JobResponse result;
do
{
result = await jobClient.GetJobAsync(jobId);
Console.WriteLine("Job Status : " + result.Status.ToString());
Thread.Sleep(2000);
} while ((result.Status != JobStatus.Completed) && (result.Status != JobStatus.Failed));
}

8. Add the following method to the Program class:

public static async Task StartMethodJob(string jobId)


{
CloudToDeviceMethod directMethod = new CloudToDeviceMethod("LockDoor", TimeSpan.FromSeconds(5),
TimeSpan.FromSeconds(5));

JobResponse result = await jobClient.ScheduleDeviceMethodAsync(jobId,


$"DeviceId IN ['{deviceId}']",
directMethod,
DateTime.UtcNow,
(long)TimeSpan.FromMinutes(2).TotalSeconds);

Console.WriteLine("Started Method Job");


}

9. Add another method to the Program class:

public static async Task StartTwinUpdateJob(string jobId)


{
Twin twin = new Twin(deviceId);
twin.Tags = new TwinCollection();
twin.Tags["Building"] = "43";
twin.Tags["Floor"] = "3";
twin.ETag = "*";

twin.Properties.Desired["LocationUpdate"] = DateTime.UtcNow;

JobResponse createJobResponse = jobClient.ScheduleTwinUpdateAsync(


jobId,
$"DeviceId IN ['{deviceId}']",
twin,
DateTime.UtcNow,
(long)TimeSpan.FromMinutes(2).TotalSeconds).Result;

Console.WriteLine("Started Twin Update Job");


}
NOTE
For more information about query syntax, see IoT Hub query language.

10. Finally, add the following lines to the Main method:

Console.WriteLine("Press ENTER to start running jobs.");


Console.ReadLine();

jobClient = JobClient.CreateFromConnectionString(connString);

string methodJobId = Guid.NewGuid().ToString();

StartMethodJob(methodJobId);
MonitorJob(methodJobId).Wait();
Console.WriteLine("Press ENTER to run the next job.");
Console.ReadLine();

string twinUpdateJobId = Guid.NewGuid().ToString();

StartTwinUpdateJob(twinUpdateJobId);
MonitorJob(twinUpdateJobId).Wait();
Console.WriteLine("Press ENTER to exit.");
Console.ReadLine();

11. Save your work and build your solution.

Run the apps


You are now ready to run the apps.
1. In the Visual Studio Solution Explorer, right-click your solution, and then click Build. Multiple startup
projects. Make sure SimulateDeviceMethods is at the top of the list followed by ScheduleJob . Set both their
actions to Start and click OK.
2. Run the projects by clicking Start or go to the Debug menu and click Start Debugging.
3. You see the output from both device and back-end apps.
Next steps
In this tutorial, you used a job to schedule a direct method to a device and the update of the device twin's
properties.
To continue getting started with IoT Hub and device management patterns such as remote over the air firmware
update, read Tutorial: How to do a firmware update.
To learn about deploying AI to edge devices with Azure IoT Edge, see Getting started with IoT Edge.
Schedule and broadcast jobs (Java)
5/29/2018 • 13 min to read • Edit Online

Use Azure IoT Hub to schedule and track jobs that update millions of devices. Use jobs to:
Update desired properties
Update tags
Invoke direct methods
A job wraps one of these actions and tracks the execution against a set of devices. A device twin query defines the
set of devices the job executes against. For example, a back-end app can use a job to invoke a direct method on
10,000 devices that reboots the devices. You specify the set of devices with a device twin query and schedule the
job to run at a future time. The job tracks progress as each of the devices receive and execute the reboot direct
method.
To learn more about each of these capabilities, see:
Device twin and properties: Get started with device twins
Direct methods: IoT Hub developer guide - direct methods and Tutorial: Use direct methods

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a device app that implements a direct method called lockDoor. The device app also receives desired
property changes from the back-end app.
Create a back-end app that creates a job to call the lockDoor direct method on multiple devices. Another job
sends desired property updates to multiple devices.
At the end of this tutorial, you have a java console device app and a java console back-end app:
simulated-device that connects to your IoT hub, implements the lockDoor direct method, and handles desired
property changes.
schedule-jobs that use jobs to call the lockDoor direct method and update the device twin desired properties on
multiple devices.

NOTE
The article Azure IoT SDKs provides information about the Azure IoT SDKs that you can use to build both device and back-
end apps.

Prerequisites
To complete this tutorial, you need:
The latest Java SE Development Kit 8
Maven 3
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A device
cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the "Identity
registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a unique
device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new device
identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use
later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and
keys to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device. If
your application needs to store other device-specific metadata, it should use an application-specific store. For more
information, see IoT Hub developer guide.

You can also use the IoT extension for Azure CLI 2.0 tool to add a device to your IoT hub.

Create the service app


In this section, you create a Java console app that uses jobs to:
Call the lockDoor direct method on multiple devices.
Send desired properties to multiple devices.
To create the app:
1. On your development machine, create an empty folder called iot-java-schedule-jobs .
2. In the iot-java-schedule-jobs folder, create a Maven project called schedule-jobs using the following
command at your command prompt. Note this is a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=schedule-jobs -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

3. At your command prompt, navigate to the schedule-jobs folder.


4. Using a text editor, open the pom.xml file in the schedule-jobs folder and add the following dependency to
the dependencies node. This dependency enables you to use the iot-service-client package in your app
to communicate with your IoT hub:

<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-service-client</artifactId>
<version>1.7.23</version>
<type>jar</type>
</dependency>

NOTE
You can check for the latest version of iot-service-client using Maven search.
5. Add the following build node after the dependencies node. This configuration instructs Maven to use
Java 1.8 to build the app:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

6. Save and close the pom.xml file.


7. Using a text editor, open the schedule-jobs\src\main\java\com\mycompany\app\App.java file.
8. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwinDevice;
import com.microsoft.azure.sdk.iot.service.devicetwin.Pair;
import com.microsoft.azure.sdk.iot.service.devicetwin.Query;
import com.microsoft.azure.sdk.iot.service.devicetwin.SqlQuery;
import com.microsoft.azure.sdk.iot.service.jobs.JobClient;
import com.microsoft.azure.sdk.iot.service.jobs.JobResult;
import com.microsoft.azure.sdk.iot.service.jobs.JobStatus;

import java.util.Date;
import java.time.Instant;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

9. Add the following class-level variables to the App class. Replace {youriothubconnectionstring} with your
IoT hub connection string you noted in the Create an IoT Hub section:

public static final String iotHubConnectionString = "{youriothubconnectionstring}";


public static final String deviceId = "myDeviceId";

// How long the job is permitted to run without


// completing its work on the set of devices
private static final long maxExecutionTimeInSeconds = 30;

10. Add the following method to the App class to schedule a job to update the Building and Floor desired
properties in the device twin:
private static JobResult scheduleJobSetDesiredProperties(JobClient jobClient, String jobId) {
DeviceTwinDevice twin = new DeviceTwinDevice(deviceId);
Set<Pair> desiredProperties = new HashSet<Pair>();
desiredProperties.add(new Pair("Building", 43));
desiredProperties.add(new Pair("Floor", 3));
twin.setDesiredProperties(desiredProperties);
// Optimistic concurrency control
twin.setETag("*");

// Schedule the update twin job to run now


// against a single device
System.out.println("Schedule job " + jobId + " for device " + deviceId);
try {
JobResult jobResult = jobClient.scheduleUpdateTwin(jobId,
"deviceId='" + deviceId + "'",
twin,
new Date(),
maxExecutionTimeInSeconds);
return jobResult;
} catch (Exception e) {
System.out.println("Exception scheduling desired properties job: " + jobId);
System.out.println(e.getMessage());
return null;
}
}

11. To schedule a job to call the lockDoor method, add the following method to the App class:

private static JobResult scheduleJobCallDirectMethod(JobClient jobClient, String jobId) {


// Schedule a job now to call the lockDoor direct method
// against a single device. Response and connection
// timeouts are set to 5 seconds.
System.out.println("Schedule job " + jobId + " for device " + deviceId);
try {
JobResult jobResult = jobClient.scheduleDeviceMethod(jobId,
"deviceId='" + deviceId + "'",
"lockDoor",
5L, 5L, null,
new Date(),
maxExecutionTimeInSeconds);
return jobResult;
} catch (Exception e) {
System.out.println("Exception scheduling direct method job: " + jobId);
System.out.println(e.getMessage());
return null;
}
};

12. To monitor a job, add the following method to the App class:
private static void monitorJob(JobClient jobClient, String jobId) {
try {
JobResult jobResult = jobClient.getJob(jobId);
if(jobResult == null)
{
System.out.println("No JobResult for: " + jobId);
return;
}
// Check the job result until it's completed
while(jobResult.getJobStatus() != JobStatus.completed)
{
Thread.sleep(100);
jobResult = jobClient.getJob(jobId);
System.out.println("Status " + jobResult.getJobStatus() + " for job " + jobId);
}
System.out.println("Final status " + jobResult.getJobStatus() + " for job " + jobId);
} catch (Exception e) {
System.out.println("Exception monitoring job: " + jobId);
System.out.println(e.getMessage());
return;
}
}

13. To query for the details of the jobs you ran, add the following method:

private static void queryDeviceJobs(JobClient jobClient, String start) throws Exception {


System.out.println("\nQuery device jobs since " + start);

// Create a jobs query using the time the jobs started


Query deviceJobQuery = jobClient
.queryDeviceJob(SqlQuery.createSqlQuery("*", SqlQuery.FromType.JOBS, "devices.jobs.startTimeUtc >
'" + start + "'", null).getQuery());

// Iterate over the list of jobs and print the details


while (jobClient.hasNextJob(deviceJobQuery)) {
System.out.println(jobClient.getNextJob(deviceJobQuery));
}
}

14. Update the main method signature to include the following throws clause:

public static void main( String[] args ) throws Exception

15. To run and monitor two jobs sequentially, add the following code to the main method:
// Record the start time
String start = Instant.now().toString();

// Create JobClient
JobClient jobClient = JobClient.createFromConnectionString(iotHubConnectionString);
System.out.println("JobClient created with success");

// Schedule twin job desired properties


// Maximum concurrent jobs is 1 for Free and S1 tiers
String desiredPropertiesJobId = "DPCMD" + UUID.randomUUID();
scheduleJobSetDesiredProperties(jobClient, desiredPropertiesJobId);
monitorJob(jobClient, desiredPropertiesJobId);

// Schedule twin job direct method


String directMethodJobId = "DMCMD" + UUID.randomUUID();
scheduleJobCallDirectMethod(jobClient, directMethodJobId);
monitorJob(jobClient, directMethodJobId);

// Run a query to show the job detail


queryDeviceJobs(jobClient, start);

System.out.println("Shutting down schedule-jobs app");

16. Save and close the schedule-jobs\src\main\java\com\mycompany\app\App.java file


17. Build the schedule-jobs app and correct any errors. At your command prompt, navigate to the
schedule-jobs folder and run the following command:

mvn clean package -DskipTests

Create a device app


In this section, you create a Java console app that handles the desired properties sent from IoT Hub and
implements the direct method call.
1. In the iot-java-schedule-jobs folder, create a Maven project called simulated-device using the following
command at your command prompt. Note this is a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=simulated-device -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2. At your command prompt, navigate to the simulated-device folder.


3. Using a text editor, open the pom.xml file in the simulated-device folder and add the following
dependencies to the dependencies node. This dependency enables you to use the iot-device-client
package in your app to communicate with your IoT hub:

<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-device-client</artifactId>
<version>1.3.32</version>
</dependency>

NOTE
You can check for the latest version of iot-device-client using Maven search.

4. Add the following build node after the dependencies node. This configuration instructs Maven to use
Java 1.8 to build the app:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

5. Save and close the pom.xml file.


6. Using a text editor, open the simulated-device\src\main\java\com\mycompany\app\App.java file.
7. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.device.*;
import com.microsoft.azure.sdk.iot.device.DeviceTwin.*;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Scanner;

8. Add the following class-level variables to the App class. Replacing {youriothubname} with your IoT hub
name, and {yourdevicekey} with the device key value you generated in the Create a device identity section:

private static String connString = "HostName={youriothubname}.azure-


devices.net;DeviceId=myDeviceID;SharedAccessKey={yourdevicekey}";
private static IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
private static final int METHOD_SUCCESS = 200;
private static final int METHOD_NOT_DEFINED = 404;

This sample app uses the protocol variable when it instantiates a DeviceClient object.
9. To print device twin notifications to the console, add the following nested class to the App class:

// Handler for device twin operation notifications from IoT Hub


protected static class DeviceTwinStatusCallBack implements IotHubEventCallback {
public void execute(IotHubStatusCode status, Object context) {
System.out.println("IoT Hub responded to device twin operation with status " + status.name());
}
}

10. To print direct method notifications to the console, add the following nested class to the App class:

// Handler for direct method notifications from IoT Hub


protected static class DirectMethodStatusCallback implements IotHubEventCallback {
public void execute(IotHubStatusCode status, Object context) {
System.out.println("IoT Hub responded to direct method operation with status " + status.name());
}
}

11. To handle direct method calls from IoT Hub, add the following nested class to the App class:
// Handler for direct method calls from IoT Hub
protected static class DirectMethodCallback
implements DeviceMethodCallback {
@Override
public DeviceMethodData call(String methodName, Object methodData, Object context) {
DeviceMethodData deviceMethodData;
switch (methodName) {
case "lockDoor": {
System.out.println("Executing direct method: " + methodName);
deviceMethodData = new DeviceMethodData(METHOD_SUCCESS, "Executed direct method " +
methodName);
break;
}
default: {
deviceMethodData = new DeviceMethodData(METHOD_NOT_DEFINED, "Not defined direct method " +
methodName);
}
}
// Notify IoT Hub of result
return deviceMethodData;
}
}

12. Update the main method signature to include the following throws clause:

public static void main( String[] args ) throws IOException, URISyntaxException

13. Add the following code to the main method to:


Create a device client to communicate with IoT Hub.
Create a Device object to store the device twin properties.

// Create a device client


DeviceClient client = new DeviceClient(connString, protocol);

// An object to manage device twin desired and reported properties


Device dataCollector = new Device() {
@Override
public void PropertyCall(String propertyKey, Object propertyValue, Object context)
{
System.out.println("Received desired property change: " + propertyKey + " " + propertyValue);
}
};

14. To start the device client services, add the following code to the main method:
try {
// Open the DeviceClient
// Start the device twin services
// Subscribe to direct method calls
client.open();
client.startDeviceTwin(new DeviceTwinStatusCallBack(), null, dataCollector, null);
client.subscribeToDeviceMethod(new DirectMethodCallback(), null, new DirectMethodStatusCallback(),
null);
} catch (Exception e) {
System.out.println("Exception, shutting down \n" + " Cause: " + e.getCause() + " \n" +
e.getMessage());
dataCollector.clean();
client.closeNow();
System.out.println("Shutting down...");
}

15. To wait for the user to press the Enter key before shutting down, add the following code to the end of the
main method:

// Close the app


System.out.println("Press any key to exit...");
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
dataCollector.clean();
client.closeNow();
scanner.close();

16. Save and close the simulated-device\src\main\java\com\mycompany\app\App.java file.


17. Build the simulated-device app and correct any errors. At your command prompt, navigate to the
simulated-device folder and run the following command:

mvn clean package -DskipTests

Run the apps


You are now ready to run the console apps.
1. At a command prompt in the simulated-device folder, run the following command to start the device app
listening for desired property changes and direct method calls:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
2. At a command prompt in the schedule-jobs folder, run the following command to run the schedule-jobs
service app to run two jobs. The first sets the desired property values, the second calls the direct method:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

3. The device app handles the desired property change and the direct method call:
Next steps
In this tutorial, you configured a new IoT hub in the Azure portal, and then created a device identity in the IoT
hub's identity registry. You created a back-end app to run two jobs. The first job set desired property values, and
the second job called a direct method.
Use the following resources to learn how to:
Send telemetry from devices with the Get started with IoT Hub tutorial.
Control devices interactively (such as turning on a fan from a user-controlled app) with the Use direct methods
tutorial.
Schedule and broadcast jobs (Python)
5/29/2018 • 9 min to read • Edit Online

Azure IoT Hub is a fully managed service that enables a back-end app to create and track jobs that schedule and
update millions of devices. Jobs can be used for the following actions:
Update desired properties
Update tags
Invoke direct methods
Conceptually, a job wraps one of these actions and tracks the progress of execution against a set of devices, which
is defined by a device twin query. For example, a back-end app can use a job to invoke a reboot method on 10,000
devices, specified by a device twin query and scheduled at a future time. That application can then track progress
as each of those devices receive and execute the reboot method.
Learn more about each of these capabilities in these articles:
Device twin and properties: Get started with device twins and Tutorial: How to use device twin properties
Direct methods: IoT Hub developer guide - direct methods and Tutorial: direct methods

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

This tutorial shows you how to:


Create a Python simulated device app that has a direct method, which enables lockDoor, which can be called
by the solution back end.
Create a Python console app that calls the lockDoor direct method in the simulated device app using a job and
updates the desired properties using a device job.
At the end of this tutorial, you have two Python apps:
simDevice.py, which connects to your IoT hub with the device identity and receives a lockDoor direct method.
scheduleJobService.py, which calls a direct method in the simulated device app and updates the device twin's
desired properties using a job.
To complete this tutorial, you need the following:
Python 2.x or 3.x. Make sure to use the 32-bit or 64-bit installation as required by your setup. When prompted
during the installation, make sure to add Python to your platform-specific environment variable. If you are
using Python 2.x, you may need to install or upgrade pip, the Python package management system.
If you are using Windows OS, then Visual C++ redistributable package to allow the use of native DLLs from
Python.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)
NOTE
The Azure IoT SDK for Python does not directly support Jobs functionality. Instead this tutorial offers an alternate solution
utilizing asynchronous threads and timers. For further updates, see the Service Client SDK feature list on the Azure IoT
SDK for Python page.

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete this
task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A device
cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the "Identity
registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a unique
device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new device
identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use
later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and
keys to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device. If
your application needs to store other device-specific metadata, it should use an application-specific store. For more
information, see IoT Hub developer guide.

Create a simulated device app


In this section, you create a Python console app that responds to a direct method called by the cloud, which
triggers a simulated lockDoor method.
1. At your command prompt, run the following command to install the azure-iot-device-client package:

pip install azure-iothub-device-client

2. Using a text editor, create a new simDevice.py file in your working directory.
3. Add the following import statements and variables at the start of the simDevice.py file. Replace
deviceConnectionString with the connection string of the device you created above:

import time
import sys

import iothub_client
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult
from iothub_client import IoTHubError, DeviceMethodReturnValue

METHOD_CONTEXT = 0
TWIN_CONTEXT = 0
WAIT_COUNT = 10

PROTOCOL = IoTHubTransportProvider.MQTT
CONNECTION_STRING = "{deviceConnectionString}"

4. Add the following function callback to handle the lockDoor method:


def device_method_callback(method_name, payload, user_context):
if method_name == "lockDoor":
print ( "Locking Door!" )

device_method_return_value = DeviceMethodReturnValue()
device_method_return_value.response = "{ \"Response\": \"lockDoor called successfully\" }"
device_method_return_value.status = 200
return device_method_return_value

5. Add another function callback to handle device twins updates:

def device_twin_callback(update_state, payload, user_context):


print ( "")
print ( "Twin callback called with:")
print ( "payload: %s" % payload )

6. Add the following code to register the handler for the lockDoor method. Also include the main routine:

def iothub_jobs_sample_run():
try:
client = IoTHubClient(CONNECTION_STRING, PROTOCOL)
client.set_device_method_callback(device_method_callback, METHOD_CONTEXT)
client.set_device_twin_callback(device_twin_callback, TWIN_CONTEXT)

print ( "Direct method initialized." )


print ( "Device twin callback initialized." )
print ( "IoTHubClient waiting for commands, press Ctrl-C to exit" )

while True:
status_counter = 0
while status_counter <= WAIT_COUNT:
time.sleep(10)
status_counter += 1

except IoTHubError as iothub_error:


print ( "Unexpected error %s from IoTHub" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubClient sample stopped" )

if __name__ == '__main__':
print ( "Starting the IoT Hub Python jobs sample..." )
print ( " Protocol %s" % PROTOCOL )
print ( " Connection string=%s" % CONNECTION_STRING )

iothub_jobs_sample_run()

7. Save and close the simDevice.py file.

NOTE
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as an exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Schedule jobs for calling a direct method and updating a device twin's
properties
In this section, you create a Python console app that initiates a remote lockDoor on a device using a direct
method and update the device twin's properties.
1. At your command prompt, run the following command to install the azure-iot-service-client package:

pip install azure-iothub-service-client

2. Using a text editor, create a new scheduleJobService.py file in your working directory.
3. Add the following import statements and variables at the start of the scheduleJobService.py file:

import sys
import time
import threading
import uuid

import iothub_service_client
from iothub_service_client import IoTHubRegistryManager, IoTHubRegistryManagerAuthMethod
from iothub_service_client import IoTHubDeviceTwin, IoTHubDeviceMethod, IoTHubError

CONNECTION_STRING = "{IoTHubConnectionString}"
DEVICE_ID = "{deviceId}"

METHOD_NAME = "lockDoor"
METHOD_PAYLOAD = "{\"lockTime\":\"10m\"}"
UPDATE_JSON = "{\"properties\":{\"desired\":{\"building\":43,\"floor\":3}}}"
TIMEOUT = 60
WAIT_COUNT = 5

4. Add the following function that is used to query for devices:

def query_condition(device_id):
iothub_registry_manager = IoTHubRegistryManager(CONNECTION_STRING)

number_of_devices = 10
dev_list = iothub_registry_manager.get_device_list(number_of_devices)

for device in range(0, number_of_devices):


if dev_list[device].deviceId == device_id:
return 1

print ( "Device not found" )


return 0

5. Add the following methods to run the jobs that call the direct method and device twin:
def device_method_job(job_id, device_id, wait_time, execution_time):
print ( "" )
print ( "Scheduling job: " + str(job_id) )
time.sleep(wait_time)

if query_condition(device_id):
iothub_device_method = IoTHubDeviceMethod(CONNECTION_STRING)

response = iothub_device_method.invoke(device_id, METHOD_NAME, METHOD_PAYLOAD, TIMEOUT)

print ( "" )
print ( "Direct method " + METHOD_NAME + " called." )

def device_twin_job(job_id, device_id, wait_time, execution_time):


print ( "" )
print ( "Scheduling job " + str(job_id) )
time.sleep(wait_time)

if query_condition(device_id):
iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)

twin_info = iothub_twin_method.update_twin(DEVICE_ID, UPDATE_JSON)

print ( "" )
print ( "Device twin updated." )

6. Add the following code to schedule the jobs and update job status. Also include the main routine:
def iothub_jobs_sample_run():
try:
method_thr_id = uuid.uuid4()
method_thr = threading.Thread(target=device_method_job, args=(method_thr_id, DEVICE_ID, 20,
TIMEOUT), kwargs={})
method_thr.start()

print ( "" )
print ( "Direct method called with Job Id: " + str(method_thr_id) )

twin_thr_id = uuid.uuid4()
twin_thr = threading.Thread(target=device_twin_job, args=(twin_thr_id, DEVICE_ID, 10, TIMEOUT),
kwargs={})
twin_thr.start()

print ( "" )
print ( "Device twin called with Job Id: " + str(twin_thr_id) )

while True:
print ( "" )

if method_thr.is_alive():
print ( "...job " + str(method_thr_id) + " still running." )
else:
print ( "...job " + str(method_thr_id) + " complete." )

if twin_thr.is_alive():
print ( "...job " + str(twin_thr_id) + " still running." )
else:
print ( "...job " + str(twin_thr_id) + " complete." )

print ( "Job status posted, press Ctrl-C to exit" )

status_counter = 0
while status_counter <= WAIT_COUNT:
time.sleep(1)
status_counter += 1

except IoTHubError as iothub_error:


print ( "" )
print ( "Unexpected error {0}" % iothub_error )
return
except KeyboardInterrupt:
print ( "" )
print ( "IoTHubService sample stopped" )

if __name__ == '__main__':
print ( "Starting the IoT Hub jobs Python sample..." )
print ( " Connection string = {0}".format(CONNECTION_STRING) )
print ( " Device ID = {0}".format(DEVICE_ID) )

iothub_jobs_sample_run()

7. Save and close the scheduleJobService.py file.

Run the applications


You are now ready to run the applications.
1. At the command prompt in your working directory, run the following command to begin listening for the
reboot direct method:

python simDevice.py
2. At another command prompt in your working directory, run the following command to trigger the jobs to
lock the door and update the twin:

python scheduleJobService.py

3. You see the device responses to the direct method and device twins update in the console.

Next steps
In this tutorial, you used a job to schedule a direct method to a device and the update of the device twin's
properties.
To continue getting started with IoT Hub and device management patterns such as remote over the air firmware
update, see:
Tutorial: How to do a firmware update
To continue getting started with IoT Hub, see Getting started with Azure IoT Edge.
Upload files from your device to the cloud with IoT
Hub using .NET
6/6/2018 • 5 min to read • Edit Online

This tutorial builds on the code in the Send Cloud-to-Device messages with IoT Hub tutorial to show you how to
use the file upload capabilities of IoT Hub. It shows you how to:
Securely provide a device with an Azure blob URI for uploading a file.
Use the IoT Hub file upload notifications to trigger processing the file in your app back end.
The Get started with IoT Hub and Send Cloud-to-Device messages with IoT Hub tutorials show the basic device-
to-cloud and cloud-to-device messaging functionality of IoT Hub. The Process Device-to-Cloud messages
tutorial describes a way to reliably store device-to-cloud messages in Azure blob storage. However, in some
scenarios you cannot easily map the data your devices send into the relatively small device-to-cloud messages
that IoT Hub accepts. For example:
Large files that contain images
Videos
Vibration data sampled at high frequency
Some form of preprocessed data
These files are typically batch processed in the cloud using tools such as Azure Data Factory or the Hadoop stack.
When you need to upload files from a device, you can still use the security and reliability of IoT Hub.
At the end of this tutorial you run two .NET console apps:
SimulatedDevice, a modified version of the app created in the Send Cloud-to-Device messages with IoT
Hub tutorial. This app uploads a file to storage using a SAS URI provided by your IoT hub.
ReadFileUploadNotification, which receives file upload notifications from your IoT hub.

NOTE
IoT Hub supports many device platforms and languages (including C, Java, and Javascript) through Azure IoT device SDKs.
Refer to the Azure IoT Developer Center for step-by-step instructions on how to connect your device to Azure IoT Hub.

To complete this tutorial, you need the following:


Visual Studio 2015 or Visual Studio 2017
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Associate an Azure Storage account to IoT Hub


Because the simulated device app uploads a file to a blob, you must have an Azure Storage account associated to
IoT Hub. When you associate an Azure Storage account with an IoT hub, the IoT hub generates a SAS URI. A
device can use this SAS URI to securely upload a file to a blob container. The IoT Hub service and the device
SDKs coordinate the process that generates the SAS URI and makes it available to a device to use to upload a
file.
Follow the instructions in Configure file uploads using the Azure portal to associate an Azure Storage account to
your IoT hub. Make sure that a blob container is associated with your IoT hub and that file notifications are
enabled.

Upload a file from a device app


In this section, you modify the device app you created in Send Cloud-to-Device messages with IoT Hub to
receive cloud-to-device messages from the IoT hub.
1. In Visual Studio, right-click the SimulatedDevice project, click Add, and then click Existing Item.
Navigate to an image file and include it in your project. This tutorial assumes the image is named
image.jpg .

2. Right-click on the image, and then click Properties. Make sure that Copy to Output Directory is set to
Copy always.

3. In the Program.cs file, add the following statements at the top of the file:

using System.IO;

4. Add the following method to the Program class:


private static async void SendToBlobAsync()
{
string fileName = "image.jpg";
Console.WriteLine("Uploading file: {0}", fileName);
var watch = System.Diagnostics.Stopwatch.StartNew();

using (var sourceData = new FileStream(@"image.jpg", FileMode.Open))


{
await deviceClient.UploadToBlobAsync(fileName, sourceData);
}

watch.Stop();
Console.WriteLine("Time to upload file: {0}ms\n", watch.ElapsedMilliseconds);
}

The UploadToBlobAsync method takes in the file name and stream source of the file to be uploaded and
handles the upload to storage. The console app displays the time it takes to upload the file.
5. Add the following method in the Main method, right before the Console.ReadLine() line:

SendToBlobAsync();

NOTE
For simplicity's sake, this tutorial does not implement any retry policy. In production code, you should implement retry
policies (such as exponential backoff ), as suggested in the MSDN article Transient Fault Handling.

Receive a file upload notification


In this section, you write a .NET console app that receives file upload notification messages from IoT Hub.
1. In the current Visual Studio solution, create a Visual C# Windows project by using the Console
Application project template. Name the project ReadFileUploadNotification.
2. In Solution Explorer, right-click the ReadFileUploadNotification project, and then click Manage NuGet
Packages....
3. In the NuGet Package Manager window, search for Microsoft.Azure.Devices, click Install, and accept
the terms of use.
This action downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package in the
ReadFileUploadNotification project.
4. In the Program.cs file, add the following statements at the top of the file:

using Microsoft.Azure.Devices;

5. Add the following fields to the Program class. Substitute the placeholder value with the IoT hub
connection string from [Get started with IoT Hub]:

static ServiceClient serviceClient;


static string connectionString = "{iot hub connection string}";

6. Add the following method to the Program class:

private async static void ReceiveFileUploadNotificationAsync()


{
var notificationReceiver = serviceClient.GetFileNotificationReceiver();

Console.WriteLine("\nReceiving file upload notification from service");


while (true)
{
var fileUploadNotification = await notificationReceiver.ReceiveAsync();
if (fileUploadNotification == null) continue;

Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Received file upload noticiation: {0}", string.Join(", ",
fileUploadNotification.BlobName));
Console.ResetColor();

await notificationReceiver.CompleteAsync(fileUploadNotification);
}
}

Note this receive pattern is the same one used to receive cloud-to-device messages from the device app.
7. Finally, add the following lines to the Main method:

Console.WriteLine("Receive file upload notifications\n");


serviceClient = ServiceClient.CreateFromConnectionString(connectionString);
ReceiveFileUploadNotificationAsync();
Console.WriteLine("Press Enter to exit\n");
Console.ReadLine();

Run the applications


Now you are ready to run the applications.
1. In Visual Studio, right-click your solution, and select Set StartUp projects. Select Multiple startup
projects, then select the Start action for ReadFileUploadNotification and SimulatedDevice.
2. Press F5. Both applications should start. You should see the upload completed in one console app and the
upload notification message received by the other console app. You can use the Azure portal or Visual
Studio Server Explorer to check for the presence of the uploaded file in your Azure Storage account.

Next steps
In this tutorial, you learned how to use the file upload capabilities of IoT Hub to simplify file uploads from
devices. You can continue to explore IoT hub features and scenarios with the following articles:
Create an IoT hub programmatically
Introduction to C SDK
Azure IoT SDKs
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Upload files from your device to the cloud with IoT
Hub
6/6/2018 • 6 min to read • Edit Online

This tutorial builds on the code in the Send Cloud-to-Device messages with IoT Hub tutorial to show you how to
use the file upload capabilities of IoT Hub to upload a file to Azure blob storage. The tutorial shows you how to:
Securely provide a device with an Azure blob URI for uploading a file.
Use the IoT Hub file upload notifications to trigger processing the file in your app back end.
The Get started with IoT Hub and Send Cloud-to-Device messages with IoT Hub tutorials show the basic device-
to-cloud and cloud-to-device messaging functionality of IoT Hub. The Process Device-to-Cloud messages tutorial
describes a way to reliably store device-to-cloud messages in Azure blob storage. However, in some scenarios
you cannot easily map the data your devices send into the relatively small device-to-cloud messages that IoT Hub
accepts. For example:
Large files that contain images
Videos
Vibration data sampled at high frequency
Some form of preprocessed data.
These files are typically batch processed in the cloud using tools such as Azure Data Factory or the Hadoop stack.
When you need to upland files from a device, you can still use the security and reliability of IoT Hub.
At the end of this tutorial you run two Java console apps:
simulated-device, a modified version of the app created in the [Send Cloud-to-Device messages with IoT
Hub] tutorial. This app uploads a file to storage using a SAS URI provided by your IoT hub.
read-file-upload-notification, which receives file upload notifications from your IoT hub.

NOTE
IoT Hub supports many device platforms and languages (including C, .NET, and Javascript) through Azure IoT device SDKs.
Refer to the Azure IoT Developer Center for step-by-step instructions on how to connect your device to Azure IoT Hub.

To complete this tutorial, you need the following:


The latest Java SE Development Kit 8
Maven 3
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Associate an Azure Storage account to IoT Hub


Because the simulated device app uploads a file to a blob, you must have an Azure Storage account associated to
IoT Hub. When you associate an Azure Storage account with an IoT hub, the IoT hub generates a SAS URI. A
device can use this SAS URI to securely upload a file to a blob container. The IoT Hub service and the device
SDKs coordinate the process that generates the SAS URI and makes it available to a device to use to upload a
file.
Follow the instructions in Configure file uploads using the Azure portal to associate an Azure Storage account to
your IoT hub. Make sure that a blob container is associated with your IoT hub and that file notifications are
enabled.

Upload a file from a device app


In this section, you modify the device app you created in Send Cloud-to-Device messages with IoT Hub to upload
a file to IoT hub.
1. Copy an image file to the simulated-device folder and rename it myimage.png .
2. Using a text editor, open the simulated-device\src\main\java\com\mycompany\app\App.java file.
3. Add the variable declaration to the App class:

private static String fileName = "myimage.png";

4. To process file upload status callback messages, add the following nested class to the App class:

// Define a callback method to print status codes from IoT Hub.


protected static class FileUploadStatusCallBack implements IotHubEventCallback {
public void execute(IotHubStatusCode status, Object context) {
System.out.println("IoT Hub responded to file upload for " + fileName
+ " operation with status " + status.name());
}
}

5. To upload images to IoT Hub, add the following method to the App class to upload images to IoT Hub:
// Use IoT Hub to upload a file asynchronously to Azure blob storage.
private static void uploadFile(String fullFileName) throws FileNotFoundException, IOException
{
File file = new File(fullFileName);
InputStream inputStream = new FileInputStream(file);
long streamLength = file.length();

client.uploadToBlobAsync(fileName, inputStream, streamLength, new FileUploadStatusCallBack(), null);


}

6. Modify the main method to call the uploadFile method as shown in the following snippet:

client.open();

try
{
// Get the filename and start the upload.
String fullFileName = System.getProperty("user.dir") + File.separator + fileName;
uploadFile(fullFileName);
System.out.println("File upload started with success");
}
catch (Exception e)
{
System.out.println("Exception uploading file: " + e.getCause() + " \nERROR: " + e.getMessage());
}

MessageSender sender = new MessageSender();

7. Use the following command to build the simulated-device app and check for errors:

mvn clean package -DskipTests

Receive a file upload notification


In this section, you create a Java console app that receives file upload notification messages from IoT Hub.
You need the iothubowner connection string for your IoT Hub to complete this section. You can find the
connection string in the Azure portal on the Shared access policy blade.
1. Create a Maven project called read-file-upload-notification using the following command at your
command prompt. Note this command is a single, long command:

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=read-file-upload-notification -


DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2. At your command prompt, navigate to the new read-file-upload-notification folder.


3. Using a text editor, open the pom.xml file in the read-file-upload-notification folder and add the
following dependency to the dependencies node. Adding the dependency enables you to use the iothub-
java-service-client package in your application to communicate with your IoT hub service:

<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-service-client</artifactId>
<version>1.7.23</version>
</dependency>
NOTE
You can check for the latest version of iot-service-client using Maven search.

4. Save and close the pom.xml file.


5. Using a text editor, open the read-file-upload-notification\src\main\java\com\mycompany\app\App.java file.
6. Add the following import statements to the file:

import com.microsoft.azure.sdk.iot.service.*;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

7. Add the following class-level variables to the App class:

private static final String connectionString = "{Your IoT Hub connection string}";
private static final IotHubServiceClientProtocol protocol = IotHubServiceClientProtocol.AMQPS;
private static FileUploadNotificationReceiver fileUploadNotificationReceiver = null;

8. To print information about the file upload to the console, add the following nested class to the App class:

// Create a thread to receive file upload notifications.


private static class ShowFileUploadNotifications implements Runnable {
public void run() {
try {
while (true) {
System.out.println("Recieve file upload notifications...");
FileUploadNotification fileUploadNotification = fileUploadNotificationReceiver.receive();
if (fileUploadNotification != null) {
System.out.println("File Upload notification received");
System.out.println("Device Id : " + fileUploadNotification.getDeviceId());
System.out.println("Blob Uri: " + fileUploadNotification.getBlobUri());
System.out.println("Blob Name: " + fileUploadNotification.getBlobName());
System.out.println("Last Updated : " + fileUploadNotification.getLastUpdatedTimeDate());
System.out.println("Blob Size (Bytes): " + fileUploadNotification.getBlobSizeInBytes());
System.out.println("Enqueued Time: " + fileUploadNotification.getEnqueuedTimeUtcDate());
}
}
} catch (Exception ex) {
System.out.println("Exception reading reported properties: " + ex.getMessage());
}
}
}

9. To start the thread that listens for file upload notifications, add the following code to the main method:
public static void main(String[] args) throws IOException, URISyntaxException, Exception {
ServiceClient serviceClient = ServiceClient.createFromConnectionString(connectionString, protocol);

if (serviceClient != null) {
serviceClient.open();

// Get a file upload notification receiver from the ServiceClient.


fileUploadNotificationReceiver = serviceClient.getFileUploadNotificationReceiver();
fileUploadNotificationReceiver.open();

// Start the thread to receive file upload notifications.


ShowFileUploadNotifications showFileUploadNotifications = new ShowFileUploadNotifications();
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(showFileUploadNotifications);

System.out.println("Press ENTER to exit.");


System.in.read();
executor.shutdownNow();
System.out.println("Shutting down sample...");
fileUploadNotificationReceiver.close();
serviceClient.close();
}
}

10. Save and close the read-file-upload-notification\src\main\java\com\mycompany\app\App.java file.


11. Use the following command to build the read-file-upload-notification app and check for errors:

mvn clean package -DskipTests

Run the applications


Now you are ready to run the applications.
At a command prompt in the read-file-upload-notification folder, run the following command:

mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

At a command prompt in the simulated-device folder, run the following command:

mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

The following screenshot shows the output from the simulated-device app:
The following screenshot shows the output from the read-file-upload-notification app:

You can use the portal to view the uploaded file in the storage container you configured:
Next steps
In this tutorial, you learned how to use the file upload capabilities of IoT Hub to simplify file uploads from
devices. You can continue to explore IoT hub features and scenarios with the following articles:
Create an IoT hub programmatically
Introduction to C SDK
Azure IoT SDKs
To further explore the capabilities of IoT Hub, see:
Simulating a device with IoT Edge
Upload files from your device to the cloud with IoT
Hub
5/29/2018 • 5 min to read • Edit Online

This tutorial builds on the code in the Send Cloud-to-Device messages with IoT Hub tutorial to show you how to
use the file upload capabilities of IoT Hub to upload a file to Azure blob storage. The tutorial shows you how to:
Securely provide a device with an Azure blob URI for uploading a file.
Use the IoT Hub file upload notifications to trigger processing the file in your app back end.
The Get started with IoT Hub tutorial demonstrates the basic device-to-cloud messaging functionality of IoT Hub.
However, in some scenarios you cannot easily map the data your devices send into the relatively small device-to-
cloud messages that IoT Hub accepts. For example:
Large files that contain images
Videos
Vibration data sampled at high frequency
Some form of preprocessed data.
These files are typically batch processed in the cloud using tools such as Azure Data Factory or the Hadoop stack.
When you need to upland files from a device, you can still use the security and reliability of IoT Hub.
At the end of this tutorial you run two Node.js console apps:
SimulatedDevice.js, which uploads a file to storage using a SAS URI provided by your IoT hub.
ReadFileUploadNotification.js, which receives file upload notifications from your IoT hub.

NOTE
IoT Hub supports many device platforms and languages (including C, .NET, Javascript, Python, and Java) through Azure IoT
device SDKs. Refer to the Azure IoT Developer Center for step-by-step instructions on how to connect your device to Azure
IoT Hub.

To complete this tutorial, you need the following:


Node.js version 4.0.x or later.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Associate an Azure Storage account to IoT Hub


Because the simulated device app uploads a file to a blob, you must have an Azure Storage account associated to
IoT Hub. When you associate an Azure Storage account with an IoT hub, the IoT hub generates a SAS URI. A
device can use this SAS URI to securely upload a file to a blob container. The IoT Hub service and the device
SDKs coordinate the process that generates the SAS URI and makes it available to a device to use to upload a
file.
Follow the instructions in Configure file uploads using the Azure portal to associate an Azure Storage account to
your IoT hub. Make sure that a blob container is associated with your IoT hub and that file notifications are
enabled.
Upload a file from a device app
In this section, you create the device app to upload a file to IoT hub.
1. Create an empty folder called simulateddevice . In the simulateddevice folder, create a package.json file
using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the simulateddevice folder, run the following command to install the azure-
iot-device Device SDK package and azure-iot-device-mqtt package:

npm install azure-iot-device azure-iot-device-mqtt --save

3. Using a text editor, create a SimulatedDevice.js file in the simulateddevice folder.


4. Add the following require statements at the start of the SimulatedDevice.js file:

'use strict';

var fs = require('fs');
var mqtt = require('azure-iot-device-mqtt').Mqtt;
var clientFromConnectionString = require('azure-iot-device-mqtt').clientFromConnectionString;

5. Add a deviceconnectionstring variable and use it to create a Client instance. Replace


{deviceconnectionstring} with the name of the device you created in the Create an IoT Hub section:
var connectionString = '{deviceconnectionstring}';
var filename = 'myimage.png';

NOTE
For the sake of simplicity the connection string is included in the code: this is not a recommended practice and
depending on your use-case and architecture you may want to consider more secure ways of storing this secret.

6. Add the following code to connect the client:

var client = clientFromConnectionString(connectionString);


console.log('Client connected');

7. Create a callback and use the uploadToBlob function to upload the file.

fs.stat(filename, function (err, stats) {


const rr = fs.createReadStream(filename);

client.uploadToBlob(filename, rr, stats.size, function (err) {


if (err) {
console.error('Error uploading file: ' + err.toString());
} else {
console.log('File uploaded');
}
});
});

8. Save and close the SimulatedDevice.js file.


9. Copy an image file to the simulateddevice folder and rename it myimage.png .

Receive a file upload notification


In this section, you create a Node.js console app that receives file upload notification messages from IoT Hub.
You can use the iothubowner connection string from your IoT Hub to complete this section. You will find the
connection string in the Azure portal on the Shared access policy blade.
1. Create an empty folder called fileuploadnotification . In the fileuploadnotification folder, create a
package.json file using the following command at your command prompt. Accept all the defaults:

npm init

2. At your command prompt in the fileuploadnotification folder, run the following command to install the
azure-iothub SDK package:

npm install azure-iothub --save

3. Using a text editor, create a FileUploadNotification.js file in the fileuploadnotification folder.


4. Add the following require statements at the start of the FileUploadNotification.js file:
'use strict';

var Client = require('azure-iothub').Client;

5. Add a iothubconnectionstring variable and use it to create a Client instance. Replace


{iothubconnectionstring} with the connection string to the IoT hub you created in the Create an IoT Hub
section:

var connectionString = '{iothubconnectionstring}';

NOTE
For the sake of simplicity the connection string is included in the code: this is not a recommended practice and
depending on your use-case and architecture you may want to consider more secure ways of storing this secret.

6. Add the following code to connect the client:

var serviceClient = Client.fromConnectionString(connectionString);

7. Open the client and use the getFileNotificationReceiver function to receive status updates.

serviceClient.open(function (err) {
if (err) {
console.error('Could not connect: ' + err.message);
} else {
console.log('Service client connected');
serviceClient.getFileNotificationReceiver(function receiveFileUploadNotification(err, receiver){
if (err) {
console.error('error getting the file notification receiver: ' + err.toString());
} else {
receiver.on('message', function (msg) {
console.log('File upload from device:')
console.log(msg.getData().toString('utf-8'));
});
}
});
}
});

8. Save and close the FileUploadNotification.js file.

Run the applications


Now you are ready to run the applications.
At a command prompt in the fileuploadnotification folder, run the following command:

node FileUploadNotification.js

At a command prompt in the simulateddevice folder, run the following command:

node SimulatedDevice.js
The following screenshot shows the output from the SimulatedDevice app:

The following screenshot shows the output from the FileUploadNotification app:

You can use the portal to view the uploaded file in the storage container you configured:

Next steps
In this tutorial, you learned how to use the file upload capabilities of IoT Hub to simplify file uploads from
devices. You can continue to explore IoT hub features and scenarios with the following articles:
Create an IoT hub programmatically
Introduction to C SDK
Azure IoT SDKs
Upload files from your device to the cloud with IoT
Hub
5/29/2018 • 6 min to read • Edit Online

This tutorial follows how to use the file upload capabilities of IoT Hub to upload a file to Azure blob storage. The
tutorial shows you how to:
Securely provide a storage container for uploading a file.
Use the Python client to upload a file through your IoT hub.
The Get started with IoT Hub tutorial demonstrates the basic device-to-cloud messaging functionality of IoT
Hub. However, in some scenarios you cannot easily map the data your devices send into the relatively small
device-to-cloud messages that IoT Hub accepts. When you need to upland files from a device, you can still use
the security and reliability of IoT Hub.

NOTE
IoT Hub Python SDK currently only supports uploading character-based files such as .txt files.

At the end of this tutorial you run the Python console app:
FileUpload.py, which uploads a file to storage using the Python Device SDK.

NOTE
IoT Hub supports many device platforms and languages (including C, .NET, Javascript, Python, and Java) through Azure IoT
device SDKs. Refer to the Azure IoT Developer Center for step-by-step instructions on how to connect your device to Azure
IoT Hub.

To complete this tutorial, you need the following:


Python 2.x or 3.x. Make sure to use the 32-bit or 64-bit installation as required by your setup. When prompted
during the installation, make sure to add Python to your platform-specific environment variable. If you are
using Python 2.x, you may need to install or upgrade pip, the Python package management system.
If you are using Windows OS, then Visual C++ redistributable package to allow the use of native DLLs from
Python.
An active Azure account. (If you don't have an account, you can create a free account in just a couple of
minutes.)

Create an IoT hub


Create an IoT hub for your simulated device app to connect to. The following steps show you how to complete
this task by using the Azure portal.
1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
8. When your new IoT hub is ready, click its tile in the Azure portal to open its properties window. Now that
you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub. Click Shared access policies.
9. In Shared access policies, select the iothubowner policy. Copy the IoT Hub Connection string---
primary key to use later. For more information, see Access control in the "IoT Hub developer guide."

Create a device identity


In this section, you use the Azure portal to create a device identity in the identity registry in your IoT hub. A
device cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the
"Identity registry" section of the IoT Hub developer guide. Use the IoT Devices panel in the portal to generate a
unique device ID and key for your device to use to identify itself to IoT Hub. Device IDs are case-sensitive.
1. Sign in to the Azure portal.
2. Select All resources and find your IoT hub resource.
3. When your IoT hub resource is opened, click the IoT Devices tool, and then click Add at the top.
4. Provide a name for your new device, such as myDeviceId, and click Save. This action creates a new
device identity for your IoT hub.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

5. In the device list, click the newly created device and copy the Connection string---primary key to use
later.
NOTE
The IoT Hub identity registry only stores device identities to enable secure access to the IoT hub. It stores device IDs and
keys to use as security credentials, and an enabled/disabled flag that you can use to disable access for an individual device.
If your application needs to store other device-specific metadata, it should use an application-specific store. For more
information, see IoT Hub developer guide.

Associate an Azure Storage account to IoT Hub


Because the simulated device app uploads a file to a blob, you must have an Azure Storage account associated to
IoT Hub. When you associate an Azure Storage account with an IoT hub, the IoT hub generates a SAS URI. A
device can use this SAS URI to securely upload a file to a blob container. The IoT Hub service and the device
SDKs coordinate the process that generates the SAS URI and makes it available to a device to use to upload a
file.
Follow the instructions in Configure file uploads using the Azure portal to associate an Azure Storage account to
your IoT hub. Make sure that a blob container is associated with your IoT hub and that file notifications are
enabled.
Upload a file from a device app
In this section, you create the device app to upload a file to IoT hub.
1. At your command prompt, run the following command to install the azure-iothub-device-client
package:

pip install azure-iothub-device-client

2. Using a text editor, create a FileUpload.py file in your working folder.


3. Add the following import statements and variables at the start of the FileUpload.py file. Replace
deviceConnectionString with the connection string of your IoT hub device:

import time
import sys
import iothub_client
import os
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider,
IoTHubClientResult, IoTHubError

CONNECTION_STRING = "[Device Connection String]"


PROTOCOL = IoTHubTransportProvider.HTTP

PATHTOFILE = "[Full path to file]"


FILENAME = "[File name on storage after upload]"

4. Create a callback for the upload_blob function:


def blob_upload_conf_callback(result, user_context):
if str(result) == 'OK':
print ( "...file uploaded successfully." )
else:
print ( "...file upload callback returned: " + str(result) )

5. Add the following code to connect the client and upload the file. Also include the main routine:

def iothub_file_upload_sample_run():
try:
print ( "IoT Hub file upload sample, press Ctrl-C to exit" )

client = IoTHubClient(CONNECTION_STRING, PROTOCOL)

f = open(PATHTOFILE, "r")
content = f.read()

client.upload_blob_async(FILENAME, content, len(content), blob_upload_conf_callback, 0)

print ( "" )
print ( "File upload initiated..." )

while True:
time.sleep(30)

except IoTHubError as iothub_error:


print ( "Unexpected error %s from IoTHub" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubClient sample stopped" )
except:
print ( "generic error" )

if __name__ == '__main__':
print ( "Simulating a file upload using the Azure IoT Hub Device SDK for Python" )
print ( " Protocol %s" % PROTOCOL )
print ( " Connection string=%s" % CONNECTION_STRING )

iothub_file_upload_sample_run()

6. Save and close the UploadFile.py file.


7. Copy a sample text file to the working folder and rename it sample.txt .

NOTE
IoT Hub Python SDK currently only supports uploading character-based files such as .txt files.

Run the application


Now you are ready to run the application.
1. At a command prompt in your working folder, run the following command:

python FileUpload.py

2. The following screenshot shows the output from the FileUpload app:
3. You can use the portal to view the uploaded file in the storage container you configured:

Next steps
In this tutorial, you learned how to use the file upload capabilities of IoT Hub to simplify file uploads from
devices. You can continue to explore IoT hub features and scenarios with the following articles:
Create an IoT hub programmatically
Introduction to C SDK
Azure IoT SDKs
Create an IoT hub using the Azure portal
5/29/2018 • 5 min to read • Edit Online

This article describes:


How to find the IoT Hub service in the Azure portal.
How to create and manage IoT hubs.

Where to find the IoT Hub service


You can find the IoT Hub service in the following locations in the portal:
Choose + New, then choose Internet of Things.
In the Marketplace, choose Internet of Things.

Create an IoT hub


You can create an IoT hub using the following methods:
The + New option opens the blade shown in the following screen shot. The steps for creating the IoT hub
through this method and through the marketplace are identical.
In the Marketplace, choose Create to open the blade shown in the following screen shot.
The following sections describe the several steps to create an IoT hub:
Choose the name of the IoT hub
To create an IoT hub, you must name the IoT hub. This name must be unique across all IoT hubs.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while naming
it.

Choose the pricing tier


You can choose from several tiers depending on how many features you want and how many messages you
send through your solution per day. The free tier is intended for testing and evaluation. It allows 500 devices to
be connected to the IoT hub and up to 8,000 messages per day. Each Azure subscription can create one IoT Hub
in the free tier.
For details about the other tier options, see Choosing the right IoT Hub tier.
IoT hub units
The number of messages allowed per unit per day depends on your hub's pricing tier. For example, if you want
the IoT hub to support ingress of 700,000 messages, you choose two S1 tier units.
Device to cloud partitions and resource group
You can change the number of partitions for an IoT hub. The default number of partitions is 4, you can choose a
different number from the drop-down list.
You do not need to explicitly create an empty resource group. When you create a resource, you can choose either
to create a new, or use an existing resource group.
Choose subscription
Azure IoT Hub automatically lists the Azure subscriptions the user account is linked to. You can choose the Azure
subscription to associate the IoT hub to.
Choose the location
The location option provides a list of the regions where IoT Hub is available.
Create the IoT hub
When all previous steps are complete, you can create the IoT hub. Click Create to start the back-end process to
create and deploy the IoT hub with the options you chose.
It can take a few minutes to create the IoT hub as it takes time for the back-end deployment to run on the
appropriate location servers.

Change the settings of the IoT hub


You can change the settings of an existing IoT hub after it is created from the IoT Hub blade.

Shared access policies: These policies define the permissions for devices and services to connect to IoT Hub.
You can access these policies by clicking Shared access policies under General. In this blade, you can either
modify existing policies or add a new policy.
Create a policy
Click Add to open a blade. Here you can enter the new policy name and the permissions that you want to
associate with this policy, as shown in the following figure:
There are several permissions that can be associated with these shared policies. The Registry read and
Registry write policies grant read and write access rights to the identity registry. Choosing the write
option automatically chooses the read option.
The Service connect policy grants permission to access service endpoints such as Receive device-to-
cloud. The Device connect policy grants permissions for sending and receiving messages using the IoT
Hub device-side endpoints.
Click Create to add this newly created policy to the existing list.
Endpoints
Click Endpoints to display a list of endpoints for the IoT hub that you are modifying. There are two types of
endpoints: endpoints that are built into the IoT hub, and endpoints that you add to the IoT hub after its creation.

Built-in endpoints
There are two built-in endpoints: Cloud to device feedback and Events.
Cloud to device feedback settings: This setting has two subsettings: Cloud to Device TTL (time-to-live)
and Retention time (in hours) for the messages. When your first create an IoT hub, both these settings have
the default value of one hour. To adjust these settings, use the sliders or type the values.
Events settings: This setting has several subsettings, some of which are read-only. The following list
describes these settings:
Partitions: A default value is set when the IoT hub is created. You can change the number of
partitions through this setting.
Event Hub-compatible name and endpoint: When the IoT hub is created, an Event Hub is
created internally that you may need access to under certain circumstances. You cannot customize
the Event Hub-compatible name and endpoint values but you can copy them by clicking Copy.
Retention Time: Set to one day by default but you can change it using the drop-down list. This
value is in days for the device-to-cloud setting.
Consumer Groups: Consumer groups enable multiple readers to read messages independently
from the IoT hub. Every IoT hub is created with a default consumer group. However, you can add
or delete consumer groups to your IoT hubs using this setting.

NOTE
The default consumer group cannot be edited or deleted.

Custom endpoints
You can add custom endpoints on your IoT hub using the portal. From the Endpoints blade, click Add at the
top to open the Add endpoint blade. Enter the required information, then click OK. Your custom endpoint is
now listed in the main Endpoints blade.
You can read more about custom endpoints in Reference - IoT hub endpoints.

Routes
Click Routes to manage how IoT Hub dispatches your device-to-cloud messages.
You can add routes to your IoT hub by clicking Add at the top of the Routes* blade, entering the required
information, and clicking OK. Your route is then listed in the main Routes blade. You can edit a route by clicking
it in the list of routes. To enable a route, click it in the list of routes and set the Enabled toggle to Off. To save the
change, click OK at the bottom of the blade.

Delete the IoT hub


You can browse to the IoT hub you want to delete by clicking Browse, and then choosing the appropriate hub to
delete. To delete the IoT hub, click the Delete button below the IoT hub name.

Next steps
Follow these links to learn more about managing Azure IoT Hub:
Bulk manage IoT devices
IoT Hub metrics
Operations monitoring
To further explore the capabilities of IoT Hub, see:
IoT Hub developer guide
Deploying AI to edge devices with Azure IoT Edge
Secure your IoT solution from the ground up
Create an IoT hub using the New-AzureRmIotHub
cmdlet
5/29/2018 • 2 min to read • Edit Online

Introduction
You can use Azure PowerShell cmdlets to create and manage Azure IoT hubs. This tutorial shows you how to
create an IoT hub with PowerShell.

NOTE
Azure has two different deployment models for creating and working with resources: Azure Resource Manager and classic.
This article covers using the Azure Resource Manager deployment model.

To complete this tutorial, you need the following:


An active Azure account.
If you don't have an account, you can create a free account in just a couple of minutes.
Azure PowerShell cmdlets.

Connect to your Azure subscription


In a PowerShell command prompt, enter the following command to sign in to your Azure subscription:

Connect-AzureRmAccount

If you have multiple Azure subscriptions, signing in to Azure grants you access to all the Azure subscriptions
associated with your credentials. Use the following command to list the Azure subscriptions available for you to
use:

Get-AzureRMSubscription

Use the following command to select subscription that you want to use to run the commands to create your IoT
hub. You can use either the subscription name or ID from the output of the previous command:

Select-AzureRMSubscription `
-SubscriptionName "{your subscription name}"

Create resource group


You need a resource group to deploy an IoT hub. You can use an existing resource group or create a new one.
You can use the following command to discover the locations where you can deploy an IoT hub:

((Get-AzureRmResourceProvider `
-ProviderNamespace Microsoft.Devices).ResourceTypes `
| Where-Object ResourceTypeName -eq IoTHubs).Locations
To create a resource group for your IoT hub in one of the supported locations for IoT Hub, use the following
command. This example creates a resource group called MyIoTRG1 in the East US region:

New-AzureRmResourceGroup -Name MyIoTRG1 -Location "East US"

Create an IoT hub


To create an IoT hub in the resource group you created in the previous step, use the following command. This
example creates an S1 hub called MyTestIoTHub in the East US region:

New-AzureRmIotHub `
-ResourceGroupName MyIoTRG1 `
-Name MyTestIoTHub `
-SkuName S1 -Units 1 `
-Location "East US"

The name of the IoT hub must be unique.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while naming
it.

You can list all the IoT hubs in your subscription using the following command:

Get-AzureRmIotHub

The previous example adds an S1 Standard IoT Hub for which you are billed. You can delete the IoT hub using the
following command:

Remove-AzureRmIotHub `
-ResourceGroupName MyIoTRG1 `
-Name MyTestIoTHub

Alternatively, you can remove a resource group and all the resources it contains using the following command:

Remove-AzureRmResourceGroup -Name MyIoTRG1

Next steps
Now you have deployed an IoT hub using a PowerShell cmdlet, you may want to explore further:
Discover other PowerShell cmdlets for working with your IoT hub.
Read about the capabilities of the IoT Hub resource provider REST API.
To learn more about developing for IoT Hub, see the following articles:
Introduction to C SDK
Azure IoT SDKs
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Create an IoT hub using the Azure CLI 2.0
5/29/2018 • 2 min to read • Edit Online

Introduction
You can use Azure CLI 2.0 (az.py) to create and manage Azure IoT hubs programmatically. This article shows you
how to use the Azure CLI 2.0 (az.py) to create an IoT hub.
You can complete the task using one of the following CLI versions:
Azure CLI (azure.js) – the CLI for the classic and resource management deployment models.
Azure CLI 2.0 (az.py) - the next generation CLI for the resource management deployment model as described
in this article.
To complete this tutorial, you need the following:
An active Azure account. If you don't have an account, you can create a free account in just a couple of minutes.
Azure CLI 2.0.

Sign in and set your Azure account


Sign in to your Azure account and select your subscription.
1. At the command prompt, run the login command:

az login

Follow the instructions to authenticate using the code and sign in to your Azure account through a web
browser.
2. If you have multiple Azure subscriptions, signing in to Azure grants you access to all the Azure accounts
associated with your credentials. Use the following command to list the Azure accounts available for you to
use:

az account list

Use the following command to select subscription that you want to use to run the commands to create
your IoT hub. You can use either the subscription name or ID from the output of the previous command:

az account set --subscription {your subscription name or id}

Create an IoT Hub


Use the Azure CLI to create a resource group and then add an IoT hub.
1. When you create an IoT hub, you must create it in a resource group. Either use an existing resource group,
or run the following command to create a resource group:

az group create --name {your resource group name} --location westus


TIP
The previous example creates the resource group in the West US location. You can view a list of available locations
by running the command az account list-locations -o table .

2. Run the following command to create an IoT hub in your resource group, using a globally unique name for
your IoT hub:

az iot hub create --name {your iot hub name} --resource-group {your resource group name} --sku S1

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

NOTE
The previous command creates an IoT hub in the S1 pricing tier for which you are billed. For more information, see Azure
IoT Hub pricing.

Remove an IoT Hub


You can use the Azure CLI to delete an individual resource, such as an IoT hub, or delete a resource group and all
its resources, including any IoT hubs.
To delete an IoT hub, run the following command:

az iot hub delete --name {your iot hub name} --resource-group {your resource group name}

To delete a resource group and all its resources, run the following command:

az group delete --name {your resource group name}

Next steps
To learn more about developing for IoT Hub, see the following articles:
IoT Hub developer guide
To further explore the capabilities of IoT Hub, see:
Using the Azure portal to manage IoT Hub
Create an IoT hub using the Azure CLI
5/29/2018 • 2 min to read • Edit Online

Introduction
You can use Azure CLI (azure.js) to create and manage Azure IoT hubs programmatically. This article shows you
how to use the Azure CLI (azure.js) to create an IoT hub.
You can complete the task using one of the following CLI versions:
Azure CLI (azure.js) – the CLI for the classic and resource management deployment models as described in
this article.
Azure CLI 2.0 (az.py) - the next generation CLI for the resource management deployment model.
To complete this tutorial, you need the following:
An active Azure account. If you don't have an account, you can create a free account in just a couple of
minutes.
Azure CLI 0.10.4 or later. If you already have the Azure CLI installed, you can validate the current version at
the command prompt with the following command:

azure --version

NOTE
Azure has two different deployment models for creating and working with resources: Azure Resource Manager and classic.
The Azure CLI must be in Azure Resource Manager mode:

azure config mode arm

Set your Azure account and subscription


1. At the command prompt, login by typing the following command:

azure login

Use the suggested web browser and code to authenticate.


2. If you have multiple Azure subscriptions, connecting to Azure grants you access to all the Azure
subscriptions associated with your credentials. You can view the Azure subscriptions, and identify which
one is the default, using the command:

azure account list

To set the subscription context under which you want to run the rest of the commands use:

azure account set <subscription name>


3. If you do not have a resource group, you can create one named exampleResourceGroup:

azure group create -n exampleResourceGroup -l westus

TIP
The article Use the Azure CLI to manage Azure resources and resource groups provides more information about how to
use the Azure CLI to manage Azure resources.

Create an IoT Hub


Required parameters:

azure iothub create -g <resource-group> -n <name> -l <location> -s <sku-name> -u <units>

resource-group. The resource group name. The format is case insensitive alphanumeric, underscore, and
hyphen, 1-64 length.
name. The name of the IoT hub to be created. The format is case insensitive alphanumeric and hyphen, 3-50
length.
location. The location (azure region/datacenter) to provision the IoT hub.
sku-name. The name of the sku, one of: [F1, S1, S2, S3]. For details about each sku, see Azure IoT Hub
pricing. Currently, basic tiers are only available through the portal.
units. The number of provisioned units. For details about unit limits, see Azure IoT Hub pricing.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while naming
it.

To see all the parameters available for creation, you can use the help command in command prompt:

azure iothub create -h

Quick example: To create an IoT Hub called exampleIoTHubName in the resource group
exampleResourceGroup, run the following command:

azure iothub create -g exampleResourceGroup -n exampleIoTHubName -l westus -k s1 -u 1

NOTE
This Azure CLI command creates an S1 Standard IoT Hub for which you are billed. You can delete the IoT hub
exampleIoTHubName using following command:

azure iothub delete -g exampleResourceGroup -n exampleIoTHubName

Next steps
To learn more about developing for IoT Hub, see the following article:
IoT SDKs
To further explore the capabilities of IoT Hub, see:
Using the Azure portal to manage IoT Hub
Create an IoT hub using the resource provider REST
API (.NET)
5/29/2018 • 7 min to read • Edit Online

You can use the IoT Hub resource provider REST API to create and manage Azure IoT hubs programmatically.
This tutorial shows you how to use the IoT Hub resource provider REST API to create an IoT hub from a C#
program.

NOTE
Azure has two different deployment models for creating and working with resources: Azure Resource Manager and classic.
This article covers using the Azure Resource Manager deployment model.

To complete this tutorial, you need the following:


Visual Studio 2015 or Visual Studio 2017.
An active Azure account.
If you don't have an account, you can create a free account in just a couple of minutes.
Azure PowerShell 1.0 or later.

Prepare to authenticate Azure Resource Manager requests


You must authenticate all the operations that you perform on resources using the Azure Resource Manager with
Azure Active Directory (AD ). The easiest way to configure this is to use PowerShell or Azure CLI.
Install the Azure PowerShell cmdlets before you continue.
The following steps show how to set up password authentication for an AD application using PowerShell. You can
run these commands in a standard PowerShell session.
1. Log in to your Azure subscription using the following command:

Connect-AzureRmAccount

2. If you have multiple Azure subscriptions, signing in to Azure grants you access to all the Azure
subscriptions associated with your credentials. Use the following command to list the Azure subscriptions
available for you to use:

Get-AzureRMSubscription

Use the following command to select subscription that you want to use to run the commands to manage
your IoT hub. You can use either the subscription name or ID from the output of the previous command:

Select-AzureRMSubscription `
-SubscriptionName "{your subscription name}"

3. Make a note of your TenantId and SubscriptionId. You need them later.
4. Create a new Azure Active Directory application using the following command, replacing the place holders:
{Display name}: a display name for your application such as MySampleApp
{Home page URL }: the URL of the home page of your app such as http://mysampleapp/home. This
URL does not need to point to a real application.
{Application identifier}: A unique identifier such as http://mysampleapp. This URL does not need
to point to a real application.
{Password}: A password that you use to authenticate with your app.

New-AzureRmADApplication -DisplayName {Display name} -HomePage {Home page URL} -IdentifierUris


{Application identifier} -Password {Password}

5. Make a note of the ApplicationId of the application you created. You need this later.
6. Create a new service principal using the following command, replacing {MyApplicationId} with the
ApplicationId from the previous step:

New-AzureRmADServicePrincipal -ApplicationId {MyApplicationId}

7. Set up a role assignment using the following command, replacing {MyApplicationId} with your
ApplicationId.

New-AzureRmRoleAssignment -RoleDefinitionName Owner -ServicePrincipalName {MyApplicationId}

You have now finished creating the Azure AD application that enables you to authenticate from your custom C#
application. You need the following values later in this tutorial:
TenantId
SubscriptionId
ApplicationId
Password

Prepare your Visual Studio project


1. In Visual Studio, create a Visual C# Windows Classic Desktop project using the Console App (.NET
Framework) project template. Name the project CreateIoTHubREST.
2. In Solution Explorer, right-click on your project and then click Manage NuGet Packages.
3. In NuGet Package Manager, check Include prerelease, and on the Browse page search for
Microsoft.Azure.Management.ResourceManager. Select the package, click Install, in Review
Changes click OK, then click I Accept to accept the licenses.
4. In NuGet Package Manager, search for Microsoft.IdentityModel.Clients.ActiveDirectory. Click Install,
in Review Changes click OK, then click I Accept to accept the license.
5. In Program.cs, replace the existing using statements with the following code:
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using Microsoft.Azure.Management.ResourceManager;
using Microsoft.Azure.Management.ResourceManager.Models;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Newtonsoft.Json;
using Microsoft.Rest;
using System.Linq;
using System.Threading;

6. In Program.cs, add the following static variables replacing the placeholder values. You made a note of
ApplicationId, SubscriptionId, TenantId, and Password earlier in this tutorial. Resource group name
is the name of the resource group you use when you create the IoT hub. You can use a pre-existing or a
new resource group. IoT Hub name is the name of the IoT Hub you create, such as MyIoTHub. The
name of your IoT hub must be globally unique. Deployment name is a name for the deployment, such as
Deployment_01.

static string applicationId = "{Your ApplicationId}";


static string subscriptionId = "{Your SubscriptionId}";
static string tenantId = "{Your TenantId}";
static string password = "{Your application Password}";

static string rgName = "{Resource group name}";


static string iotHubName = "{IoT Hub name including your initials}";

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

Obtain an Azure Resource Manager token


Azure Active Directory must authenticate all the tasks that you perform on resources using the Azure Resource
Manager. The example shown here uses password authentication, for other approaches see Authenticating Azure
Resource Manager requests.
1. Add the following code to the Main method in Program.cs to retrieve a token from Azure AD using the
application id and password.

var authContext = new AuthenticationContext(string.Format


("https://login.microsoftonline.com/{0}", tenantId));
var credential = new ClientCredential(applicationId, password);
AuthenticationResult token = authContext.AcquireTokenAsync
("https://management.core.windows.net/", credential).Result;

if (token == null)
{
Console.WriteLine("Failed to obtain the token");
return;
}

2. Create a ResourceManagementClient object that uses the token by adding the following code to the end
of the Main method:
var creds = new TokenCredentials(token.AccessToken);
var client = new ResourceManagementClient(creds);
client.SubscriptionId = subscriptionId;

3. Create, or obtain a reference to, the resource group you are using:

var rgResponse = client.ResourceGroups.CreateOrUpdate(rgName,


new ResourceGroup("East US"));
if (rgResponse.Properties.ProvisioningState != "Succeeded")
{
Console.WriteLine("Problem creating resource group");
return;
}

Use the resource provider REST API to create an IoT hub


Use the IoT Hub resource provider REST API to create an IoT hub in your resource group. You can also use the
resource provider REST API to make changes to an existing IoT hub.
1. Add the following method to Program.cs:

static void CreateIoTHub(string token)


{

2. Add the following code to the CreateIoTHub method. This code creates an HttpClient object with the
authentication token in the headers:

HttpClient client = new HttpClient();


client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

3. Add the following code to the CreateIoTHub method. This code describes the IoT hub to create and
generates a JSON representation. For the current list of locations that support IoT Hub see Azure Status:

var description = new


{
name = iotHubName,
location = "East US",
sku = new
{
name = "S1",
tier = "Standard",
capacity = 1
}
};

var json = JsonConvert.SerializeObject(description, Formatting.Indented);

4. Add the following code to the CreateIoTHub method. This code submits the REST request to Azure. The
code then checks the response and retrieves the URL you can use to monitor the state of the deployment
task:
var content = new StringContent(JsonConvert.SerializeObject(description), Encoding.UTF8,
"application/json");
var requestUri =
string.Format("https://management.azure.com/subscriptions/{0}/resourcegroups/{1}/providers/Microsoft.de
vices/IotHubs/{2}?api-version=2016-02-03", subscriptionId, rgName, iotHubName);
var result = client.PutAsync(requestUri, content).Result;

if (!result.IsSuccessStatusCode)
{
Console.WriteLine("Failed {0}", result.Content.ReadAsStringAsync().Result);
return;
}

var asyncStatusUri = result.Headers.GetValues("Azure-AsyncOperation").First();

5. Add the following code to the end of the CreateIoTHub method. This code uses the asyncStatusUri
address retrieved in the previous step to wait for the deployment to complete:

string body;
do
{
Thread.Sleep(10000);
HttpResponseMessage deploymentstatus = client.GetAsync(asyncStatusUri).Result;
body = deploymentstatus.Content.ReadAsStringAsync().Result;
} while (body == "{\"status\":\"Running\"}");

6. Add the following code to the end of the CreateIoTHub method. This code retrieves the keys of the IoT
hub you created and prints them to the console:

var listKeysUri =
string.Format("https://management.azure.com/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.De
vices/IotHubs/{2}/IoTHubKeys/listkeys?api-version=2016-02-03", subscriptionId, rgName, iotHubName);
var keysresults = client.PostAsync(listKeysUri, null).Result;

Console.WriteLine("Keys: {0}", keysresults.Content.ReadAsStringAsync().Result);

Complete and run the application


You can now complete the application by calling the CreateIoTHub method before you build and run it.
1. Add the following code to the end of the Main method:

CreateIoTHub(token.AccessToken);
Console.ReadLine();

2. Click Build and then Build Solution. Correct any errors.


3. Click Debug and then Start Debugging to run the application. It may take several minutes for the
deployment to run.
4. To verify that your application added the new IoT hub, visit the Azure portal and view your list of resources.
Alternatively, use the Get-AzureRmResource PowerShell cmdlet.
NOTE
This example application adds an S1 Standard IoT Hub for which you are billed. When you are finished, you can delete the
IoT hub through the Azure portal or by using the Remove-AzureRmResource PowerShell cmdlet when you are finished.

Next steps
Now you have deployed an IoT hub using the resource provider REST API, you may want to explore further:
Read about the capabilities of the IoT Hub resource provider REST API.
Read Azure Resource Manager overview to learn more about the capabilities of Azure Resource Manager.
To learn more about developing for IoT Hub, see the following articles:
Introduction to C SDK
Azure IoT SDKs
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Create an IoT hub using Azure Resource Manager
template (PowerShell)
5/29/2018 • 3 min to read • Edit Online

You can use Azure Resource Manager to create and manage Azure IoT hubs programmatically. This tutorial
shows you how to use an Azure Resource Manager template to create an IoT hub with PowerShell.

NOTE
Azure has two different deployment models for creating and working with resources: Azure Resource Manager and
classic. This article covers using the Azure Resource Manager deployment model.

To complete this tutorial, you need the following:


An active Azure account.
If you don't have an account, you can create a free account in just a couple of minutes.
Azure PowerShell 1.0 or later.

TIP
The article Using Azure PowerShell with Azure Resource Manager provides more information about how to use
PowerShell and Azure Resource Manager templates to create Azure resources.

Connect to your Azure subscription


In a PowerShell command prompt, enter the following command to sign in to your Azure subscription:

Connect-AzureRmAccount

If you have multiple Azure subscriptions, signing in to Azure grants you access to all the Azure subscriptions
associated with your credentials. Use the following command to list the Azure subscriptions available for you to
use:

Get-AzureRMSubscription

Use the following command to select subscription that you want to use to run the commands to create your IoT
hub. You can use either the subscription name or ID from the output of the previous command:

Select-AzureRMSubscription `
-SubscriptionName "{your subscription name}"

You can use the following commands to discover where you can deploy an IoT hub and the currently supported
API versions:
((Get-AzureRmResourceProvider -ProviderNamespace Microsoft.Devices).ResourceTypes | Where-Object
ResourceTypeName -eq IoTHubs).Locations
((Get-AzureRmResourceProvider -ProviderNamespace Microsoft.Devices).ResourceTypes | Where-Object
ResourceTypeName -eq IoTHubs).ApiVersions

Create a resource group to contain your IoT hub using the following command in one of the supported
locations for IoT Hub. This example creates a resource group called MyIoTRG1:

New-AzureRmResourceGroup -Name MyIoTRG1 -Location "East US"

Submit a template to create an IoT hub


Use a JSON template to create an IoT hub in your resource group. You can also use an Azure Resource
Manager template to make changes to an existing IoT hub.
1. Use a text editor to create an Azure Resource Manager template called template.json with the
following resource definition to create a new standard IoT hub. This example adds the IoT Hub in the
East US region, creates two consumer groups (cg1 and cg2) on the Event Hub-compatible endpoint,
and uses the 2016-02-03 API version. This template also expects you to pass in the IoT hub name as a
parameter called hubName. For the current list of locations that support IoT Hub see Azure Status.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"hubName": {
"type": "string"
}
},
"resources": [
{
"apiVersion": "2016-02-03",
"type": "Microsoft.Devices/IotHubs",
"name": "[parameters('hubName')]",
"location": "East US",
"sku": {
"name": "S1",
"tier": "Standard",
"capacity": 1
},
"properties": {
"location": "East US"
}
},
{
"apiVersion": "2016-02-03",
"type": "Microsoft.Devices/IotHubs/eventhubEndpoints/ConsumerGroups",
"name": "[concat(parameters('hubName'), '/events/cg1')]",
"dependsOn": [
"[concat('Microsoft.Devices/Iothubs/', parameters('hubName'))]"
]
},
{
"apiVersion": "2016-02-03",
"type": "Microsoft.Devices/IotHubs/eventhubEndpoints/ConsumerGroups",
"name": "[concat(parameters('hubName'), '/events/cg2')]",
"dependsOn": [
"[concat('Microsoft.Devices/Iothubs/', parameters('hubName'))]"
]
}
],
"outputs": {
"hubKeys": {
"value": "[listKeys(resourceId('Microsoft.Devices/IotHubs', parameters('hubName')), '2016-02-
03')]",
"type": "object"
}
}
}

2. Save the Azure Resource Manager template file on your local machine. This example assumes you save
it in a folder called c:\templates.
3. Run the following command to deploy your new IoT hub, passing the name of your IoT hub as a
parameter. In this example, the name of the IoT hub is abcmyiothub . The name of your IoT hub must be
globally unique:

New-AzureRmResourceGroupDeployment -ResourceGroupName MyIoTRG1 -TemplateFile


C:\templates\template.json -hubName abcmyiothub
IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information
while naming it.

4. The output displays the keys for the IoT hub you created.
5. To verify your application added the new IoT hub, visit the Azure portal and view your list of resources.
Alternatively, use the Get-AzureRmResource PowerShell cmdlet.

NOTE
This example application adds an S1 Standard IoT Hub for which you are billed. You can delete the IoT hub through the
Azure portal or by using the Remove-AzureRmResource PowerShell cmdlet when you are finished.

Next steps
Now you have deployed an IoT hub using an Azure Resource Manager template with PowerShell, you may
want to explore further:
Read about the capabilities of the IoT Hub resource provider REST API.
Read Azure Resource Manager overview to learn more about the capabilities of Azure Resource Manager.
To learn more about developing for IoT Hub, see the following articles:
Introduction to C SDK
Azure IoT SDKs
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Create an IoT hub using Azure Resource Manager
template (.NET)
5/29/2018 • 7 min to read • Edit Online

You can use Azure Resource Manager to create and manage Azure IoT hubs programmatically. This tutorial
shows you how to use an Azure Resource Manager template to create an IoT hub from a C# program.

NOTE
Azure has two different deployment models for creating and working with resources: Azure Resource Manager and classic.
This article covers using the Azure Resource Manager deployment model.

To complete this tutorial, you need the following:


Visual Studio 2015 or Visual Studio 2017.
An active Azure account.
If you don't have an account, you can create a free account in just a couple of minutes.
An Azure Storage account where you can store your Azure Resource Manager template files.
Azure PowerShell 1.0 or later.

Prepare to authenticate Azure Resource Manager requests


You must authenticate all the operations that you perform on resources using the Azure Resource Manager with
Azure Active Directory (AD ). The easiest way to configure this is to use PowerShell or Azure CLI.
Install the Azure PowerShell cmdlets before you continue.
The following steps show how to set up password authentication for an AD application using PowerShell. You
can run these commands in a standard PowerShell session.
1. Log in to your Azure subscription using the following command:

Connect-AzureRmAccount

2. If you have multiple Azure subscriptions, signing in to Azure grants you access to all the Azure
subscriptions associated with your credentials. Use the following command to list the Azure subscriptions
available for you to use:

Get-AzureRMSubscription

Use the following command to select subscription that you want to use to run the commands to manage
your IoT hub. You can use either the subscription name or ID from the output of the previous command:

Select-AzureRMSubscription `
-SubscriptionName "{your subscription name}"

3. Make a note of your TenantId and SubscriptionId. You need them later.
4. Create a new Azure Active Directory application using the following command, replacing the place
holders:
{Display name}: a display name for your application such as MySampleApp
{Home page URL }: the URL of the home page of your app such as http://mysampleapp/home.
This URL does not need to point to a real application.
{Application identifier}: A unique identifier such as http://mysampleapp. This URL does not need
to point to a real application.
{Password}: A password that you use to authenticate with your app.

New-AzureRmADApplication -DisplayName {Display name} -HomePage {Home page URL} -IdentifierUris


{Application identifier} -Password {Password}

5. Make a note of the ApplicationId of the application you created. You need this later.
6. Create a new service principal using the following command, replacing {MyApplicationId} with the
ApplicationId from the previous step:

New-AzureRmADServicePrincipal -ApplicationId {MyApplicationId}

7. Set up a role assignment using the following command, replacing {MyApplicationId} with your
ApplicationId.

New-AzureRmRoleAssignment -RoleDefinitionName Owner -ServicePrincipalName {MyApplicationId}

You have now finished creating the Azure AD application that enables you to authenticate from your custom C#
application. You need the following values later in this tutorial:
TenantId
SubscriptionId
ApplicationId
Password

Prepare your Visual Studio project


1. In Visual Studio, create a Visual C# Windows Classic Desktop project using the Console App (.NET
Framework) project template. Name the project CreateIoTHub.
2. In Solution Explorer, right-click on your project and then click Manage NuGet Packages.
3. In NuGet Package Manager, check Include prerelease, and on the Browse page search for
Microsoft.Azure.Management.ResourceManager. Select the package, click Install, in Review
Changes click OK, then click I Accept to accept the licenses.
4. In NuGet Package Manager, search for Microsoft.IdentityModel.Clients.ActiveDirectory. Click
Install, in Review Changes click OK, then click I Accept to accept the license.
5. In Program.cs, replace the existing using statements with the following code:

using System;
using Microsoft.Azure.Management.ResourceManager;
using Microsoft.Azure.Management.ResourceManager.Models;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.Rest;
6. In Program.cs, add the following static variables replacing the placeholder values. You made a note of
ApplicationId, SubscriptionId, TenantId, and Password earlier in this tutorial. Your Azure Storage
account name is the name of the Azure Storage account where you store your Azure Resource Manager
template files. Resource group name is the name of the resource group you use when you create the IoT
hub. The name can be a pre-existing or new resource group. Deployment name is a name for the
deployment, such as Deployment_01.

static string applicationId = "{Your ApplicationId}";


static string subscriptionId = "{Your SubscriptionId}";
static string tenantId = "{Your TenantId}";
static string password = "{Your application Password}";
static string storageAddress = "https://{Your storage account name}.blob.core.windows.net";
static string rgName = "{Resource group name}";
static string deploymentName = "{Deployment name}";

Obtain an Azure Resource Manager token


Azure Active Directory must authenticate all the tasks that you perform on resources using the Azure Resource
Manager. The example shown here uses password authentication, for other approaches see Authenticating Azure
Resource Manager requests.
1. Add the following code to the Main method in Program.cs to retrieve a token from Azure AD using the
application id and password.

var authContext = new AuthenticationContext(string.Format


("https://login.microsoftonline.com/{0}", tenantId));
var credential = new ClientCredential(applicationId, password);
AuthenticationResult token = authContext.AcquireTokenAsync
("https://management.core.windows.net/", credential).Result;

if (token == null)
{
Console.WriteLine("Failed to obtain the token");
return;
}

2. Create a ResourceManagementClient object that uses the token by adding the following code to the
end of the Main method:

var creds = new TokenCredentials(token.AccessToken);


var client = new ResourceManagementClient(creds);
client.SubscriptionId = subscriptionId;

3. Create, or obtain a reference to, the resource group you are using:

var rgResponse = client.ResourceGroups.CreateOrUpdate(rgName,


new ResourceGroup("East US"));
if (rgResponse.Properties.ProvisioningState != "Succeeded")
{
Console.WriteLine("Problem creating resource group");
return;
}

Submit a template to create an IoT hub


Use a JSON template and parameter file to create an IoT hub in your resource group. You can also use an Azure
Resource Manager template to make changes to an existing IoT hub.
1. In Solution Explorer, right-click on your project, click Add, and then click New Item. Add a JSON file
called template.json to your project.
2. To add a standard IoT hub to the East US region, replace the contents of template.json with the
following resource definition. For the current list of regions that support IoT Hub see Azure Status:

{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"hubName": {
"type": "string"
}
},
"resources": [
{
"apiVersion": "2016-02-03",
"type": "Microsoft.Devices/IotHubs",
"name": "[parameters('hubName')]",
"location": "East US",
"sku": {
"name": "S1",
"tier": "Standard",
"capacity": 1
},
"properties": {
"location": "East US"
}
}
],
"outputs": {
"hubKeys": {
"value": "[listKeys(resourceId('Microsoft.Devices/IotHubs', parameters('hubName')), '2016-02-
03')]",
"type": "object"
}
}
}

3. In Solution Explorer, right-click on your project, click Add, and then click New Item. Add a JSON file
called parameters.json to your project.
4. Replace the contents of parameters.json with the following parameter information that sets a name for
the new IoT hub such as {your initials}mynewiothub. The IoT hub name must be globally unique so it
should include your name or initials:

{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"hubName": { "value": "mynewiothub" }
}
}

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
5. In Server Explorer, connect to your Azure subscription, and in your Azure Storage account create a
container called templates. In the Properties panel, set the Public Read Access permissions for the
templates container to Blob.
6. In Server Explorer, right-click on the templates container and then click View Blob Container. Click the
Upload Blob button, select the two files, parameters.json and templates.json, and then click Open to
upload the JSON files to the templates container. The URLs of the blobs containing the JSON data are:

https://{Your storage account name}.blob.core.windows.net/templates/parameters.json


https://{Your storage account name}.blob.core.windows.net/templates/template.json

7. Add the following method to Program.cs:

static void CreateIoTHub(ResourceManagementClient client)


{

8. Add the following code to the CreateIoTHub method to submit the template and parameter files to the
Azure Resource Manager:

var createResponse = client.Deployments.CreateOrUpdate(


rgName,
deploymentName,
new Deployment()
{
Properties = new DeploymentProperties
{
Mode = DeploymentMode.Incremental,
TemplateLink = new TemplateLink
{
Uri = storageAddress + "/templates/template.json"
},
ParametersLink = new ParametersLink
{
Uri = storageAddress + "/templates/parameters.json"
}
}
});

9. Add the following code to the CreateIoTHub method that displays the status and the keys for the new
IoT hub:

string state = createResponse.Properties.ProvisioningState;


Console.WriteLine("Deployment state: {0}", state);

if (state != "Succeeded")
{
Console.WriteLine("Failed to create iothub");
}
Console.WriteLine(createResponse.Properties.Outputs);

Complete and run the application


You can now complete the application by calling the CreateIoTHub method before you build and run it.
1. Add the following code to the end of the Main method:
CreateIoTHub(client);
Console.ReadLine();

2. Click Build and then Build Solution. Correct any errors.


3. Click Debug and then Start Debugging to run the application. It may take several minutes for the
deployment to run.
4. To verify your application added the new IoT hub, visit the Azure portal and view your list of resources.
Alternatively, use the Get-AzureRmResource PowerShell cmdlet.

NOTE
This example application adds an S1 Standard IoT Hub for which you are billed. You can delete the IoT hub through the
Azure portal or by using the Remove-AzureRmResource PowerShell cmdlet when you are finished.

Next steps
Now you have deployed an IoT hub using an Azure Resource Manager template with a C# program, you may
want to explore further:
Read about the capabilities of the IoT Hub resource provider REST API.
Read Azure Resource Manager overview to learn more about the capabilities of Azure Resource Manager.
To learn more about developing for IoT Hub, see the following articles:
Introduction to C SDK
Azure IoT SDKs
To further explore the capabilities of IoT Hub, see:
Deploying AI to edge devices with Azure IoT Edge
Configure IoT Hub file uploads using the Azure
portal
5/29/2018 • 1 min to read • Edit Online

File upload
To use the file upload functionality in IoT Hub, you must first associate an Azure Storage account with your hub.
Select File upload to display a list of file upload properties for the IoT hub that is being modified.

Storage container: Use the Azure portal to select a blob container in an Azure Storage account in your current
Azure subscription to associate with your IoT Hub. If necessary, you can create an Azure Storage account on the
Storage accounts blade and blob container on the Containers blade. IoT Hub automatically generates SAS
URIs with write permissions to this blob container for devices to use when they upload files.
Receive notifications for uploaded files: Enable or disable file upload notifications via the toggle.
SAS TTL: This setting is the time-to-live of the SAS URIs returned to the device by IoT Hub. Set to one hour by
default but can be customized to other values using the slider.
File notification settings default TTL: The time-to-live of a file upload notification before it is expired. Set to
one day by default but can be customized to other values using the slider.
File notification maximum delivery count: The number of times the IoT Hub attempts to deliver a file
upload notification. Set to 10 by default but can be customized to other values using the slider.
Next steps
For more information about the file upload capabilities of IoT Hub, see Upload files from a device in the IoT Hub
developer guide.
Follow these links to learn more about managing Azure IoT Hub:
Bulk manage IoT devices
IoT Hub metrics
Operations monitoring
To further explore the capabilities of IoT Hub, see:
IoT Hub developer guide
Deploying AI to edge devices with Azure IoT Edge
Secure your IoT solution from the ground up
Configure IoT Hub file uploads using PowerShell
5/29/2018 • 3 min to read • Edit Online

To use the file upload functionality in IoT Hub, you must first associate an Azure storage account with your IoT
hub. You can use an existing storage account or create a new one.
To complete this tutorial, you need the following:
An active Azure account. If you don't have an account, you can create a free account in just a couple of minutes.
Azure PowerShell cmdlets.
An Azure IoT hub. If you don't have an IoT hub, you can use the New -AzureRmIoTHub cmdlet to create one or
use the portal to Create an IoT hub.
An Azure storage account. If you don't have an Azure storage account, you can use the Azure Storage
PowerShell cmdlets to create one or use the portal to Create a storage account.

Sign in and set your Azure account


Sign in to your Azure account and select your subscription.
1. At the PowerShell prompt, run the Connect-AzureRmAccount cmdlet:

Connect-AzureRmAccount

2. If you have multiple Azure subscriptions, signing in to Azure grants you access to all the Azure
subscriptions associated with your credentials. Use the following command to list the Azure subscriptions
available for you to use:

Get-AzureRMSubscription

Use the following command to select subscription that you want to use to run the commands to manage
your IoT hub. You can use either the subscription name or ID from the output of the previous command:

Select-AzureRMSubscription `
-SubscriptionName "{your subscription name}"

Retrieve your storage account details


The following steps assume that you created your storage account using the Resource Manager deployment
model, and not the Classic deployment model.
To configure file uploads from your devices, you need the connection string for an Azure storage account. The
storage account must be in the same subscription as your IoT hub. You also need the name of a blob container in
the storage account. Use the following command to retrieve your storage account keys:

Get-AzureRmStorageAccountKey `
-Name {your storage account name} `
-ResourceGroupName {your storage account resource group}

Make a note of the key1 storage account key value. You need it in the following steps.
You can either use an existing blob container for your file uploads or create new one:
To list the existing blob containers in your storage account, use the following commands:

$ctx = New-AzureStorageContext `
-StorageAccountName {your storage account name} `
-StorageAccountKey {your storage account key}
Get-AzureStorageContainer -Context $ctx

To create a blob container in your storage account, use the following commands:

$ctx = New-AzureStorageContext `
-StorageAccountName {your storage account name} `
-StorageAccountKey {your storage account key}
New-AzureStorageContainer `
-Name {your new container name} `
-Permission Off `
-Context $ctx

Configure your IoT hub


You can now configure your IoT hub to enable file upload functionality using your storage account details.
The configuration requires the following values:
Storage container: A blob container in an Azure storage account in your current Azure subscription to associate
with your IoT hub. You retrieved the necessary storage account information in the preceding section. IoT Hub
automatically generates SAS URIs with write permissions to this blob container for devices to use when they
upload files.
Receive notifications for uploaded files: Enable or disable file upload notifications.
SAS TTL: This setting is the time-to-live of the SAS URIs returned to the device by IoT Hub. Set to one hour by
default.
File notification settings default TTL: The time-to-live of a file upload notification before it is expired. Set to
one day by default.
File notification maximum delivery count: The number of times the IoT Hub attempts to deliver a file upload
notification. Set to 10 by default.
Use the following PowerShell cmdlet to configure the file upload settings on your IoT hub:

Set-AzureRmIotHub `
-ResourceGroupName "{your iot hub resource group}" `
-Name "{your iot hub name}" `
-FileUploadNotificationTtl "01:00:00" `
-FileUploadSasUriTtl "01:00:00" `
-EnableFileUploadNotifications $true `
-FileUploadStorageConnectionString "DefaultEndpointsProtocol=https;AccountName={your storage account
name};AccountKey={your storage account key};EndpointSuffix=core.windows.net" `
-FileUploadContainerName "{your blob container name}" `
-FileUploadNotificationMaxDeliveryCount 10

Next steps
For more information about the file upload capabilities of IoT Hub, see Upload files from a device.
Follow these links to learn more about managing Azure IoT Hub:
Bulk manage IoT devices
IoT Hub metrics
Operations monitoring
To further explore the capabilities of IoT Hub, see:
IoT Hub developer guide
Deploying AI to edge devices with Azure IoT Edge
Secure your IoT solution from the ground up
Configure IoT Hub file uploads using Azure CLI
5/29/2018 • 4 min to read • Edit Online

To use the file upload functionality in IoT Hub, you must first associate an Azure Storage account with your IoT
hub. You can use an existing storage account or create a new one.
To complete this tutorial, you need the following:
An active Azure account. If you don't have an account, you can create a free account in just a couple of minutes.
Azure CLI 2.0.
An Azure IoT hub. If you don't have an IoT hub, you can use the az iot hub create command to create one or
use the portal to [Create an IoT hub][lnk-portal-hub].
An Azure Storage account. If you don't have an Azure Storage account, you can use the Azure CLI 2.0 -
Manage storage accounts to create one or use the portal to Create a storage account.

Sign in and set your Azure account


Sign in to your Azure account and select your subscription.
1. At the command prompt, run the login command:

az login

Follow the instructions to authenticate using the code and sign in to your Azure account through a web
browser.
2. If you have multiple Azure subscriptions, signing in to Azure grants you access to all the Azure accounts
associated with your credentials. Use the following command to list the Azure accounts available for you to
use:

az account list

Use the following command to select subscription that you want to use to run the commands to create your
IoT hub. You can use either the subscription name or ID from the output of the previous command:

az account set --subscription {your subscription name or id}

Retrieve your storage account details


The following steps assume that you created your storage account using the Resource Manager deployment
model, and not the Classic deployment model.
To configure file uploads from your devices, you need the connection string for an Azure storage account. The
storage account must be in the same subscription as your IoT hub. You also need the name of a blob container in
the storage account. Use the following command to retrieve your storage account keys:

az storage account show-connection-string --name {your storage account name} --resource-group {your storage
account resource group}
Make a note of the connectionString value. You need it in the following steps.
You can either use an existing blob container for your file uploads or create new one:
To list the existing blob containers in your storage account, use the following command:

az storage container list --connection-string "{your storage account connection string}"

To create a blob container in your storage account, use the following command:

az storage container create --name {container name} --connection-string "{your storage account
connection string}"

File upload
You can now configure your IoT hub to enable file upload functionality using your storage account details.
The configuration requires the following values:
Storage container: A blob container in an Azure storage account in your current Azure subscription to associate
with your IoT hub. You retrieved the necessary storage account information in the preceding section. IoT Hub
automatically generates SAS URIs with write permissions to this blob container for devices to use when they
upload files.
Receive notifications for uploaded files: Enable or disable file upload notifications.
SAS TTL: This setting is the time-to-live of the SAS URIs returned to the device by IoT Hub. Set to one hour by
default.
File notification settings default TTL: The time-to-live of a file upload notification before it is expired. Set to
one day by default.
File notification maximum delivery count: The number of times the IoT Hub attempts to deliver a file upload
notification. Set to 10 by default.
Use the following Azure CLI commands to configure the file upload settings on your IoT hub:
In a bash shell use:

az iot hub update --name {your iot hub name} --set properties.storageEndpoints.'$default'.connectionString="
{your storage account connection string}"
az iot hub update --name {your iot hub name} --set properties.storageEndpoints.'$default'.containerName="{your
storage container name}"
az iot hub update --name {your iot hub name} --set
properties.storageEndpoints.'$default'.sasTtlAsIso8601=PT1H0M0S

az iot hub update --name {your iot hub name} --set properties.enableFileUploadNotifications=true
az iot hub update --name {your iot hub name} --set
properties.messagingEndpoints.fileNotifications.maxDeliveryCount=10
az iot hub update --name {your iot hub name} --set
properties.messagingEndpoints.fileNotifications.ttlAsIso8601=PT1H0M0S

At a Windows command prompt use:


az iot hub update --name {your iot hub name} --set "properties.storageEndpoints.$default.connectionString="
{your storage account connection string}""
az iot hub update --name {your iot hub name} --set "properties.storageEndpoints.$default.containerName="{your
storage container name}""
az iot hub update --name {your iot hub name} --set
"properties.storageEndpoints.$default.sasTtlAsIso8601=PT1H0M0S"

az iot hub update --name {your iot hub name} --set properties.enableFileUploadNotifications=true
az iot hub update --name {your iot hub name} --set
properties.messagingEndpoints.fileNotifications.maxDeliveryCount=10
az iot hub update --name {your iot hub name} --set
properties.messagingEndpoints.fileNotifications.ttlAsIso8601=PT1H0M0S

You can review the file upload configuration on your IoT hub using the following command:

az iot hub show --name {your iot hub name}

Next steps
For more information about the file upload capabilities of IoT Hub, see Upload files from a device.
Follow these links to learn more about managing Azure IoT Hub:
Bulk manage IoT devices
IoT Hub metrics
Operations monitoring
To further explore the capabilities of IoT Hub, see:
IoT Hub developer guide
Deploying AI to edge devices with Azure IoT Edge
Secure your IoT solution from the ground up
Monitor the health of Azure IoT Hub and diagnose
problems quickly
6/7/2018 • 8 min to read • Edit Online

Businesses that implement Azure IoT Hub expect reliable performance from their resources. To help you maintain
a close watch on your operations, IoT Hub is fully integrated with Azure Monitor and Azure Resource Health.
These two services work in tandem to provide you with the data you need to keep your IoT solutions up and
running in a healthy state.
Azure Monitor is a single source of monitoring and logging for all your Azure services. You can send the
diagnostic logs that Azure Monitor generates to Log Analytics, Event Hubs, or Azure Storage for custom
processing. Azure Monitor's metrics and diagnostics settings give you visibility into the performance of your
resources. Continue reading this article to learn how to Use Azure Monitor with your IoT hub.

IMPORTANT
The events emitted by the IoT Hub service using Azure Monitor diagnostic logs are not guaranteed to be reliable or
ordered. Some events might be lost or delivered out of order. Diagnostic logs also aren't meant to be real-time, and it may
take several minutes for events to be logged to your choice of destination.

Azure Resource Health helps you diagnose and get support when an Azure issues impacts your resources. A
personalized dashboard provides current and past health status for your IoT Hubs. Continue reading this article to
learn how to Use Azure Resource Health with your IoT hub.
In addition to integrating with these two services, IoT Hub also provides its own metrics that you can use to
understand the state of your IoT resources. To learn more, see Understand IoT Hub metrics.

Use Azure Monitor


Azure Monitor provides resource-level diagnostics information, which means that you can monitor operations
that take place within your IoT hub.
Azure Monitor's diagnostics settings replaces the IoT Hub operations monitor. If you currently use operations
monitoring, you should migrate your workflows. For more information, see Migrate from operations monitoring
to diagnostics settings.
To learn more about the specific metrics and events that Azure Monitor watches, see Supported metrics with
Azure Monitor and Supported services, schemas, and categories for Azure Diagnostic Logs.
Enable logging with diagnostics settings
1. Sign in to the Azure portal and navigate to your IoT Hub.
2. Select Diagnostics settings.
3. Select Turn on diagnostics.
4. Give the diagnostic settings a name.
5. Choose where you want to send the logs. You can select any combination of the three options:
Archive to a storage account
Stream to an event hub
Send to Log Analytics
6. Choose which operations you want to monitor, and enable logs for those operations. The operations that
diagnostic settings can report on are:
Connections
Device telemetry
Cloud-to-device messages
Device identity operations
File uploads
Message routing
Cloud-to-device twin operations
Device-to-cloud twin operations
Twin operations
Job operations
Direct methods
7. Save the new settings.
If you want to turn on diagnostics settings with PowerShell, use the following code:

Connect-AzureRmAccount
Select-AzureRmSubscription -SubscriptionName <subscription that includes your IoT Hub>
Set-AzureRmDiagnosticSetting -ResourceId <your resource Id> -ServiceBusRuleId <your service bus rule Id> -
Enabled $true

New settings take effect in about 10 minutes. After that, logs appear in the configured archival target on the
Diagnostics settings blade. For more information about configuring diagnostics, see Collect and consume log
data from your azure resources.
Understand the logs
Azure Monitor tracks different operations that occur in IoT Hub. Each category has a schema that defines how
events in that category are reported.
Connections
The connections category tracks device connect and disconnect events from an IoT hub as well as errors. Tracking
this category is useful for identifying unauthorized connection attempts and for tracking when a connection is lost
for devices in areas of poor connectivity.

{
"time": "UTC timestamp",
"resourceId": "Resource Id",
"operationName": "deviceConnect",
"category": "Connections",
"level": "Information",
"properties": "{\"deviceId\":\"<deviceId>\",\"protocol\":\"<protocol>\",\"authType\":\"
{\\\"scope\\\":\\\"device\\\",\\\"type\\\":\\\"sas\\\",\\\"issuer\\\":\\\"iothub\\\",\\\"acceptingIpFilterRule
\\\":null}\",\"maskedIpAddress\":\"<maskedIpAddress>\"}",
"location": "Resource location"
}

Cloud-to-device commands
The cloud-to-device commands category tracks errors that occur at the IoT hub and are related to the cloud-to-
device message pipeline. This category includes errors that occur when sending cloud-to-device messages (such
as unauthorized sender), receiving cloud-to-device messages (such as delivery count exceeded), and receiving
cloud-to-device message feedback (such as feedback expired). This category does not catch errors from a device
that improperly handles a cloud-to-device message if the cloud-to-device message was delivered successfully.

{
"time": " UTC timestamp",
"resourceId": "Resource Id",
"operationName": "messageExpired",
"category": "C2DCommands",
"level": "Error",
"resultType": "Event status",
"resultDescription": "MessageDescription",
"properties": "{\"deviceId\":\"<deviceId>\",\"messageId\":\"<messageId>\",\"messageSizeInBytes\":\"
<messageSize>\",\"protocol\":\"Amqp\",\"deliveryAcknowledgement\":\"<None, NegativeOnly, PositiveOnly,
Full>\",\"deliveryCount\":\"0\",\"expiryTime\":\"<timestamp>\",\"timeInSystem\":\"<timeInSystem>\",\"ttl\":
<ttl>, \"EventProcessedUtcTime\":\"<UTC timestamp>\",\"EventEnqueuedUtcTime\":\"<UTC timestamp>\",
\"maskedIpAddresss\": \"<maskedIpAddress>\", \"statusCode\": \"4XX\"}",
"location": "Resource location"
}

Device identity operations


The device identity operations category tracks errors that occur when you attempt to create, update, or delete an
entry in your IoT hub's identity registry. Tracking this category is useful for provisioning scenarios.

{
"time": "UTC timestamp",
"resourceId": "Resource Id",
"operationName": "get",
"category": "DeviceIdentityOperations",
"level": "Error",
"resultType": "Event status",
"resultDescription": "MessageDescription",
"properties": "{\"maskedIpAddress\":\"<maskedIpAddress>\",\"deviceId\":\"<deviceId>\",
\"statusCode\":\"4XX\"}",
"location": "Resource location"
}

Routes
The message routing category tracks errors that occur during message route evaluation and endpoint health as
perceived by IoT Hub. This category includes events such as when a rule evaluates to "undefined", when IoT Hub
marks an endpoint as dead, and any other errors received from an endpoint. This category does not include
specific errors about the messages themselves (such as device throttling errors), which are reported under the
"device telemetry" category.

{
"time": "UTC timestamp",
"resourceId": "Resource Id",
"operationName": "endpointUnhealthy",
"category": "Routes",
"level": "Error",
"properties": "{\"deviceId\": \"<deviceId>\",\"endpointName\":\"<endpointName>\",\"messageId\":
<messageId>,\"details\":\"<errorDetails>\",\"routeName\": \"<routeName>\"}",
"location": "Resource location"
}

Device telemetry
The device telemetry category tracks errors that occur at the IoT hub and are related to the telemetry pipeline.
This category includes errors that occur when sending telemetry events (such as throttling) and receiving
telemetry events (such as unauthorized reader). This category cannot catch errors caused by code running on the
device itself.

{
"time": "UTC timestamp",
"resourceId": "Resource Id",
"operationName": "ingress",
"category": "DeviceTelemetry",
"level": "Error",
"resultType": "Event status",
"resultDescription": "MessageDescription",
"properties": "{\"deviceId\":\"<deviceId>\",\"batching\":\"0\",\"messageSizeInBytes\":\"
<messageSizeInBytes>\",\"EventProcessedUtcTime\":\"<UTC timestamp>\",\"EventEnqueuedUtcTime\":\"<UTC
timestamp>\",\"partitionId\":\"1\"}",
"location": "Resource location"
}

File upload operations


The file upload category tracks errors that occur at the IoT hub and are related to file upload functionality. This
category includes:
Errors that occur with the SAS URI, such as when it expires before a device notifies the hub of a completed
upload.
Failed uploads reported by the device.
Errors that occur when a file is not found in storage during IoT Hub notification message creation.
This category cannot catch errors that directly occur while the device is uploading a file to storage.
{
"time": "UTC timestamp",
"resourceId": "Resource Id",
"operationName": "ingress",
"category": "FileUploadOperations",
"level": "Error",
"resultType": "Event status",
"resultDescription": "MessageDescription",
"durationMs": "1",
"properties": "{\"deviceId\":\"<deviceId>\",\"protocol\":\"<protocol>\",\"authType\":\"
{\\\"scope\\\":\\\"device\\\",\\\"type\\\":\\\"sas\\\",\\\"issuer\\\":\\\"iothub\\\",\\\"acceptingIpFilterRule
\\\":null}\",\"blobUri\":\"http//bloburi.com\"}",
"location": "Resource location"
}

Cloud-to-device twin operations


The cloud-to-device twin operations category tracks service-initiated events on device twins. These operations can
include get twin, update reported properties, and subscribe to desired properties

{
"time": "UTC timestamp",
"resourceId": "Resource Id",
"operationName": "read",
"category": "C2DTwinOperations",
"level": "Information",
"durationMs": "1",
"properties": "{\"deviceId\":\"<deviceId>\",\"sdkVersion\":\"<sdkVersion>\",\"messageSize\":\"
<messageSize>\"}",
"location": "Resource location"
}

Device-to-cloud twin operations


The device-to-cloud twin operations category tracks device-initiated events on device twins. These operations can
include get twin, update or replace tags, and update or replace desired properties.

{
"time": "UTC timestamp",
"resourceId": "Resource Id",
"operationName": "update",
"category": "D2CTwinOperations",
"level": "Information",
"durationMs": "1",
"properties": "{\"deviceId\":\"<deviceId>\",\"protocol\":\"<protocol>\",\"authenticationType\":\"
{\\\"scope\\\":\\\"device\\\",\\\"type\\\":\\\"sas\\\",\\\"issuer\\\":\\\"iothub\\\",\\\"acceptingIpFilterRule
\\\":null}\"}",
"location": "Resource location"
}

Twin queries
The twin queries category reports on query requests for device twins that are initiated in the cloud.
{
"time": "UTC timestamp",
"resourceId": "Resource Id",
"operationName": "query",
"category": "TwinQueries",
"level": "Information",
"durationMs": "1",
"properties": "{\"query\":\"<twin query>\",\"sdkVersion\":\"<sdkVersion>\",\"messageSize\":\"
<messageSize>\",\"pageSize\":\"<pageSize>\", \"continuation\":\"<true, false>\", \"resultSize\":\"
<resultSize>\"}",
"location": "Resource location"
}

Jobs operations
The jobs operations category reports on job requests to update device twins or invoke direct methods on multiple
devices. These requests are initiated in the cloud.

{
"time": "UTC timestamp",
"resourceId": "Resource Id",
"operationName": "jobCompleted",
"category": "JobsOperations",
"level": "Information",
"durationMs": "1",
"properties": "{\"jobId\":\"<jobId>\", \"sdkVersion\": \"<sdkVersion>\",\"messageSize\":
<messageSize>,\"filter\":\"DeviceId IN ['1414ded9-b445-414d-89b9-
e48e8c6285d5']\",\"startTimeUtc\":\"Wednesday, September 13, 2017\",\"duration\":\"0\"}",
"location": "Resource location"
}

Direct Methods
The direct methods category tracks request-reponse interactions sent to individual devices. These requests are
initiated in the cloud.

{
"time": "UTC timestamp",
"resourceId": "Resource Id",
"operationName": "send",
"category": "DirectMethods",
"level": "Information",
"durationMs": "1",
"properties": "{\"deviceId\":\"<deviceId>\", \"RequestSize\": 1, \"ResponseSize\": 1, \"sdkVersion\":
\"2017-07-11\"}",
"location": "Resource location"
}

Read logs from Azure Event Hubs


After you set up event logging through diagnostics settings, you can create applications that read out the logs so
that you can take action based on the information in them. This sample code retrieves logs from an event hub:
class Program
{
static string connectionString = "{your AMS eventhub endpoint connection string}";
static string monitoringEndpointName = "{your AMS event hub endpoint name}";
static EventHubClient eventHubClient;
//This is the Diagnostic Settings schema
class AzureMonitorDiagnosticLog
{
string time { get; set; }
string resourceId { get; set; }
string operationName { get; set; }
string category { get; set; }
string level { get; set; }
string resultType { get; set; }
string resultDescription { get; set; }
string durationMs { get; set; }
string callerIpAddress { get; set; }
string correlationId { get; set; }
string identity { get; set; }
string location { get; set; }
Dictionary<string, string> properties { get; set; }
};
static void Main(string[] args)
{
Console.WriteLine("Monitoring. Press Enter key to exit.\n");
eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, monitoringEndpointName);
var d2cPartitions = eventHubClient.GetRuntimeInformation().PartitionIds;
CancellationTokenSource cts = new CancellationTokenSource();
var tasks = new List<Task>();
foreach (string partition in d2cPartitions)
{
tasks.Add(ReceiveMessagesFromDeviceAsync(partition, cts.Token));
}
Console.ReadLine();
Console.WriteLine("Exiting...");
cts.Cancel();
Task.WaitAll(tasks.ToArray());
}
private static async Task ReceiveMessagesFromDeviceAsync(string partition, CancellationToken ct)
{
var eventHubReceiver = eventHubClient.GetDefaultConsumerGroup().CreateReceiver(partition,
DateTime.UtcNow);
while (true)
{
if (ct.IsCancellationRequested)
{
await eventHubReceiver.CloseAsync();
break;
}
EventData eventData = await eventHubReceiver.ReceiveAsync(new TimeSpan(0,0,10));
if (eventData != null)
{
string data = Encoding.UTF8.GetString(eventData.GetBytes());
Console.WriteLine("Message received. Partition: {0} Data: '{1}'", partition, data);
var deserializer = new JavaScriptSerializer();
//deserialize json data to azure monitor object
AzureMonitorDiagnosticLog message = new
JavaScriptSerializer().Deserialize<AzureMonitorDiagnosticLog>(result);

}
}
}
}

Use Azure Resource Health


Use Azure Resource Health to monitor whether your IoT hub is up and running. You can also learn whether a
regional outage is impacting the health of your IoT hub. To understand specific details about the health state of
your Azure IoT Hub, we recommend that you Use Azure Monitor.
Azure IoT Hub indicates health at a regional level. If there a regional outage impacting your IoT hub, the health
status shows as Unknown. To learn more about the specific health checks that Azure Resource Health performs,
see Resource types and health checks in Azure resource health.
To check the health of your IoT hubs, follow these steps:
1. Sign in to the Azure portal.
2. Navigate to Service Health > Resource health.
3. From the drop-down boxes, select your subscription and IoT Hub.
To learn more about how to interpret health data, see Azure resource health overview

Next steps
Understand IoT Hub metrics
IoT remote monitoring and notifications with Azure Logic Apps connecting your IoT hub and mailbox
Migrate your IoT Hub from operations monitoring to
diagnostics settings
5/30/2018 • 2 min to read • Edit Online

Customers using operations monitoring to track the status of operations in IoT Hub can migrate that workflow to
Azure diagnostics settings, a feature of Azure Monitor. Diagnostics settings supply resource-level diagnostic
information for many Azure services.
The operations monitoring functionality of IoT Hub is deprecated, and will be removed in the future. This article
provides steps to move your workloads from operations monitoring to diagnostics settings. For more information
about the deprecation timeline, see Monitor your Azure IoT solutions with Azure Monitor and Azure Resource
Health.

Update IoT Hub


To update your IoT Hub in the Azure portal, first turn on diagnostics settings, then turn off operations monitoring.
Enable logging with diagnostics settings
1. Sign in to the Azure portal and navigate to your IoT Hub.
2. Select Diagnostics settings.
3. Select Turn on diagnostics.

4. Give the diagnostic settings a name.


5. Choose where you want to send the logs. You can select any combination of the three options:
Archive to a storage account
Stream to an event hub
Send to Log Analytics
6. Choose which operations you want to monitor, and enable logs for those operations. The operations that
diagnostic settings can report on are:
Connections
Device telemetry
Cloud-to-device messages
Device identity operations
File uploads
Message routing
Cloud-to-device twin operations
Device-to-cloud twin operations
Twin operations
Job operations
Direct methods
7. Save the new settings.
If you want to turn on diagnostics settings with PowerShell, use the following code:

Connect-AzureRmAccount
Select-AzureRmSubscription -SubscriptionName <subscription that includes your IoT Hub>
Set-AzureRmDiagnosticSetting -ResourceId <your resource Id> -ServiceBusRuleId <your service bus rule Id> -
Enabled $true

New settings take effect in about 10 minutes. After that, logs appear in the configured archival target on the
Diagnostics settings blade. For more information about configuring diagnostics, see Collect and consume log
data from your azure resources.
Turn off operations monitoring
Once you have tested the new diagnostics settings on your workflow, you can turn off the operations monitoring
feature.
1. In your IoT Hub menu, select Operations monitoring.
2. Under each monitoring category, select None.
3. Save the operations monitoring changes.

Update applications that use operations monitoring


The schemas for operations monitoring and diagnostics settings vary slightly. It's important that you update the
applications that use operations monitoring today to map to the schema used by diagnostics settings.
Also, diagnostics settings offers tracking for five new categories. After you update applications for the existing
schema, add the new categories as well:
Cloud-to-device twin operations
Device-to-cloud twin operations
Twin queries
Jobs operations
Direct Methods
For the specific schema structures, see Understand the schema for diagnostics settings.

Next steps
Monitor the health of Azure IoT Hub and diagnose problems quickly
IoT Hub operations monitoring
5/29/2018 • 6 min to read • Edit Online

IoT Hub operations monitoring enables you to monitor the status of operations on your IoT hub in real time.
IoT Hub tracks events across several categories of operations. You can opt into sending events from one or
more categories to an endpoint of your IoT hub for processing. You can monitor the data for errors or set up
more complex processing based on data patterns.

NOTE
IoT Hub operations monitoring is deprecated and will be removed from IoT Hub on October 10, 2018. For monitoring
the operations and health of IoT Hub, see Monitor the health of Azure IoT Hub and diagnose problems quickly. For more
information about the deprecation timeline, see Monitor your Azure IoT solutions with Azure Monitor and Azure
Resource Health.

IoT Hub monitors six categories of events:


Device identity operations
Device telemetry
Cloud-to-device messages
Connections
File uploads
Message routing

IMPORTANT
IoT Hub operations monitoring does not guarantee reliable or ordered delivery of events. Depending on IoT Hub
underlying infrastructure, some events might be lost or delivered out of order. Use operations monitoring to generate
alerts based on error signals such as failed connection attempts, or high-frequency disconnections for specific devices.
You should not rely on operations monitoring events to create a consistent store for device state, e.g. a store tracking
connected or disconnected state of a device.

How to enable operations monitoring


1. Create an IoT hub. You can find instructions on how to create an IoT hub in the Get Started guide.
2. Open the blade of your IoT hub. From there, click Operations monitoring.
3. Select the monitoring categories you wish to monitor, and then click Save. The events are available for
reading from the Event Hub-compatible endpoint listed in Monitoring settings. The IoT Hub endpoint
is called messages/operationsmonitoringevents .
NOTE
Selecting Verbose monitoring for the Connections category causes IoT Hub to generate additional diagnostics
messages. For all other categories, the Verbose setting changes the quantity of information IoT Hub includes in each
error message.

Event categories and how to use them


Each operations monitoring category tracks a different type of interaction with IoT Hub, and each monitoring
category has a schema that defines how events in that category are structured.
Device identity operations
The device identity operations category tracks errors that occur when you attempt to create, update, or delete
an entry in your IoT hub's identity registry. Tracking this category is useful for provisioning scenarios.

{
"time": "UTC timestamp",
"operationName": "create",
"category": "DeviceIdentityOperations",
"level": "Error",
"statusCode": 4XX,
"statusDescription": "MessageDescription",
"deviceId": "device-ID",
"durationMs": 1234,
"userAgent": "userAgent",
"sharedAccessPolicy": "accessPolicy"
}

Device telemetry
The device telemetry category tracks errors that occur at the IoT hub and are related to the telemetry pipeline.
This category includes errors that occur when sending telemetry events (such as throttling) and receiving
telemetry events (such as unauthorized reader). This category cannot catch errors caused by code running on
the device itself.

{
"messageSizeInBytes": 1234,
"batching": 0,
"protocol": "Amqp",
"authType": "{\"scope\":\"device\",\"type\":\"sas\",\"issuer\":\"iothub\"}",
"time": "UTC timestamp",
"operationName": "ingress",
"category": "DeviceTelemetry",
"level": "Error",
"statusCode": 4XX,
"statusType": 4XX001,
"statusDescription": "MessageDescription",
"deviceId": "device-ID",
"EventProcessedUtcTime": "UTC timestamp",
"PartitionId": 1,
"EventEnqueuedUtcTime": "UTC timestamp"
}

Cloud-to -device commands


The cloud-to-device commands category tracks errors that occur at the IoT hub and are related to the cloud-to-
device message pipeline. This category includes errors that occur when sending cloud-to-device messages
(such as unauthorized sender), receiving cloud-to-device messages (such as delivery count exceeded), and
receiving cloud-to-device message feedback (such as feedback expired). This category does not catch errors
from a device that improperly handles a cloud-to-device message if the cloud-to-device message was delivered
successfully.
{
"messageSizeInBytes": 1234,
"authType": "{\"scope\":\"hub\",\"type\":\"sas\",\"issuer\":\"iothub\"}",
"deliveryAcknowledgement": 0,
"protocol": "Amqp",
"time": " UTC timestamp",
"operationName": "ingress",
"category": "C2DCommands",
"level": "Error",
"statusCode": 4XX,
"statusType": 4XX001,
"statusDescription": "MessageDescription",
"deviceId": "device-ID",
"EventProcessedUtcTime": "UTC timestamp",
"PartitionId": 1,
"EventEnqueuedUtcTime": "UTC timestamp"
}

Connections
The connections category tracks errors that occur when devices connect or disconnect from an IoT hub.
Tracking this category is useful for identifying unauthorized connection attempts and for tracking when a
connection is lost for devices in areas of poor connectivity.

{
"durationMs": 1234,
"authType": "{\"scope\":\"hub\",\"type\":\"sas\",\"issuer\":\"iothub\"}",
"protocol": "Amqp",
"time": " UTC timestamp",
"operationName": "deviceConnect",
"category": "Connections",
"level": "Error",
"statusCode": 4XX,
"statusType": 4XX001,
"statusDescription": "MessageDescription",
"deviceId": "device-ID"
}

File uploads
The file upload category tracks errors that occur at the IoT hub and are related to file upload functionality. This
category includes:
Errors that occur with the SAS URI, such as when it expires before a device notifies the hub of a completed
upload.
Failed uploads reported by the device.
Errors that occur when a file is not found in storage during IoT Hub notification message creation.
This category cannot catch errors that directly occur while the device is uploading a file to storage.
{
"authType": "{\"scope\":\"hub\",\"type\":\"sas\",\"issuer\":\"iothub\"}",
"protocol": "HTTP",
"time": " UTC timestamp",
"operationName": "ingress",
"category": "fileUpload",
"level": "Error",
"statusCode": 4XX,
"statusType": 4XX001,
"statusDescription": "MessageDescription",
"deviceId": "device-ID",
"blobUri": "http//bloburi.com",
"durationMs": 1234
}

Message routing
The message routing category tracks errors that occur during message route evaluation and endpoint health as
perceived by IoT Hub. This category includes events such as when a rule evaluates to "undefined", when IoT
Hub marks an endpoint as dead, and any other errors received from an endpoint. This category does not
include specific errors about the messages themselves (such as device throttling errors), which are reported
under the "device telemetry" category.

{
"messageSizeInBytes": 1234,
"time": "UTC timestamp",
"operationName": "ingress",
"category": "routes",
"level": "Error",
"deviceId": "device-ID",
"messageId": "ID of message",
"routeName": "myroute",
"endpointName": "myendpoint",
"details": "ExternalEndpointDisabled"
}

View events
You can use the iothub -explorer tool to quickly test that your IoT hub is generating monitoring events. To install
the tool, see the instructions in the iothub-explorer GitHub repository.
1. Make sure the Connections monitoring category is set to Verbose in the portal.
2. At a command-prompt, run the following command to read from the monitoring endpoint:

iothub-explorer monitor-ops --login {your iothubowner connection string}

3. In another command-prompt, run the following command to simulate a device sending device-to-cloud
messages:

iothub-explorer simulate-device {your device name} --send "My test message" --login {your
iothubowner connection string}

4. The first command-prompt shows the monitoring events as the simulated device connects to your IoT
hub.

Connect to the monitoring endpoint


The monitoring endpoint on your IoT hub is an Event Hub-compatible endpoint. You can use any mechanism
that works with Event Hubs to read monitoring messages from this endpoint. The following sample creates a
basic reader that is not suitable for a high throughput deployment. For more information about how to process
messages from Event Hubs, see the Get Started with Event Hubs tutorial.
To connect to the monitoring endpoint, you need a connection string and the endpoint name. The following
steps show you how to find the necessary values in the portal:
1. In the portal, navigate to your IoT Hub resource blade.
2. Choose Operations monitoring, and make a note of the Event Hub-compatible name and Event
Hub-compatible endpoint values:

3. Choose Shared access policies, then choose service. Make a note of the Primary key value:
The following C# code sample is taken from a Visual Studio Windows Classic Desktop C# console app. The
project has the WindowsAzure.ServiceBus NuGet package installed.
Replace the connection string placeholder with a connection string that uses the Event Hub-
compatible endpoint and service Primary key values you noted previously as shown in the following
example:

"Endpoint={your Event Hub-compatible endpoint};SharedAccessKeyName=service;SharedAccessKey={your


service primary key value}"

Replace the monitoring endpoint name placeholder with the Event Hub-compatible name value you
noted previously.
class Program
{
static string connectionString = "{your monitoring endpoint connection string}";
static string monitoringEndpointName = "{your monitoring endpoint name}";
static EventHubClient eventHubClient;

static void Main(string[] args)


{
Console.WriteLine("Monitoring. Press Enter key to exit.\n");

eventHubClient = EventHubClient.CreateFromConnectionString(connectionString,
monitoringEndpointName);
var d2cPartitions = eventHubClient.GetRuntimeInformation().PartitionIds;
CancellationTokenSource cts = new CancellationTokenSource();
var tasks = new List<Task>();

foreach (string partition in d2cPartitions)


{
tasks.Add(ReceiveMessagesFromDeviceAsync(partition, cts.Token));
}

Console.ReadLine();
Console.WriteLine("Exiting...");
cts.Cancel();
Task.WaitAll(tasks.ToArray());
}

private static async Task ReceiveMessagesFromDeviceAsync(string partition, CancellationToken ct)


{
var eventHubReceiver = eventHubClient.GetDefaultConsumerGroup().CreateReceiver(partition,
DateTime.UtcNow);
while (true)
{
if (ct.IsCancellationRequested)
{
await eventHubReceiver.CloseAsync();
break;
}

EventData eventData = await eventHubReceiver.ReceiveAsync(new TimeSpan(0,0,10));

if (eventData != null)
{
string data = Encoding.UTF8.GetString(eventData.GetBytes());
Console.WriteLine("Message received. Partition: {0} Data: '{1}'", partition, data);
}
}
}
}

Next steps
To further explore the capabilities of IoT Hub, see:
IoT Hub developer guide
Deploying AI to edge devices with Azure IoT Edge
Azure IoT Hub get started with real devices
5/29/2018 • 1 min to read • Edit Online

You can use Azure IoT Hub and the Azure IoT device SDKs to build Internet of Things (IoT) solutions:
Azure IoT Hub is a fully managed service in the cloud that securely connects, monitors, and manages your IoT
devices. Use the Azure IoT Device SDKs to implement your IoT devices.
Use an IoT gateway in more complex IoT scenarios. For example, where you need to consider factors such as
legacy devices, bandwidth costs, security and privacy policies, or edge data processing. In these scenarios, use
Azure IoT Edge to implement a gateway that connects devices to your IoT hub.

What the How-to articles cover


These articles introduce you to Azure IoT Hub and the device SDKs. The articles cover common IoT scenarios to
demonstrate the capabilities of IoT Hub. The articles also illustrate how to combine IoT Hub with other Azure
services and tools to build more powerful IoT solutions. In the articles, you use real IoT devices.

Set up your device


Connect an IoT device or gateway to Azure IoT Hub:

IOT DEVICE PROGRAMMING LANGUAGE

Raspberry Pi Python, Node.js, C

IoT DevKit Arduino in VSCode

Intel Edison Node.js, C

Adafruit Feather HUZZAH ESP8266 Arduino

Sparkfun ESP8266 Thing Dev Arduino

Adafruit Feather M0 Arduino

Online device simulator Raspberry Pi (Node.js)

Extended IoT scenarios


Use other Azure services and tools. When you have connected your device to IoT Hub, you can explore additional
scenarios that use other Azure tools and services:

SCENARIO AZURE SERVICE OR TOOL

Manage IoT Hub messages iothub-explorer tool

Manage your IoT device Azure CLI 2.0 and the IoT extension

Save IoT Hub messages to Azure storage Azure table storage


SCENARIO AZURE SERVICE OR TOOL

Visualize sensor data Microsoft Power BI

Visualize sensor data Azure Web Apps

Forecast weather with sensor data Azure Machine Learning

Automatic anomaly detection and reaction Azure Logic Apps

Next steps
When you have completed these tutorials, you can further explore the capabilities of IoT Hub in the Developer
guide. You can find additional tutorials in the How To section.
Connect Raspberry Pi online simulator to Azure IoT
Hub (Node.js)
5/29/2018 • 4 min to read • Edit Online

In this tutorial, you begin by learning the basics of working with Raspberry Pi online simulator. You then learn
how to seamlessly connect the Pi simulator to the cloud by using Azure IoT Hub.
If you have physical devices, visit Connect Raspberry Pi to Azure IoT Hub to get started.

What you do
Learn the basics of Raspberry Pi online simulator.
Create an IoT hub.
Register a device for Pi in your IoT hub.
Run a sample application on Pi to send simulated sensor data to your IoT hub.
Connect simulated Raspberry Pi to an IoT hub that you create. Then you run a sample application with the
simulator to generate sensor data. Finally, you send the sensor data to your IoT hub.

What you learn


How to create an Azure IoT hub and get your new device connection string. If you don't have an Azure
account, create a free Azure trial account in just a few minutes.
How to work with Raspberry Pi online simulator.
How to send sensor data to your IoT hub.

Overview of Raspberry Pi web simulator


Click the button to launch Raspberry Pi online simulator.
STA RT RA SP B E RRY P I
S IM U L A T O R

There are three areas in the web simulator.


1. Assembly area - The default circuit is that a Pi connects with a BME280 sensor and an LED. The area is locked
in preview version so currently you cannot do customization.
2. Coding area - An online code editor for you to code with Raspberry Pi. The default sample application helps
to collect sensor data from BME280 sensor and sends to your Azure IoT Hub. The application is fully
compatible with real Pi devices.
3. Integrated console window - It shows the output of your code. At the top of this window, there are three
buttons.
Run - Run the application in the coding area.
Reset - Reset the coding area to the default sample application.
Fold/Expand - On the right side there is a button for you to fold/expand the console window.

NOTE
The Raspberry Pi web simulator is now available in preview version. We'd like to hear your voice in the Gitter Chatroom.
The source code is public on Github.

Create an IoT hub


1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
Now that you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub.
In your IoT hub navigation menu, open Shared access policies. Select the iothubowner policy, and then copy
the Connection string---primary key of your IoT hub. For more information, see Control access to IoT Hub.

NOTE
You do not need this iothubowner connection string for this set-up tutorial. However, you may need it for some of the
tutorials or different IoT scenarios after you complete this set-up.

Register a device in the IoT hub for your device


1. In your IoT hub navigation menu, open IoT devices, then click Add to register a device in your IoT hub.
2. Enter a Device ID for the new device. Device IDs are case sensitive.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.

3. Click Save.
4. After the device is created, open the device from the list in the IoT devices pane.
5. Copy the Connection string---primary key to use later.

Run a sample application on Pi web simulator


1. In coding area, make sure you are working on the default sample application. Replace the placeholder in
Line 15 with the Azure IoT hub device connection string.
2. Click Run or type npm start to run the application.

You should see the following output that shows the sensor data and the messages that are sent to your IoT hub

Next steps
You’ve run a sample application to collect sensor data and send it to your IoT hub.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Azure IoT Hub get started with physical devices
tutorials
5/29/2018 • 1 min to read • Edit Online

These tutorials introduce you to Azure IoT Hub and the device SDKs. The tutorials cover common IoT scenarios to
demonstrate the capabilities of IoT Hub. The tutorials also illustrate how to combine IoT Hub with other Azure
services and tools to build more powerful IoT solutions. The tutorials listed in the following table show you how to
create physical IoT devices.

IOT DEVICE PROGRAMMING LANGUAGE

Raspberry Pi Python, Node.js, C

IoT DevKit Arduino in VSCode

Intel Edison Node.js, C

Adafruit Feather HUZZAH ESP8266 Arduino

Sparkfun ESP8266 Thing Dev Arduino

Adafruit Feather M0 Arduino

Extended IoT scenarios


Use other Azure services and tools. When you have connected your device to IoT Hub, you can explore additional
scenarios that use other Azure tools and services:

SCENARIO AZURE SERVICE OR TOOL

Manage IoT Hub messages iothub-explorer tool

Manage your IoT device Azure CLI 2.0 and the IoT extension

Save IoT Hub messages to Azure storage Azure table storage

Visualize sensor data Microsoft Power BI

Visualize sensor data Azure Web Apps

Forecast weather with sensor data Azure Machine Learning

Automatic anomaly detection and reaction Azure Logic Apps

Next steps
When you have completed these tutorials, you can further explore the capabilities of IoT Hub in the Developer
guide. You can find additional tutorials in the How To section.
Connect Raspberry Pi to Azure IoT Hub (Python)
5/29/2018 • 9 min to read • Edit Online

In this tutorial, you begin by learning the basics of working with Raspberry Pi that's running Raspbian. You then
learn how to seamlessly connect your devices to the cloud by using Azure IoT Hub. For Windows 10 IoT Core
samples, go to the Windows Dev Center.
Don't have a kit yet? Try Raspberry Pi online simulator. Or buy a new kit here.

What you do
Create an IoT hub.
Register a device for Pi in your IoT hub.
Setup Raspberry Pi.
Run a sample application on Pi to send sensor data to your IoT hub.
Connect Raspberry Pi to an IoT hub that you create. Then you run a sample application on Pi to collect
temperature and humidity data from a BME280 sensor. Finally, you send the sensor data to your IoT hub.

What you learn


How to create an Azure IoT hub and get your new device connection string.
How to connect Pi with a BME280 sensor.
How to collect sensor data by running a sample application on Pi.
How to send sensor data to your IoT hub.

What you need

The Raspberry Pi 2 or Raspberry Pi 3 board.


An active Azure subscription. If you don't have an Azure account, create a free Azure trial account in just a few
minutes.
A monitor, a USB keyboard, and mouse that connect to Pi.
A Mac or a PC that is running Windows or Linux.
An Internet connection.
A 16 GB or above microSD card.
A USB -SD adapter or microSD card to burn the operating system image onto the microSD card.
A 5-volt 2-amp power supply with the 6-foot micro USB cable.
The following items are optional:
An assembled Adafruit BME280 temperature, pressure, and humidity sensor.
A breadboard.
6 F/M jumper wires.
A diffused 10-mm LED.

NOTE
These items are optional because the code sample support simulated sensor data.

Create an IoT hub


1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
Now that you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub.
In your IoT hub navigation menu, open Shared access policies. Select the iothubowner policy, and then copy
the Connection string---primary key of your IoT hub. For more information, see Control access to IoT Hub.

NOTE
You do not need this iothubowner connection string for this set-up tutorial. However, you may need it for some of the
tutorials or different IoT scenarios after you complete this set-up.
Register a device in the IoT hub for your device
1. In your IoT hub navigation menu, open IoT devices, then click Add to register a device in your IoT hub.

2. Enter a Device ID for the new device. Device IDs are case sensitive.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.
3. Click Save.
4. After the device is created, open the device from the list in the IoT devices pane.
5. Copy the Connection string---primary key to use later.

Set up Raspberry Pi
Install the Raspbian operating system for Pi
Prepare the microSD card for installation of the Raspbian image.
1. Download Raspbian.
a. Download Raspbian Jessie with Desktop (the .zip file).
b. Extract the Raspbian image to a folder on your computer.
2. Install Raspbian to the microSD card.
a. Download and install the Etcher SD card burner utility.
b. Run Etcher and select the Raspbian image that you extracted in step 1.
c. Select the microSD card drive. Note that Etcher may have already selected the correct drive.
d. Click Flash to install Raspbian to the microSD card.
e. Remove the microSD card from your computer when installation is complete. It's safe to remove the
microSD card directly because Etcher automatically ejects or unmounts the microSD card upon
completion.
f. Insert the microSD card into Pi.
Enable SSH and I2C
1. Connect Pi to the monitor, keyboard and mouse, start Pi and then log in Raspbian by using pi as the user
name and raspberry as the password.
2. Click the Raspberry icon > Preferences > Raspberry Pi Configuration.
3. On the Interfaces tab, set I2C and SSH to Enable, and then click OK. If you don't have physical sensors
and want to use simulated sensor data, this step is optional.

NOTE
To enable SSH and I2C, you can find more reference documents on raspberrypi.org and RASPI-CONFIG.

Connect the sensor to Pi


Use the breadboard and jumper wires to connect an LED and a BME280 to Pi as follows. If you don’t have the
sensor, skip this section.
The BME280 sensor can collect temperature and humidity data. And the LED will blink if there is a
communication between device and the cloud.
For sensor pins, use the following wiring:

START (SENSOR & LED) END (BOARD) CABLE COLOR

VDD (Pin 5G) 3.3V PWR (Pin 1) White cable

GND (Pin 7G) GND (Pin 6) Brown cable

SDI (Pin 10G) I2C1 SDA (Pin 3) Red cable

SCK (Pin 8G) I2C1 SCL (Pin 5) Orange cable

LED VDD (Pin 18F) GPIO 24 (Pin 18) White cable

LED GND (Pin 17F) GND (Pin 20) Black cable

Click to view Raspberry Pi 2 & 3 Pin mappings for your reference.


After you've successfully connected BME280 to your Raspberry Pi, it should be like below image.
Connect Pi to the network
Turn on Pi by using the micro USB cable and the power supply. Use the Ethernet cable to connect Pi to your
wired network or follow the instructions from the Raspberry Pi Foundation to connect Pi to your wireless
network. After your Pi has been successfully connected to the network, you need to take a note of the IP address
of your Pi.
NOTE
Make sure that Pi is connected to the same network as your computer. For example, if your computer is connected to a
wireless network while Pi is connected to a wired network, you might not see the IP address in the devdisco output.

Run a sample application on Pi


Install the prerequisite packages
Use one of the following SSH clients from your host computer to connect to your Raspberry Pi.
Windows Users
1. Download and install PuTTY for Windows.
2. Copy the IP address of your Pi into the Host name (or IP address) section and select SSH as the connection
type.
Mac and Ubuntu Users
Use the built-in SSH client on Ubuntu or macOS. You might need to run ssh pi@<ip address of pi> to connect Pi
via SSH.

NOTE
The default username is pi , and the password is raspberry .

Configure the sample application


1. Clone the sample application by running the following command:
cd ~
git clone https://github.com/Azure-Samples/iot-hub-python-raspberrypi-client-app.git

2. Open the config file by running the following commands:

cd iot-hub-python-raspberrypi-client-app
nano config.py

There are 5 macros in this file you can configurate. The first one is MESSAGE_TIMESPAN , which defines the
time interval (in milliseconds) between two messages that send to cloud. The second one SIMULATED_DATA ,
which is a Boolean value for whether to use simulated sensor data or not. I2C_ADDRESS is the I2C address
which your BME280 sensor is connected. GPIO_PIN_ADDRESS is the GPIO address for your LED. The last
one is BLINK_TIMESPAN , which defined the timespan when your LED is turned on in milliseconds.
If you don't have the sensor, set the SIMULATED_DATA value to True to make the sample application
create and use simulated sensor data.
3. Save and exit by pressing Control-O > Enter > Control-X.
Build and run the sample application
1. Build the sample application by running the following command. Because the Azure IoT SDKs for Python
are wrappers on top of the Azure IoT Device C SDK, you will need to compile the C libraries if you want or
need to generate the Python libraries from source code.

sudo chmod u+x setup.sh


sudo ./setup.sh

NOTE
You can also specify the version you want by running sudo ./setup.sh [--python-version|-p] [2.7|3.4|3.5] .
If you run script without parameter, the script will automatically detect the version of python installed (Search
sequence 2.7->3.4->3.5). Make sure your Python version keeps consistent during building and running.

NOTE
On building the Python client library (iothub_client.so) on Linux devices that have less than 1GB RAM, you may see
build getting stuck at 98% while building iothub_client_python.cpp as shown below
[ 98%] Building CXX object
python/src/CMakeFiles/iothub_client_python.dir/iothub_client_python.cpp.o
. If you run into this issue, check the memory consumption of the device using free -m command in another
terminal window during that time. If you are running out of memory while compiling iothub_client_python.cpp file,
you may have to temporarily increase the swap space to get more available memory to successfully build the
Python client-side device SDK library.

2. Run the sample application by running the following command:

python app.py '<your Azure IoT hub device connection string>'


NOTE
Make sure you copy-paste the device connection string into the single quotes. And if you use the python 3, then
you can use the command python3 app.py '<your Azure IoT hub device connection string>' .

You should see the following output that shows the sensor data and the messages that are sent to your IoT hub.

Next steps
You’ve run a sample application to collect sensor data and send it to your IoT hub. To see the messages that your
Raspberry Pi has sent to your IoT hub or send messages to your Raspberry Pi in a command line interface, see
the Manage cloud device messaging with iothub-explorer tutorial.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Connect Raspberry Pi to Azure IoT Hub (Node.js)
5/29/2018 • 8 min to read • Edit Online

In this tutorial, you begin by learning the basics of working with Raspberry Pi that's running Raspbian. You
then learn how to seamlessly connect your devices to the cloud by using Azure IoT Hub. For Windows 10
IoT Core samples, go to the Windows Dev Center.
Don't have a kit yet? Try Raspberry Pi online simulator. Or buy a new kit here.

What you do
Create an IoT hub.
Register a device for Pi in your IoT hub.
Set up Raspberry Pi.
Run a sample application on Pi to send sensor data to your IoT hub.

What you learn


How to create an Azure IoT hub and get your new device connection string.
How to connect Pi with a BME280 sensor.
How to collect sensor data by running a sample application on Pi.
How to send sensor data to your IoT hub.

What you need

A Raspberry Pi 2 or Raspberry Pi 3 board.


An active Azure subscription. If you don't have an Azure account, create a free Azure trial account in just a
few minutes.
A monitor, a USB keyboard, and mouse that connects to Pi.
A Mac or PC that is running Windows or Linux.
An internet connection.
A 16 GB or above microSD card.
A USB -SD adapter or microSD card to burn the operating system image onto the microSD card.
A 5-volt 2-amp power supply with the 6-foot micro USB cable.
The following items are optional:
An assembled Adafruit BME280 temperature, pressure, and humidity sensor.
A breadboard.
6 F/M jumper wires.
A diffused 10-mm LED.

NOTE
If you don't have the optional items, you can use simulated sensor data.

Create an IoT hub


1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.
IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information
while naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on
your subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create.
You can monitor the progress in the Notifications pane.
Now that you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub.
In your IoT hub navigation menu, open Shared access policies. Select the iothubowner policy, and then
copy the Connection string---primary key of your IoT hub. For more information, see Control access to
IoT Hub.

NOTE
You do not need this iothubowner connection string for this set-up tutorial. However, you may need it for some of the
tutorials or different IoT scenarios after you complete this set-up.
Register a device in the IoT hub for your device
1. In your IoT hub navigation menu, open IoT devices, then click Add to register a device in your IoT
hub.

2. Enter a Device ID for the new device. Device IDs are case sensitive.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to
avoid any sensitive information while naming it.
3. Click Save.
4. After the device is created, open the device from the list in the IoT devices pane.
5. Copy the Connection string---primary key to use later.

Set up Raspberry Pi
Install the Raspbian operating system for Pi
Prepare the microSD card for installation of the Raspbian image.
1. Download Raspbian.
a. Download Raspbian Stretch (the .zip file).

WARNING
Please use above link to download raspbian-2017-07-5 zip image. The latest version of Raspbian images
has some known issues with Wiring-Pi Node, which might cause failure in your next steps.
1. Extract the Raspbian image to a folder on your computer.

2. Install Raspbian to the microSD card.


a. Download and install the Etcher SD card burner utility.
b. Run Etcher and select the Raspbian image that you extracted in step 1.
c. Select the microSD card drive. Etcher may have already selected the correct drive.
d. Click Flash to install Raspbian to the microSD card.
e. Remove the microSD card from your computer when installation is complete. It's safe to remove
the microSD card directly because Etcher automatically ejects or unmounts the microSD card
upon completion.
f. Insert the microSD card into Pi.
Enable SSH and I2C
1. Connect Pi to the monitor, keyboard, and mouse.
2. Start Pi and then log in Raspbian by using pi as the user name and raspberry as the password.
3. Click the Raspberry icon > Preferences > Raspberry Pi Configuration.
4. On the Interfaces tab, set I2C and SSH to Enable, and then click OK. If you don't have physical
sensors and want to use simulated sensor data, this step is optional.

NOTE
To enable SSH and I2C, you can find more reference documents on raspberrypi.org and Adafruit.com.

Connect the sensor to Pi


Use the breadboard and jumper wires to connect an LED and a BME280 to Pi as follows. If you don’t have
the sensor, skip this section.
The BME280 sensor can collect temperature and humidity data. The LED blinks when the device sends a
message to the cloud.
For sensor pins, use the following wiring:

START (SENSOR & LED) END (BOARD) CABLE COLOR

VDD (Pin 5G) 3.3V PWR (Pin 1) White cable

GND (Pin 7G) GND (Pin 6) Brown cable

SDI (Pin 10G) I2C1 SDA (Pin 3) Red cable

SCK (Pin 8G) I2C1 SCL (Pin 5) Orange cable

LED VDD (Pin 18F) GPIO 24 (Pin 18) White cable

LED GND (Pin 17F) GND (Pin 20) Black cable

Click to view Raspberry Pi 2 & 3 pin mappings for your reference.


After you've successfully connected BME280 to your Raspberry Pi, it should be like below image.
Connect Pi to the network
Turn on Pi by using the micro USB cable and the power supply. Use the Ethernet cable to connect Pi to your
wired network or follow the instructions from the Raspberry Pi Foundation to connect Pi to your wireless
network. After your Pi has been successfully connected to the network, you need to take a note of the IP
address of your Pi.
NOTE
Make sure that Pi is connected to the same network as your computer. For example, if your computer is connected to
a wireless network while Pi is connected to a wired network, you might not see the IP address in the devdisco output.

Run a sample application on Pi


Clone sample application and install the prerequisite packages
1. Connect to your Raspberry Pi with one of the following SSH clients from your host computer:
Windows Users
a. Download and install PuTTY for Windows.
b. Copy the IP address of your Pi into the Host name (or IP address) section and select SSH as the
connection type.

Mac and Ubuntu Users


Use the built-in SSH client on Ubuntu or macOS. You might need to run ssh pi@<ip address of pi>
to connect Pi via SSH.

NOTE
The default username is pi and the password is raspberry .

2. Install Node.js and NPM to your Pi.


First check your Node.js version.

node -v

If the version is lower than 4.x, or if there is no Node.js on your Pi, install the latest version.
curl -sL http://deb.nodesource.com/setup_4.x | sudo -E bash
sudo apt-get -y install nodejs

3. Clone the sample application.

git clone https://github.com/Azure-Samples/iot-hub-node-raspberrypi-client-app

4. Install all packages for the sample. The installation includes Azure IoT device SDK, BME280 Sensor
library, and Wiring Pi library.

cd iot-hub-node-raspberrypi-client-app
sudo npm install

NOTE
It might take several minutes to finish this installation process depending on your network connection.

Configure the sample application


1. Open the config file by running the following commands:

nano config.json

There are two items in this file you can configure. The first one is interval , which defines the time
interval (in milliseconds) between messages sent to the cloud. The second one is simulatedData ,
which is a Boolean value for whether to use simulated sensor data or not.
If you don't have the sensor, set the simulatedData value to true to make the sample application
create and use simulated sensor data.
2. Save and exit by typing Control-O > Enter > Control-X.
Run the sample application
Run the sample application by running the following command:

sudo node index.js '<YOUR AZURE IOT HUB DEVICE CONNECTION STRING>'

NOTE
Make sure you copy-paste the device connection string into the single quotes.

You should see the following output that shows the sensor data and the messages that are sent to your IoT
hub.

Next steps
You’ve run a sample application to collect sensor data and send it to your IoT hub. To see the messages that
your Raspberry Pi has sent to your IoT hub, or to send messages to your Raspberry Pi in a command-line
interface, see the Manage cloud device messaging with iothub-explorer tutorial.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Connect Raspberry Pi to Azure IoT Hub (C)
5/29/2018 • 7 min to read • Edit Online

In this tutorial, you begin by learning the basics of working with Raspberry Pi that's running Raspbian. You then
learn how to seamlessly connect your devices to the cloud by using Azure IoT Hub. For Windows 10 IoT Core
samples, go to the Windows Dev Center.
Don't have a kit yet? Try Raspberry Pi online simulator. Or buy a new kit here.

What you do
Create an IoT hub.
Register a device for Pi in your IoT hub.
Setup Raspberry Pi.
Run a sample application on Pi to send sensor data to your IoT hub.
Connect Raspberry Pi to an IoT hub that you create. Then you run a sample application on Pi to collect
temperature and humidity data from a BME280 sensor. Finally, you send the sensor data to your IoT hub.

What you learn


How to create an Azure IoT hub and get your new device connection string.
How to connect Pi with a BME280 sensor.
How to collect sensor data by running a sample application on Pi.
How to send sensor data to your IoT hub.

What you need

The Raspberry Pi 2 or Raspberry Pi 3 board.


An active Azure subscription. If you don't have an Azure account, create a free Azure trial account in just a few
minutes.
A monitor, a USB keyboard, and mouse that connect to Pi.
A Mac or a PC that is running Windows or Linux.
An Internet connection.
A 16 GB or above microSD card.
A USB -SD adapter or microSD card to burn the operating system image onto the microSD card.
A 5-volt 2-amp power supply with the 6-foot micro USB cable.
The following items are optional:
An assembled Adafruit BME280 temperature, pressure, and humidity sensor.
A breadboard.
6 F/M jumper wires.
A diffused 10-mm LED.

NOTE
These items are optional because the code sample support simulated sensor data.

Create an IoT hub


1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
Now that you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub.
In your IoT hub navigation menu, open Shared access policies. Select the iothubowner policy, and then copy
the Connection string---primary key of your IoT hub. For more information, see Control access to IoT Hub.

NOTE
You do not need this iothubowner connection string for this set-up tutorial. However, you may need it for some of the
tutorials or different IoT scenarios after you complete this set-up.
Register a device in the IoT hub for your device
1. In your IoT hub navigation menu, open IoT devices, then click Add to register a device in your IoT hub.

2. Enter a Device ID for the new device. Device IDs are case sensitive.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.
3. Click Save.
4. After the device is created, open the device from the list in the IoT devices pane.
5. Copy the Connection string---primary key to use later.

Setup Raspberry Pi
Install the Raspbian operating system for Pi
Prepare the microSD card for installation of the Raspbian image.
1. Download Raspbian.
a. Download Raspbian Jessie with Desktop (the .zip file).
b. Extract the Raspbian image to a folder on your computer.
2. Install Raspbian to the microSD card.
a. Download and install the Etcher SD card burner utility.
b. Run Etcher and select the Raspbian image that you extracted in step 1.
c. Select the microSD card drive. Note that Etcher may have already selected the correct drive.
d. Click Flash to install Raspbian to the microSD card.
e. Remove the microSD card from your computer when installation is complete. It's safe to remove the
microSD card directly because Etcher automatically ejects or unmounts the microSD card upon
completion.
f. Insert the microSD card into Pi.
Enable SSH and SPI
1. Connect Pi to the monitor, keyboard and mouse, start Pi and then log in Raspbian by using pi as the user
name and raspberry as the password.
2. Click the Raspberry icon > Preferences > Raspberry Pi Configuration.
3. On the Interfaces tab, set SPI and SSH to Enable, and then click OK. If you don't have physical sensors
and want to use simulated sensor data, this step is optional.

NOTE
To enable SSH and SPI, you can find more reference documents on raspberrypi.org and RASPI-CONFIG.

Connect the sensor to Pi


Use the breadboard and jumper wires to connect an LED and a BME280 to Pi as follows. If you don’t have the
sensor, skip this section.
The BME280 sensor can collect temperature and humidity data. And the LED will blink if there is a
communication between device and the cloud.
For sensor pins, use the following wiring:

START (SENSOR & LED) END (BOARD) CABLE COLOR

LED VDD (Pin 5G) GPIO 4 (Pin 7) White cable

LED GND (Pin 6G) GND (Pin 6) Black cable

VDD (Pin 18F) 3.3V PWR (Pin 17) White cable

GND (Pin 20F) GND (Pin 20) Black cable

SCK (Pin 21F) SPI0 SCLK (Pin 23) Orange cable

SDO (Pin 22F) SPI0 MISO (Pin 21) Yellow cable

SDI (Pin 23F) SPI0 MOSI (Pin 19) Green cable

CS (Pin 24F) SPI0 CS (Pin 24) Blue cable

Click to view Raspberry Pi 2 & 3 Pin mappings for your reference.


After you've successfully connected BME280 to your Raspberry Pi, it should be like below image.
Connect Pi to the network
Turn on Pi by using the micro USB cable and the power supply. Use the Ethernet cable to connect Pi to your
wired network or follow the instructions from the Raspberry Pi Foundation to connect Pi to your wireless
network. After your Pi has been successfully connected to the network, you need to take a note of the IP address
of your Pi.
Run a sample application on Pi
Login to your Raspberry Pi
1. Use one of the following SSH clients from your host computer to connect to your Raspberry Pi.
Windows Users
a. Download and install PuTTY for Windows.
b. Copy the IP address of your Pi into the Host name (or IP address) section and select SSH as the
connection type.
Mac and Ubuntu Users
Use the built-in SSH client on Ubuntu or macOS. You might need to run ssh pi@<ip address of pi> to
connect Pi via SSH.

NOTE
The default username is pi , and the password is raspberry .

Configure the sample application


1. Clone the sample application by running the following command:

sudo apt-get install git-core


git clone https://github.com/Azure-Samples/iot-hub-c-raspberrypi-client-app.git

2. Run setup script:

cd ./iot-hub-c-raspberrypi-client-app
sudo chmod u+x setup.sh
sudo ./setup.sh

NOTE
If you don't have a physical BME280, you can use '--simulated-data' as command line parameter to simulate
temperature&humidity data. sudo ./setup.sh --simulated-data

Build and run the sample application


1. Build the sample application by running the following command:

cmake . && make


2. Run the sample application by running the following command:

sudo ./app '<DEVICE CONNECTION STRING>'

NOTE
Make sure you copy-paste the device connection string into the single quotes.

You should see the following output that shows the sensor data and the messages that are sent to your IoT hub.
Next steps
You’ve run a sample application to collect sensor data and send it to your IoT hub. To see the messages that your
Raspberry Pi has sent to your IoT hub or send messages to your Raspberry Pi in a command line interface, see
the Manage cloud device messaging with iothub-explorer tutorial.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Connect IoT DevKit AZ3166 to Azure IoT Hub in the
cloud
5/29/2018 • 9 min to read • Edit Online

You can use the MXChip IoT DevKit to develop and prototype Internet of Things (IoT) solutions that take
advantage of Microsoft Azure services. It includes an Arduino-compatible board with rich peripherals and
sensors, an open-source board package, and a growing projects catalog.

What you do
Connect the DevKit to an Azure IoT hub that you create, collect the temperature and humidity data from sensors,
and send the data to the IoT hub.
Don't have a DevKit yet? Try DevKit simulator or get one.

What you learn


How to connect the IoT DevKit to a wireless access point and prepare your development environment.
How to create an IoT hub and register a device for the MXChip IoT DevKit.
How to collect sensor data by running a sample application on the MXChip IoT DevKit.
How to send the sensor data to your IoT hub.

What you need


An MXChip IoT DevKit board with a Micro-USB cable. Get it now.
A computer running Windows 10 or macOS 10.10+.
An active Azure subscription. Activate a free 30-day trial Microsoft Azure account.

Prepare your hardware


Hook up the hardware to your computer.
You need this hardware:
DevKit board
Micro-USB cable
To connect the DevKit to your computer:
1. Connect the USB end to your computer.
2. Connect the Micro-USB end to the DevKit.
3. The green LED for power confirms the connection.
Configure Wi-Fi
IoT projects rely on internet connectivity. Use the following instructions to configure the DevKit to connect to Wi-
Fi.
Enter AP mode
Hold down button B, push and release the reset button, and then release button B. Your DevKit enters AP mode
for configuring Wi-Fi. The screen displays the service set identifier (SSID ) of the DevKit and the configuration
portal IP address.
Connect to DevKit AP
Now, use another Wi-Fi enabled device (computer or mobile phone) to connect to the DevKit SSID (highlighted
in the previous image). Leave the password empty.
Configure Wi-Fi for the DevKit
Open the IP address shown on the DevKit screen on your computer or mobile phone browser, select the Wi-Fi
network that you want the DevKit to connect to, and then type the password. Select Connect.

When the connection succeeds, the DevKit reboots in a few seconds. You then see the Wi-Fi name and IP
address on the screen:
NOTE
The IP address displayed in the photo might not match the actual IP address assigned and displayed on the DevKit screen.
This is normal, because Wi-Fi uses DHCP to dynamically assign IPs.

After Wi-Fi is configured, your credentials will persist on the device for that connection, even if the device is
unplugged. For example, if you configure the DevKit for Wi-Fi in your home and then take the DevKit to the
office, you will need to reconfigure AP mode (starting at the step in the "Enter AP Mode" section) to connect the
DevKit to your office Wi-Fi.

Start using the DevKit


The default app running on the DevKit checks the latest version of the firmware and displays some sensor
diagnosis data for you.
Upgrade to the latest firmware
NOTE
Since v1.1, DevKit enables ST-SAFE in bootloader. You need to upgrade firmware if you are running under v1.1 in order to
make it work probably.

If you need a firmware upgrade, the screen will show the current and latest firmware versions. To upgrade, follow
the Upgrade firmware guide.

NOTE
This is a one-time effort. After you start developing on the DevKit and upload your app, the latest firmware will come with
your app.

Test various sensors


Press button B to test sensors. Continue pressing and releasing the button B to cycle through each sensor.
Prepare the development environment
Now it's time to set up the development environment: tools and packages for you to build stunning IoT
applications. You can choose the Windows or macOS version according to your operating system.
Windows
We encourage you to use the installation package to prepare the development environment. If you encounter
any problems, you can follow the manual steps to get it done.
Download the latest package
The .zip file that you download contains all the necessary tools and packages for DevKit development.
DOW N LOA D

The .zip file contains the following tools and packages. If you already have some components installed, the script
will detect and skip them.
Node.js and Yarn: Runtime for the setup script and automated tasks.
Azure CLI 2.0 MSI: Cross-platform command-line experience for managing Azure resources. The MSI
contains dependent Python and pip.
Visual Studio Code (VS Code): Lightweight code editor for DevKit development.
Visual Studio Code extension for Arduino: Extension that enables Arduino development in Visual Studio
Code.
Arduino IDE: Tool that the extension for Arduino relies on.
DevKit Board Package: Tool chains, libraries, and projects for the DevKit.
ST-Link Utility: Essential tools and drivers.
Run the installation script
In Windows File Explorer, locate the .zip file and extract it. Find install.cmd , right-click it, and select Run as
administrator.

During installation, you see the progress of each tool or package.


NOTE
Depending on your environment, sometimes you will get failure when installing Arduino IDE. In this case, you may try
install Arduino IDE individually and run install.cmd again. Otherwise, please follow the manual steps to install all necessary
tools and packages.

Install drivers
The VS Code for Arduino extension relies on the Arduino IDE. If this is the first time you are installing the
Arduino IDE, you're prompted to install relevant drivers:

Installation should take around 10 minutes, depending on your internet speed. After the installation is complete,
you should see Visual Studio Code and Arduino IDE shortcuts on your desktop.
NOTE
Occasionally, when you start VS Code, you're prompted with an error that it cannot find the Arduino IDE or related board
package. To solve it, close VS Code and restart the Arduino IDE. VS Code should then locate the Arduino IDE path correctly.

macOS
We encourage you to use one-click installation experience to prepare the development environment. If you
encounter any problems, you can follow the manual steps to get it done.
Install Homebrew

NOTE
If you have installed Homebrew, you can skip this step.

Follow the Homebrew installation instructions to install it.


Download the latest package
The .zip file that you download contains all the necessary tools and packages for DevKit development.
DOW N LOA D

The .zip file contains the following tools and packages. If you already have some components installed, the script
will detect and skip them.
Node.js and Yarn: Runtime for the setup script and automated tasks.
Azure CLI 2.0: Cross-platform command-line experience for managing Azure resources.
Visual Studio Code (VS Code): Lightweight code editor for DevKit development.
Visual Studio Code extension for Arduino: Extension that enables Arduino development in Visual Studio
Code.
Arduino IDE: Tool that the extension for Arduino relies on.
DevKit Board Package: Tool chains, libraries, and projects for the DevKit.
ST-Link Utility: Essential tools and drivers.
Run the installation script
In the Finder, locate the .zip and extract it:
Launch Terminal app, locate the folder you extract .zip file and run:

./install.sh

NOTE
If you meet Homebrew permission error, run brew doctor to get it fixed. Check FAQ for more details.

You now have all the necessary tools and packages installed for macOS.
Open the project folder
Start VS Code
Make sure your DevKit is not connected. Start VS Code first and connect the DevKit to your computer. VS Code
automatically finds the DevKit and opens an introduction page:

NOTE
Occasionally, when you start VS Code, you're prompted with an error that it cannot find the Arduino IDE or related board
package. Close VS Code and restart the Arduino IDE. VS Code should then locate the Arduino IDE path correctly.

Open the Arduino Examples folder


On the Arduino Examples tab, browse to Examples for MXCHIP AZ3166 > AzureIoT, and select
GetStarted.
If you happen to close the pane, you can reopen it. Use Ctrl+Shift+P (macOS: Cmd+Shift+P ) to open the
command palette, type Arduino, and then find and select Arduino: Examples.

Provision Azure services


In the solution window, run your task through Ctrl+P (macOS: Cmd+P ) by entering task cloud-provision .
In the VS Code terminal, an interactive command line guides you through provisioning the required Azure
services:

Build and upload the Arduino sketch


Windows
1. Use Ctrl+P to run task device-upload .
2. The terminal prompts you to enter configuration mode. To do so, hold down button A, then push and release
the reset button. The screen displays the DevKit id and 'Configuration'.
This is to set the connection string that retrieves from task cloud-provision step.
Then VS Code starts verifying and uploading the Arduino sketch:

The DevKit reboots and starts running the code.

NOTE
Occasionally, you get error "Error: AZ3166: Unknown package". This is due to the board package index is not refreshed.
Check this FAQ steps to solve it.

macOS
1. Put DevKit into configuration mode: Hold down button A, then push and release the reset button. The screen
displays 'Configuration'.
2. Use Cmd+P to run task device-upload .

This is to set the connection string that retrieves from task cloud-provision step.
Then VS Code starts verifying and uploading the Arduino sketch:
The DevKit reboots and starts running the code.

NOTE
Occasionally, you get error "Error: AZ3166: Unknown package". This is due to the board package index is not refreshed.
Check this FAQ steps to solve it.

Test the project


In VS Code, following these steps to open and set up the Serial Monitor:
1. Click the COM[X] word on the status bar to set the right COM port with STMicroelectronics :

2. Click power plug icon on the status bar to open the Serial Monitor:
3. On the status bar, click the number that represents the Baud Rate and set to 115200 :

The sample application is running successfully when you see the following results:
The Serial Monitor displays the same information as the content in the screenshot below.
The LED on MXChip IoT DevKit is blinking.

Problems and feedback


If you encounter problems, you can find FAQs. You can also give us feedback by leaving a comment on this page.

Next steps
You have successfully connected an MXChip IoT DevKit to your IoT hub, and you have sent the captured sensor
data to your IoT hub.
To continue getting started with Azure IoT Hub and to explore other IoT scenarios, see:
Manage cloud device messaging with iothub-explorer
Save IoT Hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from Azure IoT Hub
Use Web Apps to visualize real-time sensor data from Azure IoT Hub
Weather forecast using the sensor data from your IoT hub in Azure Machine Learning
Device management with iothub-explorer
Remote monitoring and notifications with Logic Apps
Connect Intel Edison to Azure IoT Hub (Node.js)
5/29/2018 • 8 min to read • Edit Online

In this tutorial, you begin by learning the basics of working with Intel Edison. You then learn how to seamlessly
connect your devices to the cloud by using Azure IoT Hub.
Don't have a kit yet? Start here

What you do
Setup Intel Edison and and Grove modules.
Create an IoT hub.
Register a device for Edison in your IoT hub.
Run a sample application on Edison to send sensor data to your IoT hub.
Connect Intel Edison to an IoT hub that you create. Then you run a sample application on Edison to collect
temperature and humidity data from a Grove temperature sensor. Finally, you send the sensor data to your IoT
hub.

What you learn


How to create an Azure IoT hub and get your new device connection string.
How to connect Edison with a Grove temperature sensor.
How to collect sensor data by running a sample application on Edison.
How to send sensor data to your IoT hub.

What you need

The Intel Edison board


Arduino expansion board
An active Azure subscription. If you don't have an Azure account, create a free Azure trial account in just a few
minutes.
A Mac or a PC that is running Windows or Linux.
An Internet connection.
A Micro B to Type A USB cable
A direct current (DC ) power supply. Your power supply should be rated as follows:
7-15V DC
At least 1500mA
The center/inner pin should be the positive pole of the power supply
The following items are optional:
Grove Base Shield V2
Grove - Temperature Sensor
Grove Cable
Any spacer bars or screws included in the packaging, including two screws to fasten the module to the
expansion board and four sets of screws and plastic spacers.

NOTE
These items are optional because the code sample support simulated sensor data.

Create an IoT hub


1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
Now that you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub.
In your IoT hub navigation menu, open Shared access policies. Select the iothubowner policy, and then copy
the Connection string---primary key of your IoT hub. For more information, see Control access to IoT Hub.

NOTE
You do not need this iothubowner connection string for this set-up tutorial. However, you may need it for some of the
tutorials or different IoT scenarios after you complete this set-up.
Register a device in the IoT hub for your device
1. In your IoT hub navigation menu, open IoT devices, then click Add to register a device in your IoT hub.

2. Enter a Device ID for the new device. Device IDs are case sensitive.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.
3. Click Save.
4. After the device is created, open the device from the list in the IoT devices pane.
5. Copy the Connection string---primary key to use later.

Setup Intel Edison


Assemble your board
This section contains steps to attach your Intel® Edison module to your expansion board.
1. Place the Intel® Edison module within the white outline on your expansion board, lining up the holes on
the module with the screws on the expansion board.
2. Press down on the module just below the words What will you make? until you feel a snap.

3. Use the two hex nuts (included in the package) to secure the module to the expansion board.
4. Insert a screw in one of the four corner holes on the expansion board. Twist and tighten one of the white
plastic spacers onto the screw.

5. Repeat for the other three corner spacers.


Now your board is assembled.

Connect the Grove Base Shield and the temperature sensor


1. Place the Grove Base Shield on to your board. Make sure all pins are tightly plugged into your board.
2. Use Grove Cable to connect Grove temperature sensor onto the Grove Base Shield A0 port.
Now your sensor is ready.
Power up Edison
1. Plug in the power supply.

2. A green LED (labeled DS1 on the Arduino* expansion board) should light up and stay lit.
3. Wait one minute for the board to finish booting up.

NOTE
If you do not have a DC power supply, you can still power the board through a USB port. See
Connect Edison to your computer section for details. Powering your board in this fashion may result in
unpredictable behavior from your board, especially when using Wi-Fi or driving motors.

Connect Edison to your computer


1. Toggle down the microswitch towards the two micro USB ports, so that Edison is in device mode. For
differences between device mode and host mode, please reference here.

2. Plug the micro USB cable into the top micro USB port.
3. Plug the other end of USB cable into your computer.

4. You will know that your board is fully initialized when your computer mounts a new drive (much like
inserting a SD card into your computer).

Download and run the configuration tool


Get the latest configuration tool from this link listed under the Installers heading. Execute the tool and follow
its on-screen instructions, clicking Next where needed
Flash firmware
1. On the Set up options page, click Flash Firmware .
2. Select the image to flash onto your board by doing one of the following:
To download and flash your board with the latest firmware image available from Intel, select
Download the latest image version xxxx .
To flash your board with an image you already have saved on your computer, select
Select the local image . Browse to and select the image you want to flash to your board.
3. The setup tool will attempt to flash your board. The entire flashing process may take up to 10 minutes.
Set password
1. On the Set up options page, click Enable Security .
2. You can set a custom name for your Intel® Edison board. This is optional.
3. Type a password for your board, then click Set password .
4. Mark down the password, which is used later.
Connect Wi-Fi
1. On the Set up options page, click Connect Wi-Fi . Wait up to one minute as your computer scans for
available Wi-Fi networks.
2. From the Detected Networks drop-down list, select your network.
3. From the Security drop-down list, select the network's security type.
4. Provide your login and password information, then click Configure Wi-Fi .
5. Mark down the IP address, which is used later.

NOTE
Make sure that Edison is connected to the same network as your computer. Your computer connects to your Edison by
using the IP address.
Congratulations! You've successfully configured Edison.

Run a sample application on Intel Edison


Prepare the Azure IoT Device SDK
1. Use one of the following SSH clients from your host computer to connect to your Intel Edison. The IP
address is from the configuration tool and the password is the one you've set in that tool.
PuTTY for Windows.
The built-in SSH client on Ubuntu or macOS.
2. Clone the sample client app to your device.

git clone https://github.com/Azure-Samples/iot-hub-node-intel-edison-client-app

3. Then navigate to the repo folder to run the following command to install all packages, it may take serval
minutes to complete.

cd iot-hub-node-intel-edison-client-app
npm install

Configure and run the sample application


1. Open the config file by running the following commands:

nano config.json
There are two macros in this file you can configurate. The first one is INTERVAL , which defines the time
interval between two messages that send to cloud. The second one simulatedData ,which is a Boolean
value for whether to use simulated sensor data or not.
If you don't have the sensor, set the simulatedData value to true to make the sample application
create and use simulated sensor data.
2. Save and exit by pressing Control-O > Enter > Control-X.
3. Run the sample application by running the following command:

sudo node index.js '<your Azure IoT hub device connection string>'

NOTE
Make sure you copy-paste the device connection string into the single quotes.

You should see the following output that shows the sensor data and the messages that are sent to your IoT hub.
Next steps
You’ve run a sample application to collect sensor data and send it to your IoT hub.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Connect Intel Edison to Azure IoT Hub (C)
5/29/2018 • 8 min to read • Edit Online

In this tutorial, you begin by learning the basics of working with Intel Edison. You then learn how to seamlessly
connect your devices to the cloud by using Azure IoT Hub.
Don't have a kit yet? Start here

What you do
Setup Intel Edison and and Grove modules.
Create an IoT hub.
Register a device for Edison in your IoT hub.
Run a sample application on Edison to send sensor data to your IoT hub.
Connect Intel Edison to an IoT hub that you create. Then you run a sample application on Edison to collect
temperature and humidity data from a Grove temperature sensor. Finally, you send the sensor data to your IoT
hub.

What you learn


How to create an Azure IoT hub and get your new device connection string.
How to connect Edison with a Grove temperature sensor.
How to collect sensor data by running a sample application on Edison.
How to send sensor data to your IoT hub.

What you need

The Intel Edison board


Arduino expansion board
An active Azure subscription. If you don't have an Azure account, create a free Azure trial account in just a few
minutes.
A Mac or a PC that is running Windows or Linux.
An Internet connection.
A Micro B to Type A USB cable
A direct current (DC ) power supply. Your power supply should be rated as follows:
7-15V DC
At least 1500mA
The center/inner pin should be the positive pole of the power supply
The following items are optional:
Grove Base Shield V2
Grove - Temperature Sensor
Grove Cable
Any spacer bars or screws included in the packaging, including two screws to fasten the module to the
expansion board and four sets of screws and plastic spacers.

NOTE
These items are optional because the code sample support simulated sensor data.

Create an IoT hub


1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
Now that you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub.
In your IoT hub navigation menu, open Shared access policies. Select the iothubowner policy, and then copy
the Connection string---primary key of your IoT hub. For more information, see Control access to IoT Hub.

NOTE
You do not need this iothubowner connection string for this set-up tutorial. However, you may need it for some of the
tutorials or different IoT scenarios after you complete this set-up.
Register a device in the IoT hub for your device
1. In your IoT hub navigation menu, open IoT devices, then click Add to register a device in your IoT hub.

2. Enter a Device ID for the new device. Device IDs are case sensitive.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid
any sensitive information while naming it.
3. Click Save.
4. After the device is created, open the device from the list in the IoT devices pane.
5. Copy the Connection string---primary key to use later.

Setup Intel Edison


Assemble your board
This section contains steps to attach your Intel® Edison module to your expansion board.
1. Place the Intel® Edison module within the white outline on your expansion board, lining up the holes on
the module with the screws on the expansion board.
2. Press down on the module just below the words What will you make? until you feel a snap.

3. Use the two hex nuts (included in the package) to secure the module to the expansion board.
4. Insert a screw in one of the four corner holes on the expansion board. Twist and tighten one of the white
plastic spacers onto the screw.

5. Repeat for the other three corner spacers.


Now your board is assembled.

Connect the Grove Base Shield and the temperature sensor


1. Place the Grove Base Shield on to your board. Make sure all pins are tightly plugged into your board.
2. Use Grove Cable to connect Grove temperature sensor onto the Grove Base Shield A0 port.
Now your sensor is ready.
Power up Edison
1. Plug in the power supply.

2. A green LED (labeled DS1 on the Arduino* expansion board) should light up and stay lit.
3. Wait one minute for the board to finish booting up.

NOTE
If you do not have a DC power supply, you can still power the board through a USB port. See
Connect Edison to your computer section for details. Powering your board in this fashion may result in
unpredictable behavior from your board, especially when using Wi-Fi or driving motors.

Connect Edison to your computer


1. Toggle down the microswitch towards the two micro USB ports, so that Edison is in device mode. For
differences between device mode and host mode, please reference here.

2. Plug the micro USB cable into the top micro USB port.
3. Plug the other end of USB cable into your computer.

4. You will know that your board is fully initialized when your computer mounts a new drive (much like
inserting a SD card into your computer).

Download and run the configuration tool


Get the latest configuration tool from this link listed under the Installers heading. Execute the tool and follow
its on-screen instructions, clicking Next where needed
Flash firmware
1. On the Set up options page, click Flash Firmware .
2. Select the image to flash onto your board by doing one of the following:
To download and flash your board with the latest firmware image available from Intel, select
Download the latest image version xxxx .
To flash your board with an image you already have saved on your computer, select
Select the local image . Browse to and select the image you want to flash to your board.
3. The setup tool will attempt to flash your board. The entire flashing process may take up to 10 minutes.
Set password
1. On the Set up options page, click Enable Security .
2. You can set a custom name for your Intel® Edison board. This is optional.
3. Type a password for your board, then click Set password .
4. Mark down the password, which is used later.
Connect Wi-Fi
1. On the Set up options page, click Connect Wi-Fi . Wait up to one minute as your computer scans for
available Wi-Fi networks.
2. From the Detected Networks drop-down list, select your network.
3. From the Security drop-down list, select the network's security type.
4. Provide your login and password information, then click Configure Wi-Fi .
5. Mark down the IP address, which is used later.

NOTE
Make sure that Edison is connected to the same network as your computer. Your computer connects to your Edison by
using the IP address.
Congratulations! You've successfully configured Edison.

Run a sample application on Intel Edison


Prepare the Azure IoT Device SDK
1. Use one of the following SSH clients from your host computer to connect to your Intel Edison. The IP
address is from the configuration tool and the password is the one you've set in that tool.
PuTTY for Windows.
The built-in SSH client on Ubuntu or macOS (run ssh root@"the IP address" ).
2. Clone the sample client app to your device.

git clone https://github.com/Azure-Samples/iot-hub-c-intel-edison-client-app.git

3. Then navigate to the repo folder to run the following command to build Azure IoT SDK

cd iot-hub-c-intel-edison-client-app
sed -i -e 's/\r$//' buildSDK.sh
chmod 755 buildSDK.sh
./buildSDK.sh

Configure the sample application


1. Open the config file by running the following commands:

nano config.h
There are two macros in this file you can configurate. The first one is INTERVAL , which defines the time
interval between two messages that send to cloud. The second one SIMULATED_DATA ,which is a Boolean
value for whether to use simulated sensor data or not.
If you don't have the sensor, set the SIMULATED_DATA value to 1 to make the sample application create
and use simulated sensor data.
2. Save and exit by pressing Control-O > Enter > Control-X.
Build and run the sample application
1. Build the sample application by running the following command:

cmake . && make


2. Run the sample application by running the following command:

sudo ./app '<your Azure IoT hub device connection string>'

NOTE
Make sure you copy-paste the device connection string into the single quotes.

You should see the following output that shows the sensor data and the messages that are sent to your IoT hub.
Next steps
You’ve run a sample application to collect sensor data and send it to your IoT hub.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Connect Adafruit Feather HUZZAH ESP8266 to
Azure IoT Hub in the cloud
5/29/2018 • 8 min to read • Edit Online

What you do
Connect Adafruit Feather HUZZAH ESP8266 to an IoT hub that you create. Then you run a sample application
on ESP8266 to collect the temperature and humidity data from a DHT22 sensor. Finally, you send the sensor
data to your IoT hub.

NOTE
If you're using other ESP8266 boards, you can still follow these steps to connect it to your IoT hub. Depending on the
ESP8266 board you're using, you might need to reconfigure the LED_PIN . For example, if you're using ESP8266 from AI-
Thinker, you might change it from 0 to 2 . Don't have a kit yet? Get it from the Azure website.

What you learn


How to create an IoT hub and register a device for Feather HUZZAH ESP8266
How to connect Feather HUZZAH ESP8266 with the sensor and your computer
How to collect sensor data by running a sample application on Feather HUZZAH ESP8266
How to send the sensor data to your IoT hub

What you need


To complete this operation, you need the following parts from your Feather HUZZAH ESP8266 Starter Kit:
The Feather HUZZAH ESP8266 board
A Micro USB to Type A USB cable
You also need the following things for your development environment:
An active Azure subscription. If you don't have an Azure account, create a free Azure trial account in just a
few minutes.
Mac or PC that is running Windows or Ubuntu.
Wireless network for Feather HUZZAH ESP8266 to connect to.
Internet connection to download the configuration tool.
Visual Studio Code extension for Arduino.

NOTE
The Arduino IDE version used by Visual Studio Code extension for Arduino has to be version 1.6.8 or later. Earlier versions
don't work with the AzureIoT library.

The following items are optional in case you don’t have a sensor. You also have the option of using simulated
sensor data.
An Adafruit DHT22 temperature and humidity sensor
A breadboard
M/M jumper wires

Create an IoT hub


1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
Now that you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub.
In your IoT hub navigation menu, open Shared access policies. Select the iothubowner policy, and then copy
the Connection string---primary key of your IoT hub. For more information, see Control access to IoT Hub.

NOTE
You do not need this iothubowner connection string for this set-up tutorial. However, you may need it for some of the
tutorials or different IoT scenarios after you complete this set-up.

Register a device in the IoT hub for your device


1. In your IoT hub navigation menu, open IoT devices, then click Add to register a device in your IoT hub.
2. Enter a Device ID for the new device. Device IDs are case sensitive.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to
avoid any sensitive information while naming it.

3. Click Save.
4. After the device is created, open the device from the list in the IoT devices pane.
5. Copy the Connection string---primary key to use later.

Connect Feather HUZZAH ESP8266 with the sensor and your


computer
In this section, you connect the sensors to your board. Then you plug in your device to your computer for
further use.
Connect a DHT22 temperature and humidity sensor to Feather HUZZAH ESP8266
Use the breadboard and jumper wires to make the connection as follows. If you don’t have a sensor, skip this
section because you can use simulated sensor data instead.

For sensor pins, use the following wiring:

START (SENSOR) END (BOARD) CABLE COLOR

VDD (Pin 31F) 3V (Pin 58H) Red cable

DATA (Pin 32F) GPIO 2 (Pin 46A) Blue cable

GND (Pin 34F) GND (PIn 56I) Black cable

For more information, see Adafruit DHT22 sensor setup and Adafruit Feather HUZZAH Esp8266 Pinouts.
Now your Feather Huzzah ESP8266 should be connected with a working sensor.
Connect Feather HUZZAH ESP8266 to your computer
As shown next, use the Micro USB to Type A USB cable to connect Feather HUZZAH ESP8266 to your
computer.

Add serial port permissions (Ubuntu only)


If you use Ubuntu, make sure you have the permissions to operate on the USB port of Feather HUZZAH
ESP8266. To add serial port permissions, follow these steps:
1. Run the following commands at a terminal:

ls -l /dev/ttyUSB*
ls -l /dev/ttyACM*

You get one of the following outputs:


crw -rw ---- 1 root uucp xxxxxxxx
crw -rw ---- 1 root dialout xxxxxxxx
In the output, notice that uucp or dialout is the group owner name of the USB port.
2. Add the user to the group by running the following command:

sudo usermod -a -G <group-owner-name> <username>

<group-owner-name> is the group owner name you obtained in the previous step. <username> is your
Ubuntu user name.
3. Sign out of Ubuntu, and then sign in again for the change to appear.
Collect sensor data and send it to your IoT hub
In this section, you deploy and run a sample application on Feather HUZZAH ESP8266. The sample application
blinks the LED on Feather HUZZAH ESP8266, and sends the temperature and humidity data collected from the
DHT22 sensor to your IoT hub.
Get the sample application from GitHub
The sample application is hosted on GitHub. Clone the sample repository that contains the sample application
from GitHub. To clone the sample repository, follow these steps:
1. Open a command prompt or a terminal window.
2. Go to a folder where you want the sample application to be stored.
3. Run the following command:

git clone https://github.com/Azure-Samples/iot-hub-feather-huzzah-client-app.git

Install the package for Feather HUZZAH ESP8266 in the Visual Studio Code:
1. Open the folder where the sample application is stored.
2. Open the app.ino file in the app folder in the Visual Studio Code.

3. In the Visual Studio Code, enter F1 .


4. Type Arduino and select Arduino: Board Manager.
5. In the Arduino Board Manager tab, click Additional URLs.
6. In the User Settings window, copy and paste the following at the end of the file
"arduino.additionalUrls": "http://arduino.esp8266.com/stable/package_esp8266com_index.json"

7. Save the file and close the User Settings tab.


8. Click Refresh Package Indexes. After the refresh finishes, search for esp8266.
9. Click Install button for esp8266.
Boards Manager indicates that ESP8266 with a version of 2.2.0 or later is installed.
10. Enter F1 , then type Arduino and select Arduino: Board Config.
11. Click box for Selected Board: and type esp8266, then select Adafruit HUZZAH ESP8266 (esp8266).

Install necessary libraries


1. In the Visual Studio Code, enter F1 , then type Arduino and select Arduino: Library Manager.
2. Search for the following library names one by one. For each library that you find, click Install.
AzureIoTHub
AzureIoTUtility
AzureIoTProtocol_MQTT
ArduinoJson
DHT sensor library
Adafruit Unified Sensor

Don’t have a real DHT22 sensor?


The sample application can simulate temperature and humidity data in case you don’t have a real DHT22 sensor.
To set up the sample application to use simulated data, follow these steps:
1. Open the config.h file in the app folder.
2. Locate the following line of code and change the value from false to true :

define SIMULATED_DATA true

3. Save the file.


Deploy the sample application to Feather HUZZAH ESP8266
1. In the Visual Studio Code, click on the status bar, and then click the serial port for Feather HUZZAH
ESP8266.
2. Enter F1 , then type Arduino and select Arduino: Upload to build and deploy the sample application to
Feather HUZZAH ESP8266.
Enter your credentials
After the upload completes successfully, follow these steps to enter your credentials:
1. Open Arduino IDE, click Tools > Serial Monitor.
2. In the serial monitor window, notice the two drop-down lists in the lower-right corner.
3. Select No line ending for the left drop-down list.
4. Select 115200 baud for the right drop-down list.
5. In the input box located at the top of the serial monitor window, enter the following information if you are
asked to provide them, and then click Send.
Wi-Fi SSID
Wi-Fi password
Device connection string
NOTE
The credential information is stored in the EEPROM of Feather HUZZAH ESP8266. If you click the reset button on the
Feather HUZZAH ESP8266 board, the sample application asks if you want to erase the information. Enter Y to have the
information erased. You are asked to provide the information a second time.

Verify the sample application is running successfully


If you see the following output from the serial monitor window and the blinking LED on Feather HUZZAH
ESP8266, the sample application is running successfully.

Next steps
You have successfully connected a Feather HUZZAH ESP8266 to your IoT hub, and sent the captured sensor
data to your IoT hub.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Connect Sparkfun ESP8266 Thing Dev to Azure IoT
Hub in the cloud
5/29/2018 • 8 min to read • Edit Online

What you will do


Connect Sparkfun ESP8266 Thing Dev to an IoT hub you will create. Then run a sample application on ESP8266
to collect temperature and humidity data from a DHT22 sensor. Finally, send the sensor data to your IoT hub.

NOTE
If you are using other ESP8266 boards, you can still follow these steps to connect it to your IoT hub. Depending on the
ESP8266 board you are using, you may need to reconfigure the LED_PIN . For example, if you are using ESP8266 from
AI-Thinker, you may change it from 0 to 2 . Don't have a kit yet?: Click here

What you will learn


How to create an IoT hub and register a device for Thing Dev.
How to connect Thing Dev with the sensor and your computer.
How to collect sensor data by running a sample application on Thing Dev.
How to send the sensor data to your IoT hub.

What you will need


To complete this operation, you need the following parts from your Thing Dev Starter Kit:
The Sparkfun ESP8266 Thing Dev board.
A Micro USB to Type A USB cable.
You also need the following for your development environment:
An active Azure subscription. If you don't have an Azure account, create a free Azure trial account in just a
few minutes.
Mac or PC that is running Windows or Ubuntu.
Wireless network for Sparkfun ESP8266 Thing Dev to connect to.
Internet connection to download the configuration tool.
Arduino IDE version 1.6.8 (or newer), earlier versions will not work with the AzureIoT library.
The following items are optional in case you don’t have a sensor. You also have the option of using simulated
sensor data.
An Adafruit DHT22 temperature and humidity sensor.
A breadboard.
M/M jumper wires.

Create an IoT hub


1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.
3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.
4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.

6. Select Review + create.


7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
Now that you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub.
In your IoT hub navigation menu, open Shared access policies. Select the iothubowner policy, and then copy
the Connection string---primary key of your IoT hub. For more information, see Control access to IoT Hub.

NOTE
You do not need this iothubowner connection string for this set-up tutorial. However, you may need it for some of the
tutorials or different IoT scenarios after you complete this set-up.

Register a device in the IoT hub for your device


1. In your IoT hub navigation menu, open IoT devices, then click Add to register a device in your IoT hub.
2. Enter a Device ID for the new device. Device IDs are case sensitive.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to
avoid any sensitive information while naming it.

3. Click Save.
4. After the device is created, open the device from the list in the IoT devices pane.
5. Copy the Connection string---primary key to use later.

Connect ESP8266 Thing Dev with the sensor and your computer
Connect a DHT22 temperature and humidity sensor to ESP8266 Thing Dev
Use the breadboard and jumper wires to make the connection as follows. If you don’t have a sensor, skip this
section because you can use simulated sensor data instead.
For sensor pins, we will use the following wiring:

START (SENSOR) END (BOARD) CABLE COLOR

VDD (Pin 27F) 3V (Pin 8A) Red cable

DATA (Pin 28F) GPIO 2 (Pin 9A) White cable

GND (Pin 30F) GND (Pin 7J) Black cable

For more information, see: DHT22 sensor setup and Sparkfun ESP8266 Thing Dev specification
Now your Sparkfun ESP8266 Thing Dev should be connected with a working sensor.
Connect Sparkfun ESP8266 Thing Dev to your computer
Use the Micro USB to Type A USB cable to connect Sparkfun ESP8266 Thing Dev to your computer as follows.

Add serial port permissions – Ubuntu only


If you use Ubuntu, make sure a normal user has the permissions to operate on the USB port of Sparkfun
ESP8266 Thing Dev. To add serial port permissions for a normal user, follow these steps:
1. Run the following commands at a terminal:

ls -l /dev/ttyUSB*
ls -l /dev/ttyACM*

You get one of the following outputs:


crw -rw ---- 1 root uucp xxxxxxxx
crw -rw ---- 1 root dialout xxxxxxxx
In the output, notice uucp or dialout that is the group owner name of the USB port.
2. Add the user to the group by running the following command:

sudo usermod -a -G <group-owner-name> <username>

<group-owner-name> is the group owner name you obtained in the previous step. <username> is your
Ubuntu user name.
3. Log out Ubuntu and log in it again for the change to take effect.

Collect sensor data and send it to your IoT hub


In this section, you deploy and run a sample application on Sparkfun ESP8266 Thing Dev. The sample
application blinks the LED on Sparkfun ESP8266 Thing Dev and sends the temperature and humidity data
collected from the DHT22 sensor to your IoT hub.
Get the sample application from GitHub
The sample application is hosted on GitHub. Clone the sample repository that contains the sample application
from GitHub. To clone the sample repository, follow these steps:
1. Open a command prompt or a terminal window.
2. Go to a folder where you want the sample application to be stored.
3. Run the following command:

git clone https://github.com/Azure-Samples/iot-hub-SparkFun-ThingDev-client-app.git

Install the package for Sparkfun ESP8266 Thing Dev in Arduino IDE:
1. Open the folder where the sample application is stored.
2. Open the app.ino file in the app folder in Arduino IDE.
3. In the Arduino IDE, click File > Preferences.
4. In the Preferences dialog box, click the icon next to the Additional Boards Manager URLs text box.
5. In the pop-up window, enter the following URL, and then click OK.
http://arduino.esp8266.com/stable/package_esp8266com_index.json

6. In the Preference dialog box, click OK.


7. Click Tools > Board > Boards Manager, and then search for esp8266. ESP8266 with a version of 2.2.0
or later should be installed.
8. Click Tools > Board > Sparkfun ESP8266 Thing Dev.
Install necessary libraries
1. In the Arduino IDE, click Sketch > Include Library > Manage Libraries.
2. Search for the following library names one by one. For each of the library you find, click Install.
AzureIoTHub
AzureIoTUtility
AzureIoTProtocol_MQTT
ArduinoJson
DHT sensor library
Adafruit Unified Sensor

Don’t have a real DHT22 sensor?


The sample application can simulate temperature and humidity data in case you don’t have a real DHT22 sensor.
To enable the sample application to use simulated data, follow these steps:
1. Open the config.h file in the app folder.
2. Locate the following line of code and change the value from false to true :

define SIMULATED_DATA true


3. Save with Control-s .
Deploy the sample application to Sparkfun ESP8266 Thing Dev
1. In the Arduino IDE, click Tool > Port, and then click the serial port for Sparkfun ESP8266 Thing Dev.
2. Click Sketch > Upload to build and deploy the sample application to Sparkfun ESP8266 Thing Dev.

NOTE
If you are using macOS you could probably see the following messages during uploading.
warning: espcomm_sync failed , error: espcomm_open failed . Please open your ternimal window and finish below
actions to solve this issue.

cd /System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns
sudo mv AppleUSBFTDI.kext AppleUSBFTDI.disabled
sudo touch /System/Library/Extensions

Enter your credentials


After the upload completes successfully, follow the steps to enter your credentials:
1. In the Arduino IDE, click Tools > Serial Monitor.
2. In the serial monitor window, notice the two drop-down lists on the bottom right corner.
3. Select No line ending for the left drop-down list.
4. Select 115200 baud for the right drop-down list.
5. In the input box located at the top of the serial monitor window, enter the following information if you are
asked to provide them, and then click Send.
Wi-Fi SSID
Wi-Fi password
Device connection string

NOTE
The credential information is stored in the EEPROM of Sparkfun ESP8266 Thing Dev. If you click the reset button on the
Sparkfun ESP8266 Thing Dev board, the sample application asks you if you want to erase the information. Enter Y to
have the information erased and you are asked to provide the information again.

Verify the sample application is running successfully


If you see the following output from the serial monitor window and the blinking LED on Sparkfun ESP8266
Thing Dev, the sample application is running successfully.

Next steps
You have successfully connected a Sparkfun ESP8266 Thing Dev to your IoT hub and sent the captured sensor
data to your IoT hub.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
Connect Adafruit Feather M0 WiFi to Azure IoT
Hub in the cloud
5/29/2018 • 8 min to read • Edit Online

In this tutorial, you begin by learning the basics of working with your Arduino board. You then learn how to
seamlessly connect your devices to the cloud by using Azure IoT Hub.

What you do
Connect Adafruit Feather M0 WiFi to an IoT hub that you create. Then you run a sample application on M0 WiFi
to collect the temperature and humidity data from a BME280. Finally, you send the sensor data to your IoT hub.

What you learn


How to create an IoT hub and register a device for Feather M0 WiFi
How to connect Feather M0 WiFi with the sensor and your computer
How to collect sensor data by running a sample application on Feather M0 WiFi
How to send the sensor data to your IoT hub

What you need

To complete this operation, you need the following parts from your Feather M0 WiFi Starter Kit:
The Feather M0 WiFi board
A Micro USB to Type A USB cable
You also need the following things for your development environment:
An active Azure subscription. If you don't have an Azure account, create a free Azure trial account in just a
few minutes.
A Mac or PC that is running Windows or Ubuntu.
A wireless network for Feather M0 WiFi to connect to.
An Internet connection to download the configuration tool.
Arduino IDE version 1.6.8 or later. Earlier versions don't work with the Azure IoT Hub library.
If you don’t have a sensor, the following items are optional. You also have the option of using simulated sensor
data:
A BME280 temperature and humidity sensor
A breadboard
M/M jumper wires

Create an IoT hub


1. Sign in to the Azure portal.
2. Select Create a resource > Internet of Things > IoT Hub.

3. In the IoT hub pane, enter the following information for your IoT hub:
Subscription: Choose the subscription that you want to use to create this IoT hub.
Resource group: Create a resource group to host the IoT hub or use an existing one. For more
information, see Use resource groups to manage your Azure resources.
Region: Select the closest location to you.
Name: Create a name for your IoT hub. If the name you enter is available, a green check mark
appears.

IMPORTANT
The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while
naming it.

4. Select Next: Size and scale to continue creating your IoT hub.
5. Choose your Pricing and scale tier. For this article, select the F1 - Free tier if it's still available on your
subscription. For more information, see the Pricing and scale tier.
6. Select Review + create.
7. Review your IoT hub information, then click Create. Your IoT hub might take a few minutes to create. You
can monitor the progress in the Notifications pane.
Now that you have created an IoT hub, locate the important information that you use to connect devices and
applications to your IoT hub.
In your IoT hub navigation menu, open Shared access policies. Select the iothubowner policy, and then copy
the Connection string---primary key of your IoT hub. For more information, see Control access to IoT Hub.

NOTE
You do not need this iothubowner connection string for this set-up tutorial. However, you may need it for some of the
tutorials or different IoT scenarios after you complete this set-up.
Register a device in the IoT hub for your device
1. In your IoT hub navigation menu, open IoT devices, then click Add to register a device in your IoT hub.

2. Enter a Device ID for the new device. Device IDs are case sensitive.

IMPORTANT
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to
avoid any sensitive information while naming it.
3. Click Save.
4. After the device is created, open the device from the list in the IoT devices pane.
5. Copy the Connection string---primary key to use later.

Connect Feather M0 WiFi with the sensor and your computer


In this section, you connect the sensors to your board. Then you plug in your device to your computer for
further use.
Connect a DHT22 temperature and humidity sensor to Feather M0 WiFi
Use the breadboard and jumper wires to make the connection. If you don’t have a sensor, skip this section
because you can use simulated sensor data instead.

For sensor pins, use the following wiring:

START (SENSOR) END (BOARD) CABLE COLOR

VDD (Pin 27A) 3V (Pin 3A) Red cable

GND (Pin 29A) GND (Pin 6A) Black cable

SCK (Pin 30A) SCK (Pin 12A) Yellow cable

SDO (Pin 31A) MI (Pin 14A) White cable

SDI (Pin 32A) M0 (Pin 13A) Blue cable


START (SENSOR) END (BOARD) CABLE COLOR

CS (Pin 33A) GPIO 5 (Pin 15J) Orange cable

For more information, see Adafruit BME280 Humidity + Barometric Pressure + Temperature Sensor Breakout
and Adafruit Feather M0 WiFi pinouts.
Now your Feather M0 WiFi should be connected with a working sensor.

Connect Feather M0 WiFi to your computer


Use the Micro USB to Type A USB cable to connect Feather M0 WiFi to your computer, as shown:
Add serial port permissions (Ubuntu only)
If you use Ubuntu, make sure you have the permissions to operate on the USB port of Feather M0 WiFi. To add
serial port permissions, follow these steps:
1. At a terminal, run the following commands:

ls -l /dev/ttyUSB*
ls -l /dev/ttyACM*

You get one of the following outputs:


crw -rw ---- 1 root uucp xxxxxxxx
crw -rw ---- 1 root dialout xxxxxxxx
In the output, notice that uucp or dialout is the group owner name of the USB port.
2. To add the user to the group, run the following command:

sudo usermod -a -G <group-owner-name> <username>

In the previous step, you obtained the group owner name <group-owner-name> . Your Ubuntu user name is
<username> .

3. For the change to appear, sign out of Ubuntu and then sign in again.

Collect sensor data and send it to your IoT hub


In this section, you deploy and run a sample application on Feather M0 WiFi. The sample application makes the
LED blink on Feather M0 WiFi. It then sends the temperature and humidity data collected from the BME280
sensor to your IoT hub.
Get the sample application from GitHub and prepare the Arduino IDE
The sample application is hosted on GitHub. Clone the sample repository that contains the sample application
from GitHub. To clone the sample repository, follow these steps:
1. Open a command prompt or a terminal window.
2. Go to a folder where you want the sample application to be stored.
3. Run the following command:

git clone https://github.com/Azure-Samples/iot-hub-Feather-M0-WiFi-client-app.git

Install the package for Feather M0 WiFi in the Arduino IDE


1. Open the folder where the sample application is stored.
2. Open the app.ino file in the app folder in the Arduino IDE.

3. Click File > Preferences (Windows/Linux) or Arduino > Preferences (Mac) and copy and paste the link
below into the Additional Boards Manager URLs option in the Arduino IDE preferences.

https://adafruit.github.io/arduino-board-index/package_adafruit_index.json

4. Click Tools > Board > Boards Manager, and then install the Arduino SAMD Boards version 1.6.2 or
later.
5. Then in the same window, install Adafruit SAMD Boards package to add the board file definitions.
6. Click Tools > Board > Adafruit M0 WiFi.
7. Install drivers (for Windows only). When you plug in Feather M0 WiFi, you might need to install a driver.
Click the download link on the webpage to download the driver installer. Follow the steps to install the
drivers you want.
Install necessary libraries
1. In the Arduino IDE, click Sketch > Include Library > Manage Libraries.
2. Search for the following library names one by one. For each library that you find, click Install:
RTCZero
NTPClient
AzureIoTHub
AzureIoTUtility
AzureIoTProtocol_HTTP
ArduinoJson
Adafruit BME280 Library
Adafruit Unified Sensor
3. Manually install Adafruit_WINC1500 . Go to this website and click Clone or download > Download ZIP.
Then in your Arduino IDE, go to Sketch > Include Library > Add .zip Library and add the zip file.
Use the sample application if you don’t have a real BME280 sensor
If you don’t have a real BME280 sensor, the sample application can simulate temperature and humidity data. To
set up the sample application to use simulated data, follow these steps:
1. Open the config.h file in the app folder.
2. Locate the following line of code and change the value from false to true :

define SIMULATED_DATA true


3. Save the file with Control-s .
Deploy the sample application to Feather M0 WiFi
1. In the Arduino IDE, click Tool > Port, and then click the serial port for Feather M0 WiFi.
2. Click Sketch > Upload to build and deploy the sample application to Feather M0 WiFi.
Enter your credentials
After the upload completes successfully, follow these steps to enter your credentials:
1. In the Arduino IDE, click Tools > Serial Monitor.
2. In the lower-right corner of the serial monitor window, select No line ending in the drop-down list on
the left.
3. Select 115200 baud in the drop-down list on the right.
4. In the input box at the top, enter the following information if you're asked to provide it, and click Send:
Wi-Fi SSID
Wi-Fi password
Device connection string

NOTE
The credential information is stored in the EEPROM of Feather M0 WiFi. If you click the reset button on the Feather M0
WiFi board, the sample application asks if you want to erase the information. Enter Y to erase the information. You're
asked to provide the information a second time.

Verify that the sample application is running successfully


If you see the following output from the serial monitor window and the blinking LED on Feather M0 WiFi, the
sample application is running successfully:

Next steps
You have successfully connected Feather M0 WiFi to your IoT hub and sent the captured sensor data to your IoT
hub.
To continue to get started with Azure IoT Hub and to explore other IoT scenarios, see the following:
Manage cloud device messaging with iothub-explorer
Save your Azure IoT hub messages to Azure data storage
Use Power BI to visualize real-time sensor data from your IoT hub
Use the Web Apps feature of Azure App Service to visualize real-time sensor data from your IoT hub
Forecast weather by using the sensor data from your IoT hub in Azure Machine Learning
Manage devices with iothub-explorer
Use Logic Apps for remote monitoring and notifications
How to upgrade your IoT hub
5/29/2018 • 1 min to read • Edit Online

As your IoT solution grows, Azure IoT Hub is ready to help you scale up. Azure IoT Hub offers two tiers, basic (B )
and standard (S ), to accommodate customers that want to use different features. Within each tier are three sizes
(1, 2, and 3) that determine the number of messages that can be sent each day.
When you have more devices and need more capabilities, there are three ways to adjust your IoT hub to suit your
needs:
Add units within the IoT hub. For example, each additional unit in a B1 IoT hub allows for an additional
400,000 messages per day.
Change the size of the IoT hub. For example, migrate from the B1 tier to the B2 tier to increase the amount of
messages that each unit can support per day.
Upgrade to a higher tier. For example, upgrade from the B1 tier to the S1 tier for the same messaging capacity
but with the advanced features that come in the standard tier.
These changes can all occur without interrupting existing operations.
If you want to downgrade your IoT hub, you can remove units and reduce the size of the IoT hub. However, you
cannot downgrade to a lower tier. For example, you can move from the S2 tier to the S1 tier, but not from the S2
tier to the B1 tier.
These examples are meant to help you understand how to adjust your IoT hub as your solution changes. For
specific information about each tier's capabilities you should always refer to Azure IoT Hub pricing.

Upgrade your existing IoT hub


1. Sign in to the Azure portal and navigate to your IoT hub.
2. Select Pricing and scale.
3. To change the tier for your hub, select Pricing and scale tier. Choose the new tier, then click select.

4. To change the number of units in your hub, enter a new value under IoT Hub units.
5. Select Save to save your changes.
Your IoT hub is now adjusted, and your configurations are unchanged.

Next steps
Get more details about How to choose the right IoT Hub tier.
Understand IoT Hub metrics
5/29/2018 • 6 min to read • Edit Online

IoT Hub metrics give you better data about the state of the Azure IoT resources in your Azure subscription. IoT
Hub metrics enable you to assess the overall health of the IoT Hub service and the devices connected to it. User-
facing statistics are important because they help you see what is going on with your IoT hub and help root-cause
issues without needing to contact Azure support.
Metrics are enabled by default. You can view IoT Hub metrics from the Azure portal.

How to view IoT Hub metrics


1. Create an IoT hub. You can find instructions on how to create an IoT hub in the Get Started guide.
2. Open the blade of your IoT hub. From there, click Metrics.

3. From the metrics blade, you can view the metrics for your IoT hub and create custom views of your
metrics. You can choose to send your metrics data to an Event Hubs endpoint or an Azure Storage
account by clicking Diagnostics settings.
IoT Hub metrics and how to use them
IoT Hub provides several metrics to give you an overview of the health of your hub and the total number of
connected devices. You can combine information from multiple metrics to paint a bigger picture of the state of
the IoT hub. The following table describes the metrics each IoT hub tracks, and how each metric relates to the
overall status of the IoT hub.

METRIC METRIC DISPLAY NAME UNIT AGGREGATION TYPE DESCRIPTION

d2c.telemetry.ingress. Telemetry message Count Total Number of device-to-


allProtocol send attempts cloud telemetry
messages attempted
to be sent to your
IoT hub

d2c.telemetry.ingress. Telemetry messages Count Total Number of device-to-


success sent cloud telemetry
messages sent
successfully to your
IoT hub

c2d.commands.egres Commands Count Total Number of cloud-to-


s.complete.success completed device commands
completed
successfully by the
device

c2d.commands.egres Commands Count Total Number of cloud-to-


s.abandon.success abandoned device commands
abandoned by the
device
METRIC METRIC DISPLAY NAME UNIT AGGREGATION TYPE DESCRIPTION

c2d.commands.egres Commands rejected Count Total Number of cloud-to-


s.reject.success device commands
rejected by the device

devices.totalDevices Total devices Count Total Number of devices


registered to your IoT
hub

devices.connectedDe Connected devices Count Total Number of devices


vices.allProtocol connected to your
IoT hub

d2c.telemetry.egress. Telemetry messages Count Total Number of times


success delivered messages were
successfully written
to endpoints (total)

d2c.telemetry.egress. Dropped messages Count Total Number of messages


dropped dropped because
they did not match
any routes and the
fallback route was
disabled

d2c.telemetry.egress. Orphaned messages Count Total The count of


orphaned messages not
matching any routes
including the fallback
route

d2c.telemetry.egress.i Invalid messages Count Total The count of


nvalid messages not
delivered due to
incompatibility with
the endpoint

d2c.telemetry.egress.f Messages matching Count Total Number of messages


allback fallback condition written to the fallback
endpoint

d2c.endpoints.egress. Messages delivered Count Total Number of times


eventHubs to Event Hub messages were
endpoints successfully written
to Event Hub
endpoints

d2c.endpoints.latency Message latency for Milliseconds Average The average latency


.eventHubs Event Hub endpoints between message
ingress to the IoT
hub and message
ingress into an Event
Hub endpoint, in
milliseconds
METRIC METRIC DISPLAY NAME UNIT AGGREGATION TYPE DESCRIPTION

d2c.endpoints.egress. Messages delivered Count Total Number of times


serviceBusQueues to Service Bus Queue messages were
endpoints successfully written
to Service Bus Queue
endpoints

d2c.endpoints.latency Message latency for Milliseconds Average The average latency


.serviceBusQueues Service Bus Queue between message
endpoints ingress to the IoT
hub and message
ingress into a Service
Bus Queue endpoint,
in milliseconds

d2c.endpoints.egress. Messages delivered Count Total Number of times


serviceBusTopics to Service Bus Topic messages were
endpoints successfully written
to Service Bus Topic
endpoints

d2c.endpoints.latency Message latency for Milliseconds Average The average latency


.serviceBusTopics Service Bus Topic between message
endpoints ingress to the IoT
hub and message
ingress into a Service
Bus Topic endpoint, in
milliseconds

d2c.endpoints.egress. Messages delivered Count Total Number of times


builtIn.events to the built-in messages were
endpoint successfully written
(messages/events) to the built-in
endpoint
(messages/events)

d2c.endpoints.latency Message latency for Milliseconds Average The average latency


.builtIn.events the built-in endpoint between message
(messages/events) ingress to the IoT
hub and message
ingress into the built-
in endpoint
(messages/events), in
milliseconds

d2c.twin.read.success Successful twin reads Count Total The count of all


from devices successful device-
initiated twin reads.

d2c.twin.read.failure Failed twin reads Count Total The count of all failed
from devices device-initiated twin
reads.

d2c.twin.read.size Response size of twin Bytes Average The average, min,


reads from devices and max of all
successful device-
initiated twin reads.
METRIC METRIC DISPLAY NAME UNIT AGGREGATION TYPE DESCRIPTION

d2c.twin.update.succ Successful twin Count Total The count of all


ess updates from devices successful device-
initiated twin
updates.

d2c.twin.update.failur Failed twin updates Count Total The count of all failed
e from devices device-initiated twin
updates.

d2c.twin.update.size Size of twin updates Bytes Average The average, min,


from devices and max size of all
successful device-
initiated twin
updates.

c2d.methods.success Successful direct Count Total The count of all


method invocations successful direct
method calls.

c2d.methods.failure Failed direct method Count Total The count of all failed
invocations direct method calls.

c2d.methods.request Request size of direct Bytes Average The average, min,


Size method invocations and max of all
successful direct
method requests.

c2d.methods.respons Response size of Bytes Average The average, min,


eSize direct method and max of all
invocations successful direct
method responses.

c2d.twin.read.success Successful twin reads Count Total The count of all


from back end successful back-end-
initiated twin reads.

c2d.twin.read.failure Failed twin reads Count Total The count of all failed
from back end back-end-initiated
twin reads.

c2d.twin.read.size Response size of twin Bytes Average The average, min,


reads from back end and max of all
successful back-end-
initiated twin reads.

c2d.twin.update.succ Successful twin Count Total The count of all


ess updates from back successful back-end-
end initiated twin
updates.

c2d.twin.update.failur Failed twin updates Count Total The count of all failed
e from back end back-end-initiated
twin updates.
METRIC METRIC DISPLAY NAME UNIT AGGREGATION TYPE DESCRIPTION

c2d.twin.update.size Size of twin updates Bytes Average The average, min,


from back end and max size of all
successful back-end-
initiated twin
updates.

twinQueries.success Successful twin Count Total The count of all


queries successful twin
queries.

twinQueries.failure Failed twin queries Count Total The count of all failed
twin queries.

twinQueries.resultSiz Twin queries result Bytes Average The average, min,


e size and max of the result
size of all successful
twin queries.

jobs.createTwinUpdat Successful creations Count Total The count of all


eJob.success of twin update jobs successful creation of
twin update jobs.

jobs.createTwinUpdat Failed creations of Count Total The count of all failed


eJob.failure twin update jobs creation of twin
update jobs.

jobs.createDirectMet Successful creations Count Total The count of all


hodJob.success of method invocation successful creation of
jobs direct method
invocation jobs.

jobs.createDirectMet Failed creations of Count Total The count of all failed


hodJob.failure method invocation creation of direct
jobs method invocation
jobs.

jobs.listJobs.success Successful calls to list Count Total The count of all


jobs successful calls to list
jobs.

jobs.listJobs.failure Failed calls to list jobs Count Total The count of all failed
calls to list jobs.

jobs.cancelJob.succes Successful job Count Total The count of all


s cancellations successful calls to
cancel a job.

jobs.cancelJob.failure Failed job Count Total The count of all failed


cancellations calls to cancel a job.

jobs.queryJobs.succes Successful job queries Count Total The count of all


s successful calls to
query jobs.
METRIC METRIC DISPLAY NAME UNIT AGGREGATION TYPE DESCRIPTION

jobs.queryJobs.failure Failed job queries Count Total The count of all failed
calls to query jobs.

jobs.completed Completed jobs Count Total The count of all


completed jobs.

jobs.failed Failed jobs Count Total The count of all failed


jobs.

Next steps
Now that you’ve seen an overview of IoT Hub metrics, follow this link to learn more about managing Azure IoT
Hub:
Operations monitoring
To further explore the capabilities of IoT Hub, see:
IoT Hub developer guide
Deploying AI to edge devices with Azure IoT Edge
Use IP filters
5/29/2018 • 3 min to read • Edit Online

Security is an important aspect of any IoT solution based on Azure IoT Hub. Sometimes you need to explicitly
specify the IP addresses from which devices can connect as part of your security configuration. The IP filter feature
enables you to configure rules for rejecting or accepting traffic from specific IPv4 addresses.

When to use
There are two specific use-cases when it is useful to block the IoT Hub endpoints for certain IP addresses:
Your IoT hub should receive traffic only from a specified range of IP addresses and reject everything else. For
example, you are using your IoT hub with Azure Express Route to create private connections between an IoT
hub and your on-premises infrastructure.
You need to reject traffic from IP addresses that have been identified as suspicious by the IoT hub administrator.

How filter rules are applied


The IP filter rules are applied at the IoT Hub service level. Therefore the IP filter rules apply to all connections from
devices and back-end apps using any supported protocol.
Any connection attempt from an IP address that matches a rejecting IP rule in your IoT hub receives an
unauthorized 401 status code and description. The response message does not mention the IP rule.

Default setting
By default, the IP Filter grid in the portal for an IoT hub is empty. This default setting means that your hub accepts
connections any IP address. This default setting is equivalent to a rule that accepts the 0.0.0.0/0 IP address range.

Add or edit an IP filter rule


When you add an IP filter rule, you are prompted for the following values:
An IP filter rule name that must be a unique, case-insensitive, alphanumeric string up to 128 characters long.
Only the ASCII 7-bit alphanumeric characters plus
{'-', ':', '/', '\', '.', '+', '%', '_', '#', '*', '?', '!', '(', ')', ',', '=', '@', ';', '''} are accepted.
Select a reject or accept as the action for the IP filter rule.
Provide a single IPv4 address or a block of IP addresses in CIDR notation. For example, in CIDR notation
192.168.100.0/22 represents the 1024 IPv4 addresses from 192.168.100.0 to 192.168.103.255.

After you save the rule, you see an alert notifying you that the update is in progress.

The Add option is disabled when you reach the maximum of 10 IP filter rules.
You can edit an existing rule by double-clicking the row that contains the rule.
NOTE
Rejecting IP addresses can prevent other Azure Services (such as Azure Stream Analytics, Azure Virtual Machines, or the
Device Explorer in the portal) from interacting with the IoT hub.

WARNING
If you use Azure Stream Analytics (ASA) to read messages from an IoT hub with IP filtering enabled, use the Event Hub-
compatible name and endpoint of your IoT Hub in the ASA connection string.

Delete an IP filter rule


To delete an IP filter rule, select one or more rules in the grid and click Delete.

IP filter rule evaluation


IP filter rules are applied in order and the first rule that matches the IP address determines the accept or reject
action.
For example, if you want to accept addresses in the range 192.168.100.0/22 and reject everything else, the first rule
in the grid should accept the address range 192.168.100.0/22. The next rule should reject all addresses by using the
range 0.0.0.0/0.
You can change the order of your IP filter rules in the grid by clicking the three vertical dots at the start of a row
and using drag and drop.
To save your new IP filter rule order, click Save.
Next steps
To further explore the capabilities of IoT Hub, see:
Operations monitoring
IoT Hub metrics
Configure and monitor IoT devices at scale - preview
5/29/2018 • 7 min to read • Edit Online

Automatic device management in Azure IoT Hub automates many of the repetitive and complex tasks of
managing large device fleets over the entirety of their lifecycles. With automatic device management, you can
target a set of devices based on their properties, define a desired configuration, and let IoT Hub update devices
whenever they come into scope. This is performed using an automatic device configuration, which will also allow
you to summarize completion and compliance, handle merging and conflicts, and roll out configurations in a
phased approach.

NOTE
The features described in this article are only available in the standard tier of IoT hub. For more information about the basic
and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

Automatic device configurations work by updating a set of device twins with desired properties and reporting a
summary based on device twin reported properties. It introduces a new class and JSON document called a
Configuration which has three parts:
The target condition defines the scope of device twins to be updated. The target condition is specified as
a query on device twin tags and/or reported properties.
The target content defines the desired properties to be added or updated in the targeted device twins.
The content includes a path to the section of desired properties to be changed.
The metrics define the summary counts of various configuration states such as Success, In Progress, and
Error. Custom metrics are specified as queries on device twin reported properties. System metrics are
default metrics that measure twin update status, such as the number of device twins that are targeted and
the number of twins that have been successfully updated.

NOTE
During preview, this feature is not available for IoT Hubs in East US, West US, North Europe, and West Europe regions.

Implement device twins to configure devices


Automatic device configurations require the use of device twins to synchronize state between the cloud and
devices. Refer to Understand and use device twins in IoT Hub for guidance on using device twins.

Identify devices using tags


Before you can create a configuration, you must specify which devices you want to affect. Azure IoT Hub
identifies devices using tags in the device twin. Each device can have multiple tags, and you can define them any
way that makes sense for your solution. For example, if you manage devices in different locations, you may add
the following tags to a device twin:
"tags": {
"location": {
"state": "Washington",
"city": "Tacoma"
}
},

Create a configuration
1. In the Azure portal, go to your IoT hub.
2. Select IoT device configuration (preview).
3. Select Add Configuration.
There are five steps to create a configuration. The following sections walk through each one.
Step 1: Name and Label
1. Give your configuration a unique name that is up to 128 lowercase letters. Avoid spaces and the following
invalid characters: & ^ [ ] { } \ | " < > / .
2. Add labels to help track your configurations. Labels are Name, Value pairs that describe your configuration.
For example, HostPlatform, Linux or Version, 3.0.1 .
3. Select Next to move to step two.
Step 2: Specify Settings
This section specifies the target content to be set in targeted device twins. There are two inputs for each set of
settings. The first is the device twin path, which is the path to the JSON section within the twin desired properties
that will be set. The second is the JSON content to be inserted in that section. For example, set the Device Twin
Path and Content to the following:

You can also set individual settings by specifying the entire path in the Device Twin Path and the value in the
Content with no brackets. For example, set the Device Twin Path to properties.desired.chiller-water.temperature
and set the Content to: 66
If two or more configurations target the same Device Twin Path, the Content from the highest priority
configuration will apply (priority is defined in Step 4).
If you wish to remove a property, specify the property value to null .
You can add additional settings by selecting Add Device Twin Setting
Step 3: Specify Metrics (optional)
Metrics provide summary counts of the various states that a device may report back as a result of applying
configuration content. For example, you may create a metric for pending settings changes, a metric for errors, and
a metric for successful settings changes.
1. Enter a name for Metric Name
2. Enter a query for Metric Criteria. The query is based on device twin reported properties. The metric
represents the number of rows returned by the query.
For example: SELECT deviceId FROM devices WHERE properties.reported.chillerWaterSettings.status='pending'

You can include a clause that the configuration was applied, for example:
SELECT deviceId FROM devices WHERE configurations.[[yourconfigname]].status='Applied' including the double
brackets.
Step 4: Target Devices
Use the tags property from your device twins to target the specific devices that should receive this configuration.
You can also target devices by device twin reported properties.
Since multiple configurations may target the same device, you should give each configuration a priority number.
If there's ever a conflict, the configuration with the highest priority wins.
1. Enter a positive integer for the configuration Priority. Highest numerical value is considered the highest
priority. If two configurations have the same priority number, the one that was created most recently wins.
2. Enter a Target condition to determine which devices will be targeted with this configuration. The condition is
based on device twin tags or device twin reported properties and should match the expression format. For
example, tags.environment='test' or properties.reported.chillerProperties.model='4000x' .
3. Select Next to move on to the final step.
Step 5: Review Configuration
Review your configuration information, then select Submit.

Monitor a configuration
To view the details of a configuration and monitor the devices running it, use the following steps:
1. In the Azure portal, go to your IoT hub.
2. Select IoT device configuration (preview).
3. Inspect the configuration list. For each configuration, you can view the following details:
ID - the name of the configuration.
Target condition - the query used to define targeted devices.
Priority - the priority number assigned to the configuration.
Creation time - the timestamp from when the configuration was created. This timestamp is used to
break ties when two configurations have the same priority.
System metrics - metrics that are calculated by IoT Hub and cannot be customized by developers.
Targeted specifies the number of device twins that match the target condition. Applies specified the
number of device twins that have been modified by the configuration, which can include partial
modifications in the event that a separate, higher priority configuration also made changes.
Custom metrics - metrics that have been specified by the developer as queries against device twin
reported properties. Up to five custom metrics can be defined per configuration.
4. Select the configuration that you want to monitor.
5. Inspect the configuration details. You can use tabs to view specific details about the devices that received the
configuration:
Target Condition - the devices that match the target condition.
Metrics - a list of system metrics and custom metrics. You can view a list of devices that are counted for
each metric by selecting the metric in the drop-down and then selecting View Devices.
Device Twin Settings - the device twin settings that are set by the configuration.
Configuration Labels - key-value pairs used to describe a configuration. Labels have no impact on
functionality.

Modify a configuration
When you modify a configuration, the changes immediately replicate to all targeted devices.
If you update the target condition, the following updates occur:
If a device twin didn't meet the old target condition, but meets the new target condition and this configuration
is the highest priority for that device twin, then this configuration is applied to the device twin.
If a device twin no longer meets the target condition, the settings from the configuration will be removed and
the device twin will be modified by the next highest priority configuration.
If a device twin currently running this configuration no longer meets the target condition and doesn't meet the
target condition of any other configurations, then the settings from the configuration will be removed and no
other changes will be made on the twin.
To modify a configuration, use the following steps:
1. In the Azure portal, go to your IoT hub.
2. Select IoT device configuration (preview).
3. Select the configuration that you want to modify.
4. Make updates to the following fields:
Target condition
Labels
Priority
Metrics
5. Select Save.
6. Follow the steps in [Monitor a configuration][anchor-monitor] to watch the changes roll out.

Delete a configuration
When you delete a configuration, any device twins take on their next highest priority configuration. If device twins
don't meet the target condition of any other configuration, then no other settings are applied.
1. In the Azure portal, go to your IoT hub.
2. Select IoT device configuration (preview).
3. Use the checkbox to select the configuration that you want to delete.
4. Select Delete.
5. A prompt will ask you to confirm.

Next steps
In this article, you learned how configure and monitor IoT devices at scale. Follow these links to learn more about
managing Azure IoT Hub:
Manage your IoT Hub device identities in bulk
IoT Hub metrics
Operations monitoring
To further explore the capabilities of IoT Hub, see:
IoT Hub developer guide
Deploying AI to edge devices with Azure IoT Edge
To explore using the IoT Hub Device Provisioning Service to enable zero-touch, just-in-time provisioning, see:
Azure IoT Hub Device Provisioning Service
Summary of customer data request features
5/29/2018 • 2 min to read • Edit Online

The Azure IoT Hub is a REST API-based cloud service targeted at enterprise customers that enables secure, bi-
directional communication between millions of devices and a partitioned Azure service.

NOTE
This article provides steps for how to delete personal data from the device or service and can be used to support your
obligations under the GDPR. If you’re looking for general info about GDPR, see the GDPR section of the Service Trust portal.

Individual devices are assigned a device identifier (device ID ) by a tenant administrator. Device data is based on the
assigned device ID. Microsoft maintains no information and has no access to data that would allow device ID to
user correlation.
Many of the devices managed in Azure IoT Hub are not personal devices, for example an office thermostat or
factory robot. Customers may, however, consider some devices to be personally identifiable and at their discretion
may maintain their own asset or inventory tracking methods that tie devices to individuals. Azure IoT Hub
manages and stores all data associated with devices as if it were personal data.
Tenant administrators can use either the Azure portal or the service's REST APIs to fulfill information requests by
exporting or deleting data associated with a device ID.
If you use the routing feature of the Azure IoT Hub service to forward device messages to other services, then data
requests must be performed by the tenant admin for each routing endpoint in order to complete a full request for a
given device. See each endpoint's reference documentation for further details. For more information about
supported endpoints, see Reference - IoT Hub endpoints.
If you use the Azure Event Grid integration feature of the Azure IoT Hub service, then data requests must be
performed by the tenant admin for each subscriber of these events. For more information, see React to IoT Hub
events by using Event Grid.
If you use the Azure Monitor integration feature of the Azure IoT Hub service to create diagnostic logs, then data
requests must be performed by the tenant admin against the stored logs. For more information, see Monitor the
health of Azure IoT Hub.

Deleting customer data


Tenant administrators can use the IoT devices blade of the Azure IoT Hub extension in the Azure portal to delete a
device, which deletes the data associated with that device.
It is also possible to perform delete operations for devices using REST APIs. For more information, see Device Api
- Delete Device.

Exporting customer data


Tenant administrators can utilize copy and paste within the IoT devices blade of the Azure IoT Hub extension in the
Azure portal to export data associated with a device.
It is also possible to perform export operations for devices using REST APIs. For more information, see Device Api
- Get Device.
NOTE
When you use Microsoft's enterprise services, Microsoft generates some information, known as system-generated logs. Some
Azure IoT Hub system-generated logs are not accessible or exportable by tenant administrators. These logs constitute factual
actions conducted within the service and diagnostic data related to individual devices.

Links to additional documentation


Full documentation for Azure IoT Hub Device APIs is located at
https://docs.microsoft.com/rest/api/iothub/deviceapi.

You might also like