IoT Irrigation Hack for the Holidays

johann arispe
The Startup
Published in
11 min readJan 15, 2021

There is an alternative way to take care of your dear plants over the holidays. Raspberry pi + Home Assistant + a Water pump will do it.

Wall garden with small pots and plants on a wooden shelf.
A general view of some of our plants.

At home, we have a little indoor garden that we take care of during the whole year. It is a tiny and nice set of plants and flowers that need water every day. They get good sunlight and they are intended to be kept small due to space.

The end of the year holidays and staying away from visiting the family has been a challenge to keep them healthy and attended. Sometimes we asked a friend to come over and do it, but if we need to stay away for over a month's time, then it is more challenging.

This article is intended to help you grasp the main idea and inspire you to replicate it.

Current challenge: Keep the flowers and plants with the enough amount of water so they can last over a month without our in-person care. Considering that too much water would spill all over around.

Quick video showing the iterative process of construction and experimentation.

As a software engineer and a product manager, I spent a couple of days thinking through ways of solving the problem of watering 7 pots with different types of plants. Mini pine tree, an avocado plant, lavender, a cactus, and a small coffee plant. Each of them consumes an amount of water that is sort of unique for each type.

I have been playing around with IoT development, automation, and electronics for some years. So I remembered that I had a spare Raspberry pi laying around, some electronic components, and I always wanted to try out Home Assistant's automation capabilities. Inspired by the Automated Indoor Gardener project, I assembled my custom solution.

Breaking Down The Problem

The challenge is composed of the following problems to solve:

  1. A small water pump with a good suction power
  2. A reliable tubing & dripping water system set up.
  3. An IoT controller to have automated control of the water flow and data monitoring.

Project solution

Water Pump

  • There are many types of water pumps. The most common are the aquarium ones. I didn't like them due to the size and the need to be in contact with the water when submerged. Also, they tend to be too powerful for the water flow I was looking for.
Grothen 12v DC Peristaltic Pump
  • The one I choose is the tiny 12v DC peristaltic pump with 120ml/min flow rate. This one is easy to mount and it controls the flow direction by reversing the poles.
  • The set up I had in mind was to keep a 20 liters water bottle to supply the system.

Tubing & drop water system

  • This fact is very important due to the different types of plants. Since each of them would need a specific amount, controlling the dripping current and the water pressure is essential.
  • Also, the setup of the tubing was thought accordingly to the sunlight, the size of each pot, and the amount of water required.
  • I choose LLDPE micro-tube for its flexibility, low heat conduction, and for being a type of plastic that has great recycle potential.
  • The output for the water was made of a 2.3 cm adjustable irrigation dripper and a thin plastic stake to hold it. The flow is controlled by the rotation of the cap.

IoT automation solution

  • The watering routine needed to happen without human intervention, running during specific hours of the day and deliver the same water amount each time.
  • In order to automate the water pump functioning, it was needed a 5v DC relay module to conduct 12v DC and trigger turn on and off routines.
  • The relay module had to be controlled through the GPIO interface of a Raspberry Pi 3 Model B.
  • This could be solved with some python code implementing the RPi.GPIO module to control the Raspberry pi's GPIO interface.
  • I have been very curious to test Home Assistant since it was launched in 2013, I thought to give it a try. This system allows the automation of all the routines. It stores event data and has a very friendly mobile and desktop UI. Besides, it has good built-in security configuration options, custom python code can be deployed easily. And one important fact for me was that it works over the internet.

Putting all the pieces together

As in any software and hardware product, the best approach is to break it down into iterations to learn, adapt, and evolve the solution. So if you try this experiment, start small and increment it little by little.

First step

  • Install and configure Home Assistant in the Raspberry pi.
  • Follow the instruction of the official HA site. It has a very complete guide to set up the network, credentials, and setting up modules.
  • If you are planning to control it over the internet and/or via SSH, please, set up an HTTPS certificate, 2FA, and very strong passwords. Also, if you don't have a static public IP, you will need Duck DNS as well.
  • HA's security features are fair enough to make it a good remote tool, so use them!
  • If you are looking for a more detailed step by step guide, this one from Lewis Barclay will introduce you to the main functions of HA.

Second step

  • Connect the relay module to the GPIO following the schematics diagram.
- Rpi pin 2 to relay VCC
- Rpi pin 39 to relay GND
- Rpi pin 7 to relay IN.
  • Since I am using 5V of the RPi as a power source for the relay. (Rpi pin 2 -> VCC). I set a small ~ 1kΩ resistor between pin 8 and the relay's IN pin to protect the Rpi GPIO.
  • Set up the connection between the 12v DC power source for the pump and the relay module. Use this Raspberry PI GPIO layout to confirm pin usage.
Schematics for the main connections
Set up to mount the relay module, the power supply, and the RPi.
The ethernet cable was used to connect the water pump.

Third step

  • Set up the physical infrastructure for the tubing, the pump, the water source, and the plants.
  • This isn't a step you might get right on the first try. All of the components might need a special setup. As long as the plants are getting enough water and the setup is safe, you are good to go.
  • I will give some more tips from this experience later in this post.

Last step

  • Once you have HA running, the GPIO set up and the relay module connected to the power source for the water pump. You are ready to set up HA to start controlling the water pump.
  • To avoid making this post too big, I won’t write a step-by-step guide to write the routines and the coding behind them.
  • You can see and fork the github source code at will.
  • The main 3 things I wanted to automate with HA are the following:

1 - The relay module on/off routine.

  • As you can see in the code, to set up the GPIO controller to turn the relay on or off is quite simple. Once identified the port and configure it as a switch module, you are set.
  • Add it to the configuration.yaml file and add the switch entity in the dashboard so it will help you control the relay at will.
# Defining the gpio for the pump relay and template
switch:
- platform: rpi_gpio
ports:
04: water_pump_relay
invert_logic: true
  • Also, as a safety measure to protect the pump and avoid water misuse, I configured a timer controller. It will be triggered every time the pump is turned on. After 1 min, it will turn the pump off automatically.
  • This one is a good automation practice, define a limit of use to anything that might operate autonomously.
  • Add the timer in the configuration.yaml file and create an automation routine
# Setting up a time to control max time for the pump
timer:
watering_timer:
duration: '00:01:00'
  • Also, create an automation routine so it runs for a minute and then returns to the off state. Add the routine for the timer in the automations.yaml file.
- alias: Timerswitch
id: Timerstart
trigger:
- platform: state
entity_id: switch.water_pump_controller
to: 'on'
action:
- service: timer.start
entity_id: timer.watering_timer
- alias: Timercancel
id: Timercancel
trigger:
- platform: state
entity_id: switch.water_pump_controller
to: 'off'
action:
- service: timer.cancel
entity_id: timer.watering_timer
- id: Timerstop
alias: Timerstop
trigger:
- platform: event
event_type: timer.finished
event_data:
entity_id: timer.watering_timer
action:
- service: switch.turn_off
entity_id: switch.water_pump_controller

2 - A daily schedule script to trigger the relay.

  • The core functionality for this project to work is to make HA water the plants at certain hours of the day.
  • For this specific set up, my plants need to receive water twice a day. So I created a script to start the water pump at 8:30 and 19:30. It runs twice at the scheduled hour with an interval of 3 minutes. This helps the water to soak in since some of the pots are small. Remember that the water pump has a 1-minute timer each time it is triggered.
  • HA has an automation interface where I think this can be accomplished. But since I prefer to have more control of the code for some chores, I decided to write a python script.
  • AppDaemon is a great add-on to automate this sort of routine, and it is a good python option for HA. So if you like coding, it could be a good choice.
  • About time zones use in HA. By default, it is set up to run the server and daemons at UTC. So be aware to adjust it to your timezone with the timedelta function.
#
# Schedule when to trigger a water pump at specific hours.
# Arguments:
# - morning_schedule
# - evening_schedule
import hassapi as hass
import datetime
class Watering(hass.Hass):def initialize(self):
self.log("*** Starting Water Pump Scheduler at [SP time]: %s | [UTC time]: %s ***", datetime.datetime.now(), self.datetime())
# self.log("Current time self.datetime() : %s",self.datetime())
utc_current_datetime = self.datetime()
# Schedule daily watering. Once during the morning and once during the evening.
morning_water_time = self.parse_datetime(format(self.args["morning_schedule"]))
utc_morning_water_time = morning_water_time + datetime.timedelta(hours=4)
utc_morning_water_time_3 = utc_morning_water_time + datetime.timedelta(minutes=3)
evening_water_time = self.parse_datetime(format(self.args["evening_schedule"]))
utc_evening_water_time = evening_water_time + datetime.timedelta(hours=4)
utc_evening_water_time_3 = utc_evening_water_time + datetime.timedelta(minutes=3)
# Schedule a daily callback that will call run_daily() at 8am and 7pm every day
handle_morning = self.run_daily(self.daily_water_callback, self.parse_time(format(utc_morning_water_time)))
handle_evening = self.run_daily(self.daily_water_callback, self.parse_time(format(utc_evening_water_time)))

# Schedule second round daily callback 3 min after the first call
handle_morning = self.run_daily(self.daily_water_callback, self.parse_time(format(utc_morning_water_time_3)))
handle_evening = self.run_daily(self.daily_water_callback, self.parse_time(format(utc_evening_water_time_3)))
self.log("Morning Schedule (UTC). First round: %s",self.parse_time(format(utc_morning_water_time)))
self.log("Morning Schedule (UTC). Second round: %s",self.parse_time(format(utc_morning_water_time_3)))
self.log("Evening Schedule (UTC). First round: %s",self.parse_time(format(utc_evening_water_time)))
self.log("Evening Schedule (UTC). Second round: %s",self.parse_time(format(utc_evening_water_time_3)))
if utc_morning_water_time < utc_current_datetime:
self.log("Morning watering was already triggered at: %s", self.parse_time(format(utc_morning_water_time)))
elif utc_morning_water_time > utc_current_datetime:
self.log("Morning watering yet to be triggered at: %s", self.parse_time(format(utc_morning_water_time)))
message ="As plantas serão regadas às: " + str(self.parse_time(format(morning_water_time)))
self.notify(message)

if utc_evening_water_time < utc_current_datetime:
self.log("Evening watering was already triggered at: %s", self.parse_time(format(utc_evening_water_time)))
elif utc_evening_water_time > utc_current_datetime:
self.log("Evening watering yet to be triggered at: %s", self.parse_time(format(utc_evening_water_time)))
message ="As plantas serão regadas às: " + str(self.parse_time(format(evening_water_time)))
self.notify(message)

self.log("Water Pump state is currenlty: %s", self.entities.switch.water_pump_controller.state)
def daily_water_callback(self, kwargs):
# Call to Home Assistant to turn the porch light on
self.log("Water Pump current state: %s", self.entities.switch.water_pump_controller.state)
if "water_pump_switch" in self.args:
self.turn_on(self.args["water_pump_switch"])
self.log("Water Pump automation state: %s", self.entities.switch.water_pump_controller.state)
self.notify("As plantas estão sendo regadas agora")

3 - Monitoring and data

  • One great thing about automating tasks is that reporting and data collection are also useful to monitor and get feedback. HA comes with great data monitoring capability. It tracks and keeps all event data in a database.
  • If you can imagine, sensors, switches, system events, cellphone integration, and many other entities are generating data. This grows very fast in HA, increasing the time of processing the data.
  • Since I am using a Raspberry PI 3 B with 1GB RAM, I wanted to use as little memory as possible to avoid overworking it and slow down the whole system. This is done by selecting and filtering the event data that you want HA to store.
  • Keep it as minimum as possible so the RPI can run smoothly. This is a known issue for HA deployments in a Raspberry Pi. Remember that it is a little but powerful machine.
  • To do it, you need to set up the recorder option in the configuration.yaml file.
recorder:
# Specify the number of history days to keep in recorder database after a purge.
purge_keep_days: 1
commit_interval: 2
# Everything is included by default.
# Ensure you are keeping only what you need to keep DB small
db_integrity_check: true
# Automatically purge the database every night at 04:12 local time
auto_purge: true
include: # Include everything you graph and will want to see later
domains:
- binary_sensor
- switch
- sensor
entities:
- automation.timerswitch
- timer.watering_timer
- switch.water_pump_controller
- binary_sensor.humedad_tierra
# Everything is included by default.
exclude: # Eliminate anything that you never graph or refer back to
domains:
- automation
- updater
- person
- zone
- device
- hassio
- camera
  • The data captured helps me to monitor how many times the plants got water. Some days I might decide to water them extra depending on the day's temperature and humidity levels.
  • In order to better track the progress, I set up an IP camera and stream it via RTMP to the HA and mount it as an entity. In this way, I can see the plants at any time on the dashboard.
Home Assistant dashboard view with IP camera streaming.

Final note

  • HA is a great tool and it has great potential. This simple setup is enough for the main purpose of taking care of the plants while I am away.
  • I even experimented with a cheap hygrometer to monitor the water vapor in the soil, but it stopped working after a week.
  • Some next iterations could involve adding temperature and humidity sensors and triggering the pump when the ambient temperature is at a certain level.
  • The set up of the tubing is very important if you want to control the amount of water for each pot. Unless you have a big flat space to lay all the pots together, then you might face a challenge.
  • The plants were used to receive a different amount each. Depending on the size and plant species, they would receive less water. I knew that the plants were used to receive at least 500ml of water each day.
  • Since the flow rate of the pump is 120ml/min, then I knew that I needed to trigger it at least 4 minutes each day.
  • In my case, I had to apply Bernoulli's Principle to adjust the height and position of each pot so the tubing set up would regulate the water pressure and velocity to reach every plant.
  • I had to simulate the flow to calculate the amount of water that each pot would receive with this pump system every time it was triggered for a minute.
  • This test gave a good understanding of the position, water pressure, and total amount of water needed. Adding all up, I knew I needed at least 15lt of water to keep them safe for 30 days.
  • It has been 3 weeks since the plants are on their own and the automation is working well. Monitoring them with the camera has helped a lot to validate and test this fun project. :)

--

--

johann arispe
The Startup

“You can make anything by writing.” — C.S. Lewis