Project tutorial
Azure IoT Swimming Pool

Azure IoT Swimming Pool © GPL3+

Control and monitor a swimming pool using Azure IoT Hub, Streaming Analytics, Azure SQL, API App, Raspberry Pi, Windows IoT Core, Arduino.

  • 25 respects

Components and supplies

DS18B20 Waterproof Digital Temperature Sensor
(Red wire connects to 3-5V, Blue/Black connects to ground and Yellow/White is data)
IoT Power Relay
Mfr 25fbf52 4k75 sml
Resistor 4.75k ohm
1/4W, 5%
R8326274 01
Raspberry Pi 2 Model B
Ph a000066 iso (1) ztbmubhmho
Arduino UNO
Arduino Uno R3

Apps and online services

About this project


The purpose of this project is to control and monitor a swimming pool using temperature sensors, relays and Microsoft Azure.

The inspiration for this project is the need to remotely operate and monitor our kids swimming pool, which is an Intex 15' x 48" round pool. The pool holds approx. 5000 gallons of water. It is connected to a Sand Filter/Pump, an 11KW Heater, and a Salt Water System. The goal was to monitor pool water temperature, air temperature and control the pump, heater and salt water system to ensure the pool was warm enough for the kids, while not over-running it.

This 5 minute video shows how the pool, sensors, circuit boards and relays are connected.

IoT Pool Video

The following architectural diagram shows all the major components in the solution.

The Raspberry Pi, Arduino, IoT Power Relay and breadboard are zip-tied into a plastic storage container to keep water/moisture away. Holes were drilled for the cables and ventilation.

Note: In the above picture, the pool temperature DS18B20 is not yet connected to the breadboard. The air temperature DS18B20 is connected and taped to the outside of the plastic container (see bottom of picture).


Monitoring of the pool water temperature and air temperature is accomplished using a pair of DS18B20 waterproof temperature sensors, connected to an Arduino Uno R3 using the Dallas Controls Library and OneWire Library. The temperature data (in Celsius) is sent to a Raspberry Pi every 1 second over I2C. The two temperature values are delimited with a "|".

temperatureData = padRight(String(poolSensor.getTempCByIndex(0)) + "|" + 
                     String(outsideSensor.getTempCByIndex(0)), I2C_BUFFER_LEN);

The DS18B20 waterproof temperature sensors come pre-wired as follows:

  • Red connects to 3v/5v
  • Blue/Black connects to ground
  • Yellow/White is data

I used some cheap 20 gauge bell wire (door bell wire) to extend the reach of the DS18B20 that is reading water temperature. This DS18B20 is submerged in the pool.

The second DS18B20 sensor reading air temperature is taped to the outside of the plastic storage container.


The Raspberry Pi controls an IoT Power Relay power bar to which the Pump and Salt Water System are connected using 110v. This is done using the 3v pin on the Pi. Toggling the 3v pin enables/disables a pair of 110v outlets on the IoT Power Relay (the pair of outlets are off by default). Refer to the diagram later for a schematic.

There was no need to connect a relay to the Heater since it has a built-in flow sensor, and will stop/start heating based on the absence or presence of water flow. Plus I couldn't readily find a relay to control a 220v/60amp circuit needed by the Heater using 3v or 5v.

In the future I will be attaching sensors to measure the electrical use of the 110v and 220v circuits. If anyone can recommend some, I would be grateful.

Raspberry Pi

The Raspberry Pi runs Windows IoT Core Build 10.0.10586.0 and performs the following:

  • Runs the IoTPoolRaspiBackgroundApp background application;
  • Acts as a IoT field gateway (opaque);
  • Provides power to the Arduino Uno over USB (5v);
  • Receives pool and air temperature (in C) from the Arduino Uno over I2C;
  • Controls the IoT Power Relay using a 3v pin; and
  • Sends the pool name, pool temperature, air temperature, IoT Power Relay on/off status and a time stamp (in UTC) every 1 minute to the Azure IoT Hub.

The IoTPoolRaspiBackgroundApp is a headless C# application, built using the Background Application (IoT) project template in Visual Studio 2015, Update 3.

The IoTPoolRaspiBackgroundApp sends the following JSON payload to the Azure IoT Hub every 1 minute using AMQP (this can be changed in the source code to HTTPS or MQTT).

"PoolName" : "iotpool",
"PoolWaterTempC" : 30,
"OutsideAirTempC" : 27,
"IsPoolPowerOn" : false, 
"SampleDateTime" : "2016-07-05T23:35:58.0882185Z"

The Raspberry Pi is registered as a device in the Azure IoT Hub. The easiest way to register a device in Azure IoT Hub is using Device Explorer. This tool is also a great way to obtain the device's connection string, monitor D2C (Device to Cloud) messages and to test sending C2D (Cloud to Device) messages.

Tip: Ensure the device name (case sensitive) you register in IoT Hub is used consistently throughout the project. In my case I used "iotpool".

Edit the following in StartupTask.cs to connect IoTPoolRaspiBackgroundApp to your IoT Hub:

static string iotPoolConnString = "HostName=<iothubname>;DeviceId=iotpool;SharedAccessKey=<key>";
static string deviceName = "iotpool";  

Arduino Uno

The Arduino Uno R3 is connected to two DS18B20 temperature sensors using the Dallas Controls Library and OneWire Library. It is powered by the Raspberry Pi over USB (5v) and sends the pair of temperature readings to the Raspberry Pi over I2C using the SDA and SLC pins. Refer to the Fritzing diagram for a schematic.

Note: In the above picture, the pool temperature DS18B20 is not yet connected to the breadboard. The air temperature DS18B20 is connected.

Use the Two-DS18B20-I2C.ino code to run the Arduino.


All Azure components were created in the same Azure region (West US) to minimize costs associated with egress traffic.

Azure IoT Hub

The free edition of the Azure IoT Hub was used in this project. It's limited to 8,000 messages/day at 500 bytes each. The IoTPoolRaspiBackgroundApp sends D2C messages at 1 per minute, or 1,440/day, at 158 bytes each. This leaves ample headroom for any C2D messages.

You must first register a device with Azure IoT Hub. The easiest method is using Device Explorer. Once registered, you can obtain the device connection string using Device Explorer.

Azure Streaming Analytics

The Azure Streaming Analytics (ASA) job connects the IoT Hub input to the Azure SQL Database output using the following simple ASA query.


This query writes each Device to Cloud (D2C) JSON message (1 per minute) to a table named Pools in an Azure SQL Database.

Future improvements to this query may include some aggregation functions to for alerting purposes (e.g. Average PoolWaterTempC > 35 indicates pool is getting too warm).

Azure SQL Database

To minimize cost, and because the performance requirements of the database were minimal, the database is an S0 Standard (10 DTUs).

A single database with a single table was created to store all the D2C messages.


CREATE TABLE [dbo].[Pools] (
[PoolWaterTempC] FLOAT (53) NOT NULL,
[OutsideAirTempC] FLOAT (53) NOT NULL,
[IsPoolPowerOn] INT NOT NULL,

Azure API App

The API is a RESTful API built using ASP.NET Web API.

API clients must authenticate using an API key specified in the HTTP header.

api-key : {your API key}

The API key is defined in the IoTPoolAPI\Controllers\PoolControllers.cs. The Mobile App and the Web App must use this API key to communicate with the API.

The REST API supports the following methods:

Future improvements to the API may include placing it behind Azure API Management and adding other authentication options into the API such as Azure Active Directory.

Tip: Postman is a great tool for testing REST APIs.

Azure Web App

The IoTPoolWebApp contains a ASP.NET web forms application to interact with the API.

There is also a mobile friendly version of the web app.

Edit the default.aspx.cs and change the following:

private static string apiKey = "";
HttpRequestMessage requestMessage = ...."http://<yourwebsite>");
HttpRequestMessage requestMessage = ...."http://<yourwebsite>");
HttpRequestMessage requestMessage = ...."http://<yourwebsite>");

The web app is integrated with Azure Active Directory (AAD) for authentication. The web app requires that all users must authenticate using AAD.

You must first register your web app with your AAD tenant (e.g. You can do this through the Azure Portal or through Visual Studio. Once registered, copy the client ID from the Azure Portal.

Next, change the AAD domain in the web app by modifying the <AAD client ID> in the web.config.

<add key="ida:ClientId" value="<AAD client ID>" />
<add key="ida:AADInstance" value="" />

Mobile App

The Mobile App is written using Xamarin Forms. I've only compiled it to run on Windows Phone and Windows 10 but should cross compile on iOS and Android.

Warning: The mobile app doesn't enforce user authentication and is not yet integrated with AAD. So be careful where you deploy the mobile app!

Edit Core.cs and change the following:

string queryString = "http://<yourwebsite>

Edit DataService.cs and change the following:

private static string apiKey = "";

Edit PoolPage.xaml.cs and change the following:

private static string apiKey = "";
HttpRequestMessage requestMessage = ...."http://<yourwebsite>");
HttpRequestMessage requestMessage = ...."http://<yourwebsite>");

Power BI

Power BI (free edition) was used to create and publish a real time dashboard showing IoT Pool data.

The process involved downloading Power BI Desktop, connecting to the Azure SQL DB (using DirectQuery), creating some reports with visuals, and publishing the .pbix to I then pinned the report to a dashboard.

In the future I may use Power BI embedded to directly embed the dashboard into the web app.

For now I can view the dashboard through or through the free Power BI mobile app.


Here's a list of resources I used in building this solution:

Special thanks to Miles Burton for the Dallas Controls Library and Mike Mackes for the Arduino / I2C / DS18B20 sample code and overall inspiration for this project.


JSON Message Payload Format for Device to Cloud (D2C) MessagesJSON
Note: "IsPoolPowerOn" - 0 indicates power off; 1 indicates power on
	"PoolName" : "IoTPool",
	"PoolWaterTempC" : 30,
	"OutsideAirTempC" : 27,
	"IsPoolPowerOn" : false,  
	"SampleDateTime" : "2016-07-05T23:35:58.0882185Z"
SQL Database "Pools" Table SchemaSQL
CREATE TABLE [dbo].[Pools] (
    [Id]              INT            IDENTITY (1, 1) NOT NULL,
    [PoolName]        NVARCHAR (MAX) NULL,
    [PoolWaterTempC]  FLOAT (53)     NOT NULL,
    [OutsideAirTempC] FLOAT (53)     NOT NULL,
    [IsPoolPowerOn]   INT  NOT NULL,
    [SampleDateTime]  DATETIME       NOT NULL,
IoT Pool Git Hub Repo
All source code


Raspberry Pi to Arduino over I2C connecting 2 DS18B20 Sensors
Raspberry Pi to Arduino over I2C connecting 2 DS18B20 Sensors
IoT Pool Architecture
Overall architectural diagram
Raspberry Pi to IoT Power Relay


Similar projects you might like

GPS Datalogger, Spatial Analysis, and Azure IoT Hub.

Project tutorial by Shawn Cruise

  • 98 respects

Windows IOT - Automate your power outlets

Project tutorial by Syed Sanoor

  • 56 respects

Pool Controller

Project tutorial by Mike Mackes

  • 141 respects

Home Automation Using Raspberry Pi 2 And Windows 10 IoT

Project tutorial by Anurag S. Vasanwala

  • 824 respects

Solar Tracker with Live Data Feed - Windows IoT

Project tutorial by Jed Hodson

  • 1 comment
  • 33 respects

OH HAI! on Windows 10 IoT Core

Project in progress by BuddyC

  • 51 respects
Add projectSign up / Login