Brewing Beer With a Raspberry Pi: Reporting Measurements to Azure IoT Hub

DZone 's Guide to

Brewing Beer With a Raspberry Pi: Reporting Measurements to Azure IoT Hub

The series on monitoring beer with a Raspberry Pi continues as measurements are reported to Microsoft Azure's IoT Hub.

· IoT Zone ·
Free Resource

As we have now fully functioning thermal solution running on Windows 10 IoT Core it’s time to focus to other components of our beer freezing solution. Our solution measures and calculates metrics of cooling beer but it doesn’t report this data anywhere. In this blog post we will set up Azure IoT Hub for our solution so it starts reporting measurements to Microsoft Azure.

Why Azure IoT Hub?

We are using Azure IoT Hub because it supports device-to-cloud and cloud-to-device messaging scenarios. In our case:

  • Device-to-cloud: our beer cooling solution will report all measurements and status feedback to Azure IoT Hub.
  • Cloud-to-device: we use Azure IoT Hub to control beer cooling solution so it doesn’t have any need for additional services to control it.

Azure Event Hub supports only device-to-cloud scenarios and it has some additional limits coming form Azure Service Bus on what it is built on. To find out more about differences between Azure IoT Hub and Event Hubs go to the page Comparison of IoT Hub and Event Hubs.

NB! From this point on I expect you have created empty Azure IoT Hub on Microsoft Azure and it is ready for use. LINK!!!

Registering Device

When we add new device we have to register it in our IoT Hub. We have to do it in code. Based on the registration device gets access token that is used to communicate with IoT Hub.

NB! You have to create new Console Application to register your device. The library you are using for this doesn’t support Universal Windows Applications. It works only with full .NET Framework.

Take the code from the Azure IoT Hub documentation page: get started with Azure IoT Hub for .NET. Here’s my simple code that worked from the first shot as soon as the connection string was correct.

namespace ConsoleApplication1
    class Program
        static RegistryManager registryManager;
        static string connectionString = "Connection to IoT Hub";

        static void Main(string[] args)
            var deviceId = "MyDevice";
            registryManager = RegistryManager.CreateFromConnectionString(connectionString);
            var deviceTask = registryManager.AddDeviceAsync(new Device(deviceId));
            Console.WriteLine("Key: {0}", deviceTask.Result.Authentication.SymmetricKey.PrimaryKey);

You can find connection string from your Azure IoT Hub settings page under Shared access policies –> iothubowner.

Update Current Time on Raspberry Pi

Before we can report measurements we have to make sure that we don’t run into time related issues with the SAS token we are using to access IoT Hub. On Windows 10 IoT Core for some reason, the clock is an hour or two behind. We have to set it to the current time using PowerShell.

Log in to your Raspberry Pi using PowerShell like shown on this page: using PowerShell to connect and configure a device running Windows 10 IoT Core. Now go through the following steps:

  1. Check the current time using Get-Date command.
  2. If time is correct then close PowerShell.
  3. If time is not correct then check how many hours it is behind current time.
  4. Run Set.Date (Get-Date).AddHours(number of hours) to set clock to current time.
  5. Close PowerShell.

For some reason my Raspberry Pi is not able to connect to the time servers, and I had to set the correct current time manually through PowerShell.

Reporting Measurements

Now let’s connect background service to Azure IoT Hub.

NB! We are using code from my previous BeerIoT posting . You can find Startup class from the post . Through previous postings, we have added new stuff to the original code, so make sure you go through the previous posts.

To keep things simple we add some new fields to the Startup class.

private const string iotHubUri = "<host>.azure-devices.net";
private const string deviceKey = "key we got above";

As host, URI insert your Azure IoT Hub URL. You can find it in the essential information block on the hub main page. As a device key, use the key we got from the console application above.

To communicate with Azure IoT Hub, we need a Nuget package. Add package Microsoft.Azure.Devices.Client to your background service project.

Adding Microsoft.Azure.Devices.Client package from Nuget

When service starts we have to connect to Azure IoT Hub. It’s better to keep one client instance alive than creating one every time we have to report measurements. We'll add a new class level member to Startup class:

privateDeviceClient _deviceClient;

When Run method is called we instantiate this field:

public void Run(IBackgroundTaskInstance taskInstance)
    taskInstance.Canceled += TaskInstance_Canceled;

    _deviceClient = DeviceClient.Create(iotHubUri, 
 new DeviceAuthenticationWithRegistrySymmetricKey("MyDevice", deviceKey), 

    _tempClient = new TemperatureClient();
    _timer = new Timer(TemperatureCallback, null, 0, 5000);            


NB! It’s important to use Http1 as transport type because Advanced Message Queuing Protocol (AMQP) is not supported in Universal Windows Application projects yet...

Now let’s write a method to report measurements to Azure IoT Hub.

private void ReportMeasurement(DateTime time, double beerTemp, 
 double ambientTemp, double estimate)
    var beerMeasurement = new
        deviceId = "MyDevice",
        timeStamp = time,
        beerTemp = beerTemp,
        ambientTemp = ambientTemp,
        estimate = estimate

    var messageString = JsonConvert.SerializeObject(beerMeasurement);
    var message = new Message(Encoding.ASCII.GetBytes(messageString));


When the timer elapses and the callback is called, we must call this method to report measurements to Azure IoT Hub.

private void TemperatureCallback(object state)
    var now = DateTime.Now;
    var temps = _tempClient.Read();

    if (!_kMeasurementDone)

    var beer = temps.First(m => m.DeviceId == BeerSensorId);
    var ambient = temps.First(m => m.DeviceId == AmbientSensorId);
    var estimate = -1d;

    if (_kMeasurementDone)
        estimate = Calc.GetCoolingEstimate(beer.Value, _ta, 1, _k);

    ReportMeasurement(now, beer.Value, ambient.Value, estimate);

    foreach (var temp in temps)
        Debug.WriteLine(now + " " + temp.DeviceId + ": " + temp.Value);

    Debug.WriteLine("Estimate: " + TimeSpan.FromMinutes(estimate));

If there’s nothing wrong with the device ID or Azure IoT Hub host name, then all measurements will be reported to hub, and we should see a picture like this on our hub main page:

Azure IoT Hub main page showing number of messages and devices

The number of messages doesn’t change immediately when new measurements are reported. Just wait a few minutes and you will see changes in the numbers.

Wrapping Up

Now we have our beer IoT solution connected to Azure IoT Hub, and all measurements are reported there. Although registering the device was a little bit tricky, we did it by creating a console application. Also, we configured our Raspberry Pi in a way that doesn’t deprecate SAS tokens. But we still don’t see the data, and we don’t have any idea what’s going on. The next posts in this series will focus on displaying and visualizing data we gather from IoT devices.

Brewing Beer With a Raspberry Pi: Table of Contents

  1. Brewing Beer With a Raspberry Pi: Measuring Temperature
  2. Brewing Beer With a Raspberry Pi: Moving to ITemperatureClient Interface
  3. Brewing Beer With a Raspberry Pi: Measuring Cooling Rate
  4. Brewing Beer With a Raspberry Pi: Making Cooling Rate Calculations Testable  
  5. Brewing Beer With a Raspberry Pi: Reporting Measurements to Azure IoT Hub
  6. Brewing Beer With Raspberry Pi: Stream Analytics
  7. Brewing Beer With Raspberry Pi: Visualizing Sensor Data  
  8. Brewing Beer With Raspberry Pi: Building a Universal Windows Application
azure, development, integration, internet of things, raspberry pi

Published at DZone with permission of Gunnar Peipman , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}