IoT Hub and Azure Time Series Insights

Azure Time Series Insights is a new service that makes it very easy to store and visualize time series data. In this blog post, we will create a dashboard that looks like the one below (click to enlarge):


The dashboard has four sections:

  • Query1: a heat map of events per device; in this case there are 20 devices sending data every 2 seconds
  • Query2: a line graph with random “temperature” data
  • Query3: a line graph with both “temperature” and “humidity” data
  • Query4: a line graph with “humidity” data

The events are sent to an IoT Hub using the following JSON shape: {temperature: x, humidity: y} where x and y are randomized floating point numbers, generated by an IoT device simulator.

Step 1: Create IoT Hub

Install Azure CLI 2.0, and then use az login to login. Use az account list to list your subscriptions and use az account set –subscription name_or_id to set the default subscription. Next, issue the following commands to create a resource group and an IoT Hub (set location to your preference):

az group create --name resource_group_name --location westeurope
az iot hub create --sku F1 --name iot_hub_name --resource-group resource_group_name

As a best practice, create a separate consumer group on the Events endpoint. In the Azure Portal, in the properties of the IoT Hub, click Endpoints. Then click Events and add a consumer group underneath $Default. Click Save.

Record the Connection String – primary key setting of the device or  iothubowner Shared access policy. Click Shared Access Policies, and device to find this connection string. It will be in the form of:;SharedAccessKeyName=keyname;SharedAccessKey=b5dARuGPhL6wdgHboUIhEC6LlcFalIjfEdh4aXYa1WI=

You will need this connection string later to configure the IoT Simulator.

Step 2: Create Time Series Insights Environment

In the Azure Portal, click the green + and navigate to Internet of Things. Click Time Series Insights and follow the on-screen instructions. You will end up with:


I selected one unit of the S1 tier which is more than enough for this example.

Step 3: Set Data Access Policy

Even though you created the Time Series Insights Environment, you still need to grant yourself access to the data. Click Data Access Policies and add your user or group and a role of Contributor.


Step 4: Add Event Source

We will add the IoT Hub we created earlier as an event source. Click Event Sources and then click Add. Give the event source a name and set the source to IoT Hub. Then select an IoT Hub from your available subscriptions and do not forget to set the consumer group to the one you created in step 1. If your event data has a timestamp, you can enter the timestamp property name. If you do not specify the timestamp, the event enqueue time set by the IoT Hub will be used.

Note that Azure Time Series Insights also supports Event Hubs as an event source.

Step 5: Configure the IoT simulator

Head over to and download iot-simulator.exe to a folder of your choice. In the same folder add a file called config.json with the following contents:

     "SasTokens":["SharedAccessSignature sr=..."],
        {"Prefix":"ts","DeviceNum":20,"Firmware":"1.0","IoTHub": 0}

In the SasTokens array, replace SharedAccessSignature sr=… with a Sas token that has the necessary rights to submit events to the IoT Hub. One way of doing so, is with Device Explorer. Once installed, copy the connection string from step 1 in the connection string box and click Generate SAS. Copy the Sas token in the config.json file.


With the config.json correctly configured, from a command prompt, start iot-simulator.exe. It will connect to the IoT Hub, create the devices and start sending data every 5 seconds from every device. In the sample config file, you can set the interval in seconds (Interval) and the amount of devices (DeviceNum). To clean up the devices, run iot-simulator.exe –r.

Step 6: Visualize the data

Now go to and login with the credentials you used in step 3. You will get a screen to select data. I selected Last 60 Mins from the quick times dropdown and then clicked the search icon:


In the following screen, click Heatmap and then configure the box at the left with a descriptive title. Also select a split by deviceid to have an idea about the number of events per time window per device and to spot devices that stopped sending data.


Now, at the right top corner, click the circle with the four squares. You end up with:


Now click the + in the top, right section. Select a time range again and then, at the left, change the measure from Events to Temperature. Automatically, the temperature will be averaged over the interval size. Change the term (Term 1) to Temperature and click the circle with the four squares again.

The temperature line graph has been added and you can now click the copy icon and create the same visualization for humidity.


Now it’s easy to create the other panel with both temperature and humidity. Give it a go and try out other visualizations. When you are finished, you can click the Save icon and save this perspective. Yep, these visualizations are called perspectives!

It’s still early days for the service and many features will be added in the near future. If you are already working with event data coming into an Event Hub and IoT Hub, it should be easy to add a new consumer group and start analyzing the data with this service.

Adding natural language to your Bot

In the last post, Bots in an IoT context, I created a very simple bot to request the air quality in a room. To change the room, you had to type change room and then type the room name when requested. It would be much nicer to be able to give commands like change room to <roomname> or set the room to <roomname> or switch room to <roomname>. Instead of using regular expressions, you should use the Language Understanding Intelligent Service or LUIS in short.

In LUIS, you first create an app. In the app, you define things like intents and entities. In this case, I only need one intent which I called ChangeRoom. Because I am going to specify the name of the room in phrases I type, I also defined an entity called room.


Next, you need to specify utterances and tell LUIS what the intent of the utterance is (if LUIS does not match your intent to the utterance automatically). The example below shows an example utterance:


When you type the utterance and click the orange arrow, LUIS will analyze the utterance. In the case above, LUIS automatically matched the utterance to the ChangeRoom intent and also marked the word asterix as an entity. If you hover over the entity, you will see the entity name, in this case room.

You should enter several utterances that make sense for your scenario and fix the intent and entity if needed. After adding several utterances, it is time to train the model with the tiny link in the bottom left of the browser.

After training, it is time to publish the application. You will get a URL that you need to supply in your bot. You can also test some queries from the publish dialog. For instance:


If you click the link for the query above, you get a JSON response like below:


What you see in the response above, is that LUIS matched the query to intent ChangeRoom and that the room entity is set to Asterix with a score of 0.948. Great!!

Now it is time to use this in your bot. You will need the following code to be able to use the LUIS app from your code and use the LUIS recognizer in the intents:


Obviously, you set the URL of the recognizer to the URL you received after publishing the LUIS app. Next, use the LUIS intent (ChangeRoom remember), in your code as follows:


In the above code, the important part is extracting the room entity. We make sure that, when a room entity is not found, we give the user a message. Otherwise, we set the room in userData.roomName.

Now it is time to test the code in Slack or another service. Everything was set up in the previous post, so we just need to push the code changes to Azure App Services (git push azure commit). Just for fun, I will show the results in Skype:


As you can see, many different phrases can be used. Not all of them were entered in LUIS. Of course, not all phrases will work. It’s clear that new place is Obelix does not work. However, it’s very simple to go back to the LUIS app and add extra utterances, train the model and publish it again.

To sum things up:

  • Regular expressions are great to get started
  • Use LUIS to add natural language processing to your bot in a simple and intuitive way