-
Notifications
You must be signed in to change notification settings - Fork 16
Weather based irrigation
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.
-
Scheduling irrigation (days,time) - done by Appdaemon
-
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
-
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.
-
Water usage (Litter/Duration) by tap/day/month. Require a global home water meter and Grafana/Influx
-
Ability to manual irrigation (manual time) in case needed
Query actual weather conditions each hour from OpenWeatherMap and estimate/calculate the following:
-
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,
-
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).
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](https://user-images.githubusercontent.com/13034429/57979726-79ab5f00-7a2a-11e9-9c48-247f5cfb1672.png)
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.
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 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:
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 |
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 |
-
HA
-
Appdaemon
-
Hardware: Sonoff 4 ch pro to switch on/off the taps
-
Sonoff firmware: Tasmota
![sonoff](https://user-images.githubusercontent.com/13034429/57979901-3c47d100-7a2c-11e9-8580-5a01fbaec10e.png)
![Sonoff 4 ch pro](https://user-images.githubusercontent.com/13034429/57979365-5a5e0300-7a25-11e9-9d5e-dbf85052c7ae.png)
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.
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
Add this to your configuration file.
This is the core that maintain the queue level per tap and calculate the ETo.
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
-
A free token from openweathermap. Add your taps in this example there are two taps
-
p1 and p2 is the names of the taps.
After this stage you should have five new sensors (base on the above configuration)
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 |
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
# 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
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
-
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
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
-
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.
m_week_duration_min: input_number.wbi_week_p2_duration
-
Scheduling per tap
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)
-
Changing the per tap queue level
sensor.wb_irrigation_p1
This is usefull for debug (usualy it is calculated)
![developer tools](https://user-images.githubusercontent.com/13034429/57979835-7c5a8400-7a2b-11e9-943a-d9a34fb4d345.png)
![newer version of hass developer tools](https://user-images.githubusercontent.com/13034429/146738480-09fd9d04-b7ae-48eb-9d9b-28b0bd57e048.png)
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
-
Rain factor: mm to ev factor. see above
-
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.
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
configuration similar to the water sensor.clock
![142733197 9e22793e 6f32 4231 824d c50199473c9f](https://user-images.githubusercontent.com/13034429/142733197-9e22793e-6f32-4231-824d-c50199473c9f.png)
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)
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).
CounterDebounce 1000
TelePeriod 60
SetOption36 20
Add this to your configuration file.
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 }}"
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. |