The Lake Water Irrigation Project

Carl Nordin · July 15, 2018

Background

The house I live in has access to “lake water”, that is, a parallell water grid with irrigation water directly from lake Mälaren, in addition to the normal utilities. There are rules to when and how this water can be used, which this project automates.

The water grid is provided by a non-profit  association named “Samfällighetsföreningen Sörgärdets Sjövatten” . The rules that govern the usage are:

  • We can use the water on days with even dates. 2, 4, 6…30.
  • Only one sprinkler can be used at any time due to pressure issues.

Some additional factors are:

  • The property has pavements at its border and soaking people is not appreciated.
  • At one of the pavements there are people returning home from the pub at night. They sometimes get peculiar ideas…

The water network

The picture below shows how the water network in the garden is constructed. The red part is constantly pressurized, the blue parts are pressurized when the main valve is open and the black parts are only pressurized whenever its corresponding valve is open.

Lake water contains a lot of biological material such as algae, humus etc. so filtration is needed to keep the valves functioning. The filter provides this for the system.

In case of a valve malfunction the water will still be turned off since two valves, the main and the corresponding sprinkler valve must both be open for the water to flow.

A valve:

Electronics

These are the basic connections:

Here are some actual pictures of the build:

Code

The system is currently controlled by a bash script. The order of the sprinklers are specific to our garden.

The script is scheduled to run at night when few people are active and it runs the sprinklers closest to the pavements first in order to avoid soaking anyone later in the cycle.

At very early Saturdays and Sundays there are people returning home from the pub at night that pass our garden. They sometimes get peculiar ideas and a running sprinkler in the summer heat can provoke undesired behaviour. Therefore the cycle is started later in the morning those days.

water.sh

#/bin/bash

i2cset="/usr/sbin/i2cset -y "
i2cget="/usr/sbin/i2cget -y "

# Relay card 1
allrc1="1 0x20 0xa 0xff"
sprinkler1="1 0x20 0xa 0x01"
sprinkler2="1 0x20 0xa 0x02"
sprinkler3="1 0x20 0xa 0x04"
sprinkler4="1 0x20 0xa 0x08"
sprinkler5="1 0x20 0xa 0x10"
sprinkler6="1 0x20 0xa 0x20"
sprinkler7="1 0x20 0xa 0x40"
sprinkler8="1 0x20 0xa 0x80"

 
# Relay card 2
allrc2="1 0x21 0xa 0xff"
main="1 0x21 0xa 0x01"
root="1 0x21 0xa 0x02"
sprinkler9="1 0x21 0xa 0x04"


WATERTIME=1800
#WATERTIME=30
COOLDOWNTIME=10

function log() {
	echo `/bin/date +%Y-%m-%d\ %H:%M:%S` $1 >> /home/pi/irrigation.log
}

function change_state() {
	local bus=$1
	local chip=$2
	local addr=$3
	local bits=$4
	local state=$5

	local curr=`$i2cget $bus $chip $addr`

	if [ "$state" == "off" ]; then
		local new=$(($curr & ~$bits))
		$i2cset $bus $chip $addr $new
	fi

	if [ "$state" == "on" ]; then
		local new=$(($curr | $bits))
		$i2cset $bus $chip $addr $new
	fi
}

function off() {
	local bus=$1
	local chip=$2
	local addr=$3
	local bits=$4

	change_state $bus $chip $addr $bits "off"
	/bin/sleep 1
	change_state $main "off"
	/bin/sleep $COOLDOWNTIME
}

function on() {
	local bus=$1
	local chip=$2
	local addr=$3
	local bits=$4

	change_state $main "on"
	/bin/sleep 1
	change_state $bus $chip $addr $bits "on"
	/bin/sleep $WATERTIME
}

function go() {
	local bus=$1
	local chip=$2
	local addr=$3
	local bits=$4

	on $bus $chip $addr $bits
	off $bus $chip $addr $bits
}



if [ "$1x" == "x" ]; then
	log "Normal schedule"
	log "Turning off all in relay card 1"
	off $allrc1
	log "Turning off all in relay card 2"
	off $allrc2

	log "Sprinkler 8 active"
	go $sprinkler8

	log "Sprinkler 6 active"
	go $sprinkler6

	log "Sprinkler 7 active"
	go $sprinkler7

	log "Sprinkler 9 active"
	go $sprinkler9

	log "Sprinkler 5 active"
	go $sprinkler5

	log "Sprinkler 3 active"
	go $sprinkler3

	log "Sprinkler 2 active"
	go $sprinkler2

	log "Sprinkler 1 active"
	go $sprinkler1

	log "Sprinkler 4 active"
	go $sprinkler4

	log "Irrigation done!"
else
#	echo "Manual $1 $2"
	eval bit=\$$1

	change_state $bit $2
fi

exit

root.sh

Runs the in-soil irrigation.

# !/bin/bash

function log() {
	echo `/bin/date +%Y-%m-%d\ %H:%M:%S` $1 >> /home/pi/irrigation.log
}

log "Root irrigation active"
/home/pi/water.sh main on
/bin/sleep 1
/home/pi/water.sh root on
/bin/sleep 60
/home/pi/water.sh root off
/bin/sleep 1
/home/pi/water.sh main off
log "Root done!"

crontab

You can’t combine time and day of month and day of week conditions in crontab. The solution here is to have two script files that are executed at specific times and days of month, and the day of week condition is checked in the scripts.

0 3 2-30/2 * * /home/pi/weekday.sh
0 4 2-30/2 * * /home/pi/holiday.sh

weekday.sh

# !/bin/bash

function log() {
	echo `/bin/date +%Y-%m-%d\ %H:%M:%S` $1 >> /home/pi/irrigation.log
}

dayofweek=`/bin/date +%u`

if [ "$dayofweek" -ne "6" -a "$dayofweek" -ne "7" ]; then
	log "Weekday!"
	/home/pi/water.sh
fi

holiday.sh

# !/bin/bash

function log() {
        echo `/bin/date +%Y-%m-%d\ %H:%M:%S` $1 >> /home/pi/irrigation.log
}

dayofweek=`/bin/date +%u`

if [ "$dayofweek" -eq "6" -o "$dayofweek" -eq "7" ]; then
	log "Holiday!"
	/home/pi/water.sh
fi

Parts

(Links are to both Swedish and international sites)

Twitter, Facebook