Water Leak Detection Kit

Water Leak Detection Kit

Regular price $89.95 USD Sale

Damage from appliance water leaks (such as water heaters, dishwashers, fridges and washing machines) cause millions of dollars in insurance claims every year.



There are many different types of water leak detection systems – the most efficient ones react at the first sign of presence of moisture, trigger an audible alarm, and provide an email alert. Audible only alarm type units do not perform well if nobody is there to hear the alarm.

We have created a water leak detection system kit using the PI-SPI Series of products, all that needs to be added is a Raspberry Pi and a 5VDC power supply for the Raspberry Pi.


There are three level of kits available, Basic, Basic + Audible and DIN + Audible. Each kit  has the following standard features:

Basic Kit:

- Four zones of water leak detection

- Each zone works with a water leak sense cable (1 x 6’ cable as part of the kit)

- Up to four temperature sensors (2 x 10K NTC thermistor with 36” leads as part of the kit)

- 1 x PI-SPI-8AI-4TEMP-4VDC Analog Input module

- 1 x PI-SPI-8KO Relay Module

- 1 x PI-SPI-CABLE-40x26-2 Ribbon cable (Required to connect to the Raspberry Pi)

- 1 x PI-SPI-CABLE-26x26-2 Ribbon Cable (Required to connect the two PI-SPI modules)

Basic + Audible Kit:

- Same as the Basic Kit above

- 24 VDC Audible Alarm Buzzer

- 24 VDC Power Supply

DIN + Audible Kit:

- Same as the Basic + Audible Kit above

- Din Rail mounting enclosures for the PI-SPI modules, Raspberry Pi and Audible Buzzer

- DIN Rail 12” long for convenient mounting of all modules

System Wiring Diagram



Theory Of Operation

The PI-SPI-8KO module has 6 channels of voltage output. For Zone 1 operation, we connect one lead of the water sense cable to the K3 terminal, and connect the other lead of the water sense cable to the PI-SPI-8AI analog input module channel 4 which has been configured as a voltage input (0 to 6.6 VDC).

The sequence of operation is a follows:

1. The K3 output is turned ON providing a 3.3 VDC output for 50 mSeconds.

2. At the end of the pulse, the Analog Input Channel 4 is read.

3. The K3 output is turned off.

4. If the reading is less than 20 AD counts, there is no moisture present on the water sens cable

5. If the reading is greater than 600 AD counts, the water sense cable is conducting and moisture is present on the cable

6. The alarm state is set or reset depending on the AD reading.



Python Code

The following code sample has been fully tested for all zones and sensor inputs.

# pi-spi-h2o-demo.py

# Import libraries

import smtplib

import time

from time import sleep

from widgetlords.pi_spi import *

from widgetlords import *

# initialize modules


inputs = Mod8AI()

relays = Mod8KO()

# Set up the email server and configure

user = 'your_email@gmail.com' # Typically your email account

password = 'Your password is here' # Your password for your email account

sent_from = user

send_to = ['to@gmail.com'] # Send the email to

subject = 'WATER LEAK ALARM'

smtp_server = 'smtp.gmail.com' # Your email provider server

smtp_port = 465 # Typically the port is 465

# Initialize email sent flag to prevent multiple emails

emails_sent = 0

# Define Relay Outputs

K1 = 0

K2 = 1

K3 = 2

K4 = 3

K5 = 4

K6 = 5

K7 = 6

K8 = 7

ON = 1

OFF = 0

# Water leak zones

Zone_Reading = [0,0,0,0]

Zone_Alarms = [0,0,0,0]

Zone_Status = ['OK','OK','OK','OK']

# Alarm threshold AD counts

Alarm_Threshold = 600

# Temperature Sensors

Temp_AD = [0,0,0,0]

Temp_Deg = [0,0,0,0]

Temp_Read = ['-','-','-','-']

# Email send function

def send_email(server,port,_user,_password,_from,_to,text):


smtp_server = smtplib.SMTP_SSL(server, port)


smtp_server.login(_user, _password)

smtp_server.sendmail(_from, _to, text)


#print ("Email sent successfully!")

except Exception as ex:

print ("Something went wrong….",ex)

# Read zone AD counts function

# Each zone relay is turned on for 50 mSec to apply voltage

# to one wire of the water sense cable

# The analog input channel reads the voltage and stores the AD Counts

# Dry condition will read less than 5 AD Counts

# Wet condition will read > 1000 AD counts

def zone_read(zone,relay):



Zone_Reading[zone] = inputs.read_single(zone+4)



# Get the individual zone alarm conditions function

def get_zone_alarms(zone):

if Zone_Reading[zone] > Alarm_Threshold:

Zone_Alarms[zone] = 1


Zone_Alarms[zone] = 0


while True:

# read all Zones






# Get zone alarms

alarms = 0


for i in range(4):


alarms = alarms + Zone_Alarms[i]


# Configure email body for Zone Alarms

for i in range(4):

if Zone_Alarms[i] != 0:

Zone_Status[i] = 'ALARM'


Zone_Status[i] = 'OK'


# Read and Configure Temperature Sensor inputs of email body

for i in range(4):

Temp_AD[i] = inputs.read_single(i)

Temp_Deg[i] = steinhart_hart(10000, 3380, 4095, Temp_AD[i])


if Temp_AD[i] > 4050:

Temp_Read[i] = '-'


Temp_Read[i] = ("%0.1f Deg C" % Temp_Deg[i])

# Temperature Sensor input 4 is used as a push button input

# to send e test email and test the audible

if Temp_AD[3] < 20:

Temp_Read[3] = 'Sending Test Email'


# Read time for the email body for a time stamp

seconds = time.time()

local_time = time.ctime(seconds)


# Prepare the body of the email

body = """\

Status: %s


Zone 1: %s

Zone 2: %s

Zone 3: %s

Zone 4: %s


Temp 1: %s

Temp 2: %s

Temp 3: %s

Temp 4: %s

""" % (local_time, Zone_Status[0], Zone_Status[1], Zone_Status[2], Zone_Status[3], Temp_Read[0], Temp_Read[1], Temp_Read[2], Temp_Read[3])

# Configure the complete email to be sent

email_text = """\

From: %s

To: %s

Subject: %s


""" % (sent_from, ", ".join(send_to), subject, body)

# Check for alarms and send email if required

# Temperature Sensor input 4 is used as a push button input

# to send e test email and test the audible

if alarms > 0 or Temp_AD[3] < 20:

# Turn on Audible relay K1



# send email only if flag has not been snet

if emails_sent != 1:


# Used for debug purposes



# set email flag to prevent multiple emails from one alarm

emails_sent = 1



# if no alarm clear audible relay K1


emails_sent = 0