Sensor Telemetry 2.0.1 Drive temperature data to Microsoft Azure IoT Hub and monitor the data remotely from a Windows Universal application. Digitally Remastered!
Story
UPDATED: The Sensor Telemetry project has been digitally remastered. Updated as of May 17th, 2017 and renamed to Sensor Telemetry 2.0.1
Introduction
Overview
In this project, we will monitor a temperature sensor (MCP9808) and send telemetry readings to a Microsoft Azure IoT Hub where a Stream Analyticsjob will process the messages and write them to an Azure SQLDatabasetable. We will use Mobile Apps to view the history of the sensor readings.
The Application
The project contains two Universal Windows Applications (on the Universal Windows Platform, UWP) that share about 99% of the code. One is targeted towards the Raspberry Pi (or ARM) and the other is targeted towards the x86 or x64 platforms.
The IoT version of the application runs on the Raspberry Pi and reads the temperature from the MCP9808. The application sends telemetry events to the Azure IoT Hub and the SignalRhub. This version will also listen for commands from the Azure IoT Hub.
The client version, started on a computer, will listen for sensor updates from the SignalR hub and display them on screen. This version will also send commands to the IoT version via the Azure IoT Hub.
Technologies
The application in this project is based on the MVVM (Model-View-ViewModel) pattern and was built using the Prismlibrary and uses Prism.Unity for the IoC (Inversion of Control) container. In addition to these libraries, the application uses the Event Aggregator found in the Prism.Eventlibrary to create, as best as possible, a purely event-driven architecture. The application uses this library to allow the internal modules to communicate while remaining loosely coupled.
The application also uses SignalR on Azure Mobile App to allow multiple instances of the application to communicate with each other. The temperature readings are “broadcast” to all clients running remotely so that they can receive temperature sensor readings to display in the main view.
Architecture
At the heart of the application is the MCP9808 library built as a separate project that can be reused in other applications. This project is developed as a UWP library that can be used in any Windows 10 application. If the library is used on a device that does not have an I2C bus the library will not return any device object. This approach can be used to “detect” a sensor and gracefully ignore the library when a senor is not found.
In the UWP client application there are several blocks that make up the overall application. The Views are the visible pages and each view has a View Model responsible for the state of the View. There are three repositories: applications settings (IApplicationSettingsRepository), debugging information (IDebugConsoleRepository) and reading and writing the MCP9808 (ITemperatureRepository). There are two concrete classes built around ITemperatureRepository; one wraps the MCP9808 library and one is a null device used when the application is not running on the Raspberry Pi.
The class Mcp9808TemperatureRepository monitors the MCP9808 using the timer service and publishes temperature information via the internal event aggregator every time the temperature reading or alert status changes. A new event is sent only when the current reading is different from the previous reading.
There are also a series of services defined by IBackgroundService that run in the background for various activities.
The diagram below depicts a high level view of the architecture and the connectivity between the various blocks and services.
Telemetry Service
This service monitors the temperature-changed event (via a subscription) and sends a message to the Azure Service Bus Event Hub whenever the temperature changes.
Timer Service
This simple service is a timer that publishes an event every 500 milliseconds and is used by the view models to display the current time on a view. It is also used by the Mcp9808TemperatureRepository to read the sensor once every second. The timer event arguments include a counter that can be used with the mod function to easily divide the timer interval into the desired length. There is a method called IsMyInterval(TimeSpan interval) on the event argument that does the math for you. All you need to do is supply the interval as a TimeSpan object.
Alert Pin Monitoring Service
This service monitors the state of the GPIO pin connected to the alert pin on the MCP9808. When the value of the GPIO is changed, this service publishes an event.
LED Service
This service is responsible for turning the LEDs on and off. This is done by monitoring (via subscription) the temperature-changed event which also includes the alert status of the MCP9808. When the alert status changes the LEDs are updated accordingly.
Push Button Monitoring Service
This service monitors the GPIO pin connected to the push button and publishes an event when the button is released. This event is picked up by the Mcp9808TemperatureRepository when the device is in manual alert reset mode (MCP9808 interrupt mode). Debug events are also published so that the state of the button can be viewed in the debug console.
Notification Relay Service
The service monitors the SignalR hub and the internal event aggregator and relays messages between the two based on a predefined mapping (using the EventRelayMap class). This essentially allows the application to only be aware of the internal event system and still able to send and receive messages with other instances of the application.
Debug Console Service
This service monitors the applications (via subscription) for debugging events and adds them to an internal collection. It also implements DebugConsoleRepository, which allows the debug console view to display these events in the application via the View Model.
Application Initialization
When the application starts, it launches the StartPage view first, which automatically invokes the StartPageViewModel. This view model gets everything up and running before launching into the main view.
Getting Started
Circuit Requirements
The circuit requires a large, solderless breadboard, and optionally, a T-shaped cobbler and ribbon cable (I use the version sold by Vilros). The breadboard can be obtained from a multitude of places (I’ve purchased from local stores and from Amazon). The circuit also uses a momentary tactile push button switch with four pins. There are many types; any will do. Finally, for the temperature sensor, I am using the MCP9808 High Accuracy I2C Temperature Sensor Breakout Board from Adafruit.
The circuit can be built without the cobbler. Simply follow the alternate breadboard diagram at the end of the project.
Circuit Assembly
Use this guide to assemble the circuit while using the diagram located near the bottom of the page as a guide (note: the color of the wires are optional and have been selected to help make the circuit easy to follow when it is constructed).
- Place each of the four LEDs onto the breadboard.
- Connect one end of a 220 Ω resistor to the anode of each LED and connect the other end of the resistor to the 3V3 (pin 1 or 17) on the Raspberry Pi. All four LED anodes should be connected to 3V3 via a 220 Ω resistor. It is best to use one of the + rails on your breadboard for the 3V3 connections.
- Place the MCP9808 onto the breadboard.
- Connect Vdd on the MCP9808 to the 3V3 on the Raspberry Pi.
- Connect GND on the MCP9808 to GND on the Raspberry Pi. Ground on the Raspberry Pi can be any of the following pins: 6, 9, 14, 20, 25, 30, 34 and 39.
- Connect SCL on the MCP9808 to SCL on the Raspberry Pi (pin 5).
- Connect SDA on the MCP9808 to SDA on the Raspberry Pi (pin 3).
- Connect a 10K Ω resistor between the Alert pin on the MCP9808 and 3V3on the Raspberry Pi.
- Connect the Alert pin on the MCP9808 to the GPIO 6 (pin 31) on the Raspberry Pi.
- Place the push button switch onto the breadboard.
- Connect one side of the switch to GPIO 5 (pin 29) on the Raspberry Pi.
- Connect the other side of the switch GND on the Raspberry Pi.
- Connect a 10K Ω resistor between the GPIO 5 and 3V3 on the Raspberry Pi.
Below are some photos of the circuit I built using the cobbler.
Microsoft Azure Requirements
If you do not have an Azure account, you will need to create one. You can get a $200 credit when you start your account. Go to azure.com and click the FREE ACCOUNT link. If you already have an account, sign in to the portal at portal.azure.com.
NOTE: This guide is not an exhaustive guide to configuring Azure. You may need to familiarize yourself with the portal if you have never used it before. I will walk through the steps necessary for this project as best I can.
Leave yourself logged into the Azure portal during the entire setup process. You will need to refer back to it many times.
Azure IoT Event Hub Setup
- Select New in the left menu of the portal.
- Select Internet of Things
- Select Iot Hub
- Enter a unique name for your hub.
- Select a subscription.
- Under Resource Group select Create New and enter a name for your group. Note you will use this group for all Azure resources created during this project.
- Choose a location (try to keep all resources in the same region to keep charges low).
- If this is your first IoT hub, select Pricing and scale tier. Then select F1 Free. You can have one free tier in your account.
- Finally, click create and wait for the IoT Hub to be created.
- Click IoT Hub in the left menu to see the new hub.
- Click the new hub to see an overview of the details. You will need to refer back to this view later.
Create a Device
The Azure IoT Hub requires that each device be uniquely identified and registered in the hub for security purposes. A device can be registered using the Azure SDK and code, but for this project we will use the Device Explorer available in the Azure SDK.
- Download the Azure SDK from GitHub from https://github.com/Azure/azure-iot-sdk-csharp either by getting the zip file or cloning the repository.
- If you downloaded the zip file, expand it to a folder on your disk.
- Open the folder azure-iot-sdk–csharp-master\tools\DeviceExplorer.
- Open the DeviceExplorer project in Visual Studio.
- Run the application.
- Go back to the Azure portal and select your IoT Hub. Click the Shared access policies link and select iothubowner. Click the copy button next to the Connection string – primary key.
- In the Device Explorer window, paste this string into the text box labeled IoT Hub Connection String.
- Click the Update button.
- Change to the Management tab in the Device Explorer and click Create.
- Type a name for your device (example, TemperatureDevice1).
- Make sure the Auto Generate Keys check box is selected and click Create.
- Click Done.
- You will need to come back to this application to get the device connection string later.
Azure SQL Database Setup
The telemetry data will be stored in an Azure SQL Database. Use the portal to create the database.
- Click SQL Databases in the portal menu.
- Click the Add button.
- Enter a name for the database (i.e. SensorTelemetry)
- Select a subscription.
- For Resource group choose Use existing and select Sensor Telemetryfrom the drop down.
- Click the server link to setup a new server.
- Enter a name for the server.
- Enter a user name (you will need this later, so remember it).
- Enter a password (you will need this later, so remember it).
- Choose a location (try to keep all resources in the same region to keep charges low).
- Click Select.
- Click Pricing tier.
- Select Basic.
- Click Select.
- Click Create.
- Click the new server in the SQL Server list,
- Click the Set server firewall to allow access from your computer to the SQL Server.
- Enter a name for the connection and your external IP address in the Start IP and End IP range.
- Click the ellipses to save the entry.
- Click Save to save the IP address.
Create the Database Table
The table used will be created manually. Code First deployment can be used in Mobile Apps, but the table created will not be compatible with Stream Analytics.
- Open Visual Studio.
- Select SQL Server Object Explorer from the View menu.
- Right-click the SQL Server object and select Add SQL Server.
- Browse the Azure databases and select the database you created in the previous step.
- Enter your username and password and click Connect.
- Expand the object explorer items until you see the database you created.
- Right-click this database and choose New Query.
- Copy the SQL script from the bottom of this project page and paste it into the Visual Studio code window.
- Select Execute from the SQL menu to run the script.
- Expanding the tables object in the explorer will reveal the newly created table called SensorReadings.
Create the App Service Plan
The App Service Plan is required for creating an App Service.
- Select App Service plans in the portal menu.
- Enter a name for the plan.
- For Resource group choose Use existing and select Sensor Telemetryfrom the drop down.
- Chose a location.
- Click Pricing tier and select B1 Basic.
- Click Create.
Create the App Service (Mobile App)
The web site and SignalR hub will run with an App Service.
- Click New from the portal menu.
- Choose Web+Mobile from the list.
- Choose Mobile App.
- Enter a name for the application.
- Select a subscription.
- For Resource group choose Use existing and select Sensor Telemetryfrom the drop down.
- Chose the App Service Plan you created in the previous step.
- App Insights is optional.
- Click Create.
Azure Stream Analytics Setup
The Stream Analytics job will monitor data events on the IoT Hub and write them to a SQL Server database. The job will consist of an input (the IoT Hub), and output (the SQL Table) and a Query that chooses which fields to use.
- Choose New.
- Select Data + Analytics from the menu.
- Select Stream Analytics Job from the menu.
- Enter a unique name for the job.
- Select a subscription.
- For Resource group choose Use existing and select Sensor Telemetry from the drop down.
- Choose a location (try to keep all resources in the same region to keep charges low).
- Click Create.
- Select More Services > from the menu.
- Scroll down to Stream Analytics and click the star. This will pin it to the portal menu.
- Click Stream Analytics jobs in the portal menu.
- Select the job you just created.
- Click Inputs.
- Click Add.
- Enter a name for the input (i.e. SensorTelemetry-Input).
- Change the source to IoT Hub.
- Accept the remaining default values.
- Click Create.
- Click Outputs.
- Click Add.
- Enter a name for the output (i.e. SensorTelemetry-Output).
- Select SQL Database as the sink.
- Select the Sensor Telemetry database.
- Enter the user name you specified when you created the database server.
- Enter the password you specified when you created the database server.
- Enter SensorReadings for the table name.
- Click Create.
- Select Query.
- Replace the text [YourOutputAlias] with the name of the output (keeping the square brackets).
- Replace the text [YourInputAlias] with the name of the input (keeping the square brackets).
- Replace the asterick (*) with this text: [TimestampUtc], Source, Temperature, IsCritical, IsAboveUpperThreshold, IsBelowLowerThreshold
- Click Save and then click Yes if prompted.
- Click Overview in the Stream Analytics job menu.
- Click the Start button.
- Choose Now.
- Click Start.
Configuring the Software
Using the repository link at the bottom of the page, either download the code as a zip file or clone the repository to your computer and open the project in Visual Studio.
Configure and Publish the Mobile App
The web application (located in the Web folder) needs to be published to the Azure App Service.
- Right-click the project in Visual Studio and select Publish.
- Click Microsoft Azure App Service.
- Select your App Service from the list (you may need to log in if this is the first time).
- Click OK.
- Click Next.
- Go to the Azure portal
- Select SQL Databases from the portal menu.
- Select your database.
- Click the Show database connection strings link.
- Click the copy button next to ADO.NET string.
- Go back to Visual Studio and paste this string into the text box labeled MS_TableConnectionString.
- Change the user name and password to the values you set when you created the SQL Server.
- Click Next.
- Click Publish.
- When the publish has completed, a browser will be launched pointed at your new web site.
Enter the IoT Hub Credentials
Before running the application, you will need to enter your IoT Hub device credentials into the code.
- Open the project in Visual Studio.
- Expand the Sensor Telemetry project under the UWP folder and open the code behind for the App.xaml.
- Scroll down to the section with the definition for IIotHubConfiguration.
- Open the Device Explorer project in another instance of Visual Stduio.
- Click to the Management tab.
- Right-click the device you created previously.
- Click the Copy connection string for selected device option in the menu.
- Go back to the Sensor Telemetry prject and paste the connection string over the text {YOUR CONNECTION STRING HERE}.
- Enter the name of the device over the text {YOUR DEVICE ID HERE}.
- Save this file.
- Expand the Sensor Telemetry IoT project and find the code behidn for App.xaml.
- Scroll down to the section with the definition for IIotHubConfiguration.
- Copy and paste the same configuration from the previous app.cs file.
Enter the Mobile App URL
The Mobile App URL also needs to be entered into the code.
- Open the project in Visual Studio.
- Expand the Shared project.
- Open the UnityConfiguration.cs.
- Scroll down to the section containng the IMobileServicesConfigurationdefinition.
- Open the Azure portal.
- Click App Services.
- Select the App Service you created for this project.
- Hover the mouse over the URL and click the Copy icon.
- Goback to Visual Studio and paste the URL over the text {YOUR MOBILE SERVICES URL HERE}.
Read More Detail :Sensor Telemetry 2.0.1