Making a hyper-engineered water alarm solution

Vinay Lanka
ITNEXT
Published in
6 min readDec 18, 2020

--

Raspberry Pi, ESP32, Docker, Nodejs, CI/CD, and an Android app. It has it all.

A seemingly menacing water system

Every independent house has a major issue when it comes to water. It’s always a daunting task to check the current water level in the tanks by walking up the many flights of stairs.

I’ve always wanted to “IoTfy” things in my house and was usually only limited to simple home automation tasks like lights and switches. So when I was assigned the task of figuring out a way to solve this seemingly menacing water system, I wanted to make the most out of it by making a really unique system.

Traditional Water Level Systems

Water Level Systems available

Traditional systems use the conductive property of water to complete a circuit. By keeping metal contacts at various levels to monitor the level of water in a tank. By increasing the number of contacts we get a finer resolution of water level.

The drawback of such a system is that it requires a lot of modifications in the tank, requires a lot of volume of hardware, and most importantly requires contact.

All things contactless — a new method of measurement.

As all things should be in 2020, I tried a contactless alternative by using an ultrasonic sensor.

An ultrasonic sensor measures the time difference between the original and reflected wave from which we can infer the distance between the sensor and any object.

By fixing such a sensor to the roof of a tank we can get the level of water in the tank by subtracting the distance from the height of the tank.

ESP32: A low power beast

A prototype for testing

Our microcontroller of choice is the ESP32 due to a few reasons.

  • We needed a completely wireless solution as this was being installed on the terrace and dealing with all the wires is a hassle. ESP32 has a wifi module built-in and can easily send data over to a server. The Arduino library is well equipped to easily send HTTP requests.
  • A very important factor was the fact that the ESP32 has a low power mode where it basically sips power. It takes a few mA on load and only a few uA when in deep sleep mode. Hooking it up to a 10000mAh power bank would make it run for months. It’s so power-efficient that we had to lessen the polling intervals for the power bank to realize that something is connected.

The ESP32 wakes up from low power mode every 20 seconds and connects to a wifi network. It then uses the ultrasonic sensor module to get the distance between the sensor and water and sends it to the server. We do not perform any additional computation to save power.

The Server and why we use Docker and Github Actions

The ESP32 had to send requests to an Express API which stores the distance in a Redis cluster. It’s a simple API with a few routes for updating the current values and fetching data. It responds to the Android app client by performing calculations and sending the latest water level and percentage filled. It also rings a buzzer continuously when a critical water level is reached.

This project could’ve been made without Docker and GitHub Actions. Hooking the Raspberry Pi to a monitor and keyboard/mouse would've sufficed but would’ve been a really bad experience to develop and debug.

This is why Docker’s slogan of Build, Ship, and Run Anywhere was an easy choice to integrate.

Workflow

I’ll probably make a separate tutorial for this as there’s so much to explain about multi-arch builds with docker. Follow so you don’t miss out.

Check out the repository here: https://github.com/vinay-lanka/water-level-api.

The Redis cluster is very tedious to set up manually. Both the Express API and the Redis cluster can be easily set up as containers using docker-compose.

The challenge here was to ring a buzzer (control I/O), with the “onoff” npm package used in the Nodejs script. Doing this from inside a container required the container to have hardware privileges and provided a problem while testing.

The final system makes it really easy to build, test and deploy the application on the Raspberry Pi. Even starting the server is a single command and if anything goes wrong with one service, the container will fix itself by restarting.

ssh and starting the server.

The Android App

We need an interface that was always present on our phones and ready to show us information. A website would result in poor UX(user experience) as people would have to go to the website to find out the level.

A mobile app solves that problem. Recently quite a few in the family have switched to Android and making an app is very accessible.

The app shows the current water level and percentage values along with a custom progress bar to show the value graphically.

It sends requests to the raspberry pi express API for receiving data.

The whole application uses a SwipeToRefresh layout to update the values when the user requires it.

It uses Volley as the networking library and custom buttons for the progress bar and buttons.

The buzzer on the Raspberry Pi rings continuously until the button on the app is pressed, ensuring that the motor which fills the tank up is in fact switched off.

Packing it all up and installing

We pack up the ESP32, power bank, and the ultrasonic sensor in one unit which can operate wirelessly.

Electronics and water do not mix well. This is why we need a waterproof box that can withstand splashes and occasional rainfall.

We still need openings for the ultrasonic sensor so we drill two holes into the waterproof box.

We use a special bit to drill holes into the enclosure

The box with all the components in it is as shown. I just used a waterproof box lying around so it's not exactly the best fit. I’d have ideally gone with a smaller box for more efficient packing of components.

All in a neat package

Conclusion

So all this was a decent 3–4 day project and so far seems to be working well. The ultrasonic sensor so far seems to be holding up well in that humid environment despite my reservations. I’d probably try to swap it out for a better waterproof ultrasonic sensor in the future.

The project is completely open-source so if anyone wants to contribute to the project they can, the repo is linked here.

I’ll try to upload the App’s source code too, I don’t have any experience in uploading Android projects to GitHub but if anyone wants to improve the app(It’s very bland..I’m not an App developer xD), I’ll try to upload that as well.

Let me know if y’all want a blog on the multi-architecture docker build process or the esp32 deep sleep modes as they’re very interesting topics I’ve explored while making this project.

Fewer trips to the terrace, hopefully.

--

--