Finally, the Raspberry Pi is mounted on a wall stud and plugged in to a UPS unit. Figure 4 shows the finished view.

Figure 4. Finished Pit View


The Raspi-Sump program currently consists of three Python scripts. The main script is raspisump.py. The script is very simple and is only about 100 lines of code. The first thing it does is set the variables of the sump pit, like depth (72cm), critical water level (35cm) and GPIO pin assignments as mentioned earlier. The script then takes a sample of 11 water-level readings every minute and uses the median sample as the best reading (more on this later). Once the reading is established, the script determines if the water is at a safe or critical level. Safe levels are logged to a CSV file, and the script waits for another minute to take the next reading. Critical levels are passed to a function that logs the level to the same CSV file and initiates an SMS e-mail to my cell phone (Figure 5). I use the Python smtplib module to handle e-mail alerts. You can configure any e-mail server to handle the alerts, including a localhost mail server on the Pi, if your ISP allows port 25 traffic. You also can use your ISP's SMTP server or Google's Gmail SMTP server if you are using a Gmail account.

Figure 5. SMS Alert

The key Python module used to communicate between the Pi and the sensor is called RPi.GPIO. This module can be used to control so many different types of equipment with your Pi. Without delving into the "nuts and bolts" of RPi.GPIO, the module helps you take control of the pins by turning them on and off. This allows you to control all sorts of equipment, like sensors and LEDs, for example.

You can view the GPIO code in the raspisump.py script within the water_level() function. Similar code is used by many other projects that communicate with the Pi's GPIO pins. Adam Lappin's Byte Creation Blog has a good example that helped me learn how to use the RPi.GPIO module in this project (see Resources).

Raspi-Sump is started automatically on bootup of the Raspberry Pi by adding this line to /etc/rc.local right before the last line exit 0:

/home/pi/raspi-sump/raspisump.py &

The ampersand (&) starts the script as a background process.

Access to GPIO pins requires elevated privileges on the Pi. To start the script manually, issue the command:

sudo /home/pi/raspisump/raspisump.py &

Figure 6 shows using the tail command to demonstrate the CSV file being updated in real time by raspisump.py.

Figure 6. CSV File Being Updated in Real Time by raspisump.py

What is displayed in Figure 6 is rather strange. The water depth is bouncing around. You would expect the water to be consistently higher with each reading. The reason for this is that there is a one-centimeter variance in each reading. Linux is a multitasking OS and not a real-time one. It is not optimal for real-time applications like communicating with sensors and returning precise results. The best reason I can come up with is that the OS is busy doing other tasks and allows raspisump.py to record the reading when it is finished dealing with those other processes.

This brings me back to the reason I use the median reading of a sorted sample. Every once in a while, the script gives an invalid reading that can be way off. This can trigger a false warning SMS alert even if the water is below my critical level. However, these readings are rare. By using a sorted sample, I can remove those fringe readings at the high and low end if they occur. The median reading is always accurate within one centimeter of the actual water level. For a residential system, I am not concerned with millimeter accuracy. A small variance in readings still provides safe reporting of the water level. This also helps explain the jagged line in the graphs that are generated and sent to a Web server at regular intervals.

Figure 7. Graphs Generated by todaychart.py

The second script I use is todaychart.py. This script generates graphs, as shown in Figure 7, of water level activity from my CSV log files. It uses the Python matplotlib and NumPy modules to generate the graphs. rsync over SSH copies the graphs and CSV log files hourly to my Web server via a cron script. I chose to generate graphs on the Pi instead of the Web server, because different Linux distributions package different versions of matplotlib and NumPy. I prefer using the packaged versions for simplicity. Always using the Raspberry Pi renders more consistent graphs, no matter which distro you use for your off-site component.

The third and final script is checkpid.py. Its purpose is to monitor the health of the raspisump.py process and restart it if it is stopped. Cron runs the script at regular intervals and looks for one of three outcomes. If the script returns 0, this indicates a failed process. checkpid.py then initiates a restart command. If the script returns 1, the process is fine, and the script exits cleanly. If the number is greater than 1, this indicates more than one raspisump.py process. In this instance, a killall 09 raspisump.py directive is initiated, and the process is restarted.

Other Issues with Raspi-Sump

The HC-SR04 sensor has a fairly wide sonar field. The user manual states that it works best with a 30° angle. My sump pit is a busy place. It has a backup pump that sits higher than the main pump on a 2x6 stud. Each pump has a float ball that bounces around in the pit. This results in false readings when the sensor picks up an object that enters its field. This problem can be mitigated by strategically placing the sensor further away from these objects. If that is not possible, you can vertically insert a 3" or greater piece of PVC pipe in the sump pit and force the sensor to take its reading down the empty pipe. This will focus the pulse and hide the objects in the pit that are causing problems.


Raspi-Sump is still in the early stages of development. There are other features I would like to add, such as:

  • A manual power button to start and shut down the Raspberry Pi gracefully without logging in.

  • A small LCD display to show the current water level without opening the lid.

  • A Web-based reporting system using a Python Web framework.

  • A Web-based management interface for Raspi-Sump on the Pi (like a home router).

  • A GSM module component to use the cellular network for alerts instead of the Internet.

  • A configuration file to store variables as opposed to within the script.

  • Package management for installation of Raspi-Sump.

A sump pit monitor is just one tool you can use to help avoid a flooded basement. It's not a replacement for a complete strategy that includes a backup pump on a separate electrical breaker. A gas-powered electrical generator is also essential for extended power outages. Also, I kept my cheap Home Depot audible alarm. A text alert at two in the morning is useless if I am sound asleep. I want a "full-out" screech to wake me up.

I welcome all feedback on this project. I am not a professional programmer, and I am sure that I can substantially improve the code or add useful features that I have not even considered.

Although it's not perfect, I now have a system that works and gives me extra peace of mind while I am away. If you are looking for a similar solution, I hope you can use, modify and improve Raspi-Sump to suit your needs. If you do, I would love to hear from you.


Special thanks to Ron Hiller (GitHub user @rhiller) for tirelessly answering my questions about voltage dividers and his own sump pump monitor called pi-distance: https://github.com/rhiller/pi-distance.


Raspi-Sump Web Site: http://www.linuxnorth.org/raspi-sump

Source Code: https://github.com/alaudet/raspi-sump