Skip to content

Weather based irrigation

Hanoh Haim edited this page Jan 18, 2022 · 27 revisions

Objective

Let Home Assistant (HA) automatically adjusts the watering duration based on actual weather conditions. The controller reduces the amount of watering when the weather cools down/rains, and adds time when it heats up.
The scheduling days and when to start irrigation is constant and set by the user.

Dashboard with 2 taps

dashboard

Features

  1. Scheduling irrigation (days,time) - done by Appdaemon

  2. Tune watering duration by actual weather. On rainy days no irrigation, on hot days more irrigation. After one time tuning there is no need to touch it

  3. The user set per tap week duration in minutes. This time is for the hottest days. Irrigation can’t pass this duration in any case.

  4. Water usage (Litter/Duration) by tap/day/month. Require a global home water meter and Grafana/Influx

  5. Ability to manual irrigation (manual time) in case needed

How it works

Query actual weather conditions each hour from OpenWeatherMap and estimate/calculate the following:

  1. Evapotranspiration: evaporation (ETo) is how much water is lost from your soil due to either evaporation directly into the air or transpiration through the plants and into the air,

  2. Rain: How much water is added to the soil

The idea was taken from a leaky bucket (networking policers).+ Each tap will maintain a virtual queue and irrigation time will be calculated in such a way to zero the queue (ev reduce the level, rain/irrigation fill it).

How to estimate evaporation (ETo)

I’ve tested a few methods and found that the best and most accurate one is based on Penman–Monteith_equation

More details could be found Evapotranspiration and ETo

Luckily, there is a python library from Mark Richards pyETo that could calculate it and estimate what needed based on weather actual conditions.

The value of ETo by FAO-56 Penman-Monteith is a value between 1.0 (cold) to 12.0 (very hot).

an example of ETo value is taken from www.omicsonline.org and can be seen in the following charts

ETo over the year

To be more accurate I’ve calculated this number each hour and aggregate it so it now it is between (~100- cold) to 300-400(hot) in ev units and not in mm/day.

Estimating Rain

OpenWeatherMap based on your accurate location could provide this information. In some cases (if you are located close to a weather station) it is surprisingly accurate. Again, this is not a forecast it is actual rain in mm. The code accumulates the total mm and covert it to ev units using a simple factor. I’m using a factor of 100. Let’s take an example:

Total rain a day: 5 mm Day Ev : 5x 100 (ev/mm) = 500 ev Which is 5 days of cold weather ETo without irrigation.

Irrigation duration

Irrigation duration is based on the queue level at the time of irrigation time.

Irrigation time = (-queue level) * max_tap_time (min)

After Irrigation the queue is zeroed WBI works the same as your old system, it just reduces the time when it fits (e.g. rain, cold days etc)

Example:

Table 1. With wbi
Day old value evaporation (-) rain Ev (+) new value desc

0

0

-200

+500

+300

rain of ~5mm total

1

+300

-200

0

+100

no rain , no irrigation

2

+100

-200

0

-100

can irrigate

3

-100

-200

0

-300

can irrigate

4*

-300

-100

0

0

can irrigate — scheduled calculate the time

Table 2. Without wbi
Day old value evaporation (-) rain Ev (+) new value desc

0

0

-300

0

-300

rain of ~5mm total

1

-300

-300

0

-600

no rain , no irrigation

2

-600

-300

0

-900

can irrigate

3

-900

-300

0

-1200

can irrigate

4*

-1200

-300

0

0

can irrigate — scheduled calculate the time

Back to Reality - Home Assistant

Ingredients for 4 taps

  1. HA

  2. Appdaemon

  3. Hardware: Sonoff 4 ch pro to switch on/off the taps

  4. Sonoff firmware: Tasmota

Sonoff 4 ch

sonoff
  1. Install latest firmware from Tasmota

  2. Sprinkler Valve could be any s 48VAC or DC Sprinkler

  3. Connect Valve, Power throw the relay ( need a picture how)

Sonoff 4 ch pro

Tasmota configuration

This is an example for 2 taps. The rules make sure that the taps won’t stay open in case of a network problem. You should tune the time for your usec-case.

Tasmota configuration (once)
Rule1 on Power1#state==1 do  RuleTimer1 1800 endon on Rules#Timer=1 do power1 off endon on Power1#state==0 do  RuleTimer1 off endon
Rule2 on Power2#state==1 do  RuleTimer2 2700 endon on Rules#Timer=2 do power2 off endon on Power2#state==0 do  RuleTimer2 off endon
Rule1 on
Rule2 on
poweronstate 0
TelePeriod 60
SetOption36 20

Install HA custom component

see wiki section ( Install HA custom component)

Enable wbi component

Add this to your configuration file.

This is the core that maintain the queue level per tap and calculate the ETo.

HA Custom Component
wb_irrigation:
  api_key: !secret openweathermap_key
  rain_factor: 90
  max_ev: 3000
  min_ev: -1500.0
  name: "wb_irrigation"
  debug: false
  longitude: !secret accurate_longitude
  latitude: !secret accurate_latitude
  elevation: !secret accurate_elevation
  taps:
    - name: p1
    - name: p2

look into this example full example with 2 taps

  1. A free token from openweathermap. Add your taps in this example there are two taps

  2. p1 and p2 is the names of the taps.

After this stage you should have five new sensors (base on the above configuration)

Table 3. sensors
sensor name units desc

sensor.wb_irrigation_px

ev

per tap ev queue value

sensor.wb_irrigation_fao56

ev

per day ev value

sensor.wb_irrigation_rain

mm/hour

per hour mm rain (aggregation,reset every day)

sensor.wb_irrigation_rain_day

mm/day

last day total mm or rain

Appdaemon script

The app is responsible to to turn on the taps in specific schedule.
The total time is calculated from the weather component (wb_irrigation see below).

In case the tap state is changed to ON (manually) the time is taken from the input and weather queue is not updated.+

see how to install in the Wiki (other section). It is possible to estimate how much littler is consumed by each tap using the global water input sensor (if exists)

See here for switch and sensor definition for this app to work

This is an example for 2 taps

Appdaemon Irrigation configuration
# irrigation app
wb_irrigation:
  module: heat_app
  class: CWBIrrigation
  m_temp_celsius: 31 #fill from here https://www.holiday-weather.com/ average *day* temperatures in celsius hottest month
  m_temp_hours: 13 # average day hours hottest month
  enabled: input_boolean.wbi_enabled #disable irrigation
  water_sensor: sensor.water_total_external_norm # read total water, optional to read water global sensor shoiuld be removed in case you don't have a global sensor
  notify: [tap_open] # enable notification with the calculated time. Good for new users for evaluating the algorithm
  taps:
     - name: p1 # the name of the tap (just a name)
       days: [2,5]  # days for schedule, 1-7 1 for sunday, .. 7 for saturday
       stime: "05:45:00" # time to start irrigating for each day in days
       m_week_duration_min: input_number.wbi_week_p1_duration # a input time in minutes. This in the total week time to irrigate for the **hottest** day
       switch: switch.wbi_p1  # switch to enable/disable the tap ("on" is enabled, "off" is disabled)
       manual_duration: input_number.wbi_p1_duration # the timer for manual operation (on/off)
       queue_sensor: sensor.wb_irrigation_p1       # from wbi component, queue (in ev) for tap p1. used to tune the irrigation dynamically
       water_sensor: variable.wbi_water_p1         #  running variable counter for the total water in litter (from global sensor if exists).  *Always* should be provided.
       time_sensor: variable.wbi_last_duration_p1  # running variable counter for the time in minutes. can be used for estimating the water (litters). *Always* should be provided.

     - name: p2
       days: [1,3,5]
       stime: "05:00:00"
       m_week_duration_min: input_number.wbi_week_p2_duration
       switch: switch.wbi_p2
       manual_duration: input_number.wbi_p2_duration
       queue_sensor: sensor.wb_irrigation_p2
       water_sensor: variable.wbi_water_p2
       time_sensor: variable.wbi_last_duration_p2

What to Tune and How?

There are two main seasons and two main domains that need to be tuned . In Israel, there is the summer (most of the year) and some days of winters. In some other area (e.g. tropical) the rain factor is more important

Summer

  1. Set the average day temperature (Celsius) of the hottest day and average hours day in this day. You can use this to get the info

Appdaemon
m_temp_celsius: 31
m_temp_hours: 13

What’s important about those two values is the multiplication of them. In the above example the per day ev is 31*13= 400

  1. Set the week time (minutes) per tap

You should change the input_number.wbi_week_p2_duration value to be the total week time (minutes) in the hottest day.

Appdaemon
m_week_duration_min: input_number.wbi_week_p2_duration
  1. Scheduling per tap

Appdaemon
  taps:
     - name: p1
       days: [2,5]  # 1-7 1 for sunday, .. 7 for saturday
       stime: "05:45:00" # time to start irrigating

In this example it is Monday and Thursday at 05:45 in the morning

The scheduling is constant. The algorithm could decide not to irrigate in case of rain or to reduce the duration

(it is not possible to have constant irrigation times)

  1. Changing the per tap queue level

Appdaemon
sensor.wb_irrigation_p1

This is usefull for debug (usualy it is calculated)

developer tools
newer version of hass developer tools

Winter

HA Custom Component
wb_irrigation:
  rain_factor: 90
  max_ev: 3000
  min_ev: -1500.0

INFO: This values are located in the custom component (not in appdaemon) - so changing those value requires HA restart

  1. Rain factor: mm to ev factor. see above

  2. max_ev : Using this value you can limit the maximum number or no irrigation due to heavy rain. for example let’s say you have 50mm of rain. with 90 rain factor it gives 4,500. With cool weather with ev=100 it be converted to 45 days without Irrigation. if you want to limit it to 5 days of cool days (ev~100). you should set this value to 500.

Grafana/Influx configuration

todo

Local Rain sensor

Update 11/2021

Lately Openweather API does not report rain correctly (it has been working perfectly for two years, maybe related to covid-19). Rain sensor is a critical part of the solution, it does not need to be super accurate but it should report rain when it’s raining!

To solve this I connected an external rain sensor to Tasmota with clock configuration similar to the water sensor.

The sensor

142733197 9e22793e 6f32 4231 824d c50199473c9f
Figure 1. rain sensor

link to what i used, AliExpress example

The principal of the sensor is simple, every 0.5mm of water, it toggles the wire (connect and disconnect). So 1 pulse should be 1 mm of water. Tasmota will count the pulses. for more details see here.

The cost of the device is about ~9$. In my case I had a Tasmota located outside so I’ve just needed to use another GPIO. (water and rain)

Tasmota configuration

I’ve used GPIO-5 with pull up-resistor of 5K (GPIO-14 has an internal pull-up used for water in my case).

Configure is Counter. Each pulse (off/on) increments the counter by 1 so 1 clock is 1mm. However, power cycle will reset the counter. Because of that there is a need for a custom component (similar to water sensor).

Tasmota configuration (once)
CounterDebounce 1000
TelePeriod 60
SetOption36 20

HA counter component

Add this to your configuration file.

HA Custom Component
sensor:
  - platform: tasmota
    name: local_rain_total
    stopic: water_out
    id: 2
    unit_of_measurement: 'mm'
    icon: mdi:water-pump
    expire_after: 300
    value_template: "{{ (0 + (value))|int }}"
External_rain field
wb_irrigation:
  api_key: !secret openweathermap_key
  rain_factor: 90
  max_ev: 3000
  min_ev: -1500.0
  name: "wb_irrigation"
  external_rain : "sensor.external_rain"  # add this to point to the external sensor
  #debug: true
  longitude: !secret accurate_longitude
  latitude: !secret accurate_latitude
  elevation: !secret accurate_elevation
  taps:
    - name: p1
    - name: p2
Note
When using external sensor it is assumed that the counter/value of rain sensor is going up (similar to water sensor) and it is not reset or going down.