Weather based irrigation

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.

My dashboard - two taps

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

ETo will increase the taps queue and rain will reduce it.
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
reduces the level, rain/irrigation fills 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 are in this book

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).

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

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:

.With wbi
[options=“header”,cols=“1,1,1,1,1,6”]
|=======================================
| 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
|=======================================

.Without wbi
[options=“header”,cols=“1,1,1,1,1,6”]
|=======================================
| 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
|=======================================

This is how it looks in grafana

image

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

  1. Install latest Tasmota firmware
  2. Sprinkler Valve could be any s 48VAC or DC Sprinkler
  3. Connect valve power throw the Sonoff relay

Tasmota configuration

This is an example for 2 taps.
The rules make sure that the taps won’t stay opened 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

Copy this project <config directory>/custom_components/ folder to your <config directory> directory
make sure you are in sync with the the right version of hass (see above)
after you copy the data you should reboot/restart HA

Enable wbi component

Add this to your configuration file

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.

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.+

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 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 
  notify: [tap_open] 
  taps: 
     - name: p1
       days: [2,5]  # 1-7 1 for sunday, .. 7 for saturday 
       stime: "05:45:00" # time to start irrigating 
       m_week_duration_min: input_number.wbi_week_p1_duration
       switch: switch.wbi_p1
       manual_duration: input_number.wbi_p1_duration
       queue_sensor: sensor.wb_irrigation_p1 
       water_sensor: variable.wbi_water_p1
       time_sensor: variable.wbi_last_duration_p1
       
     - 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

more could be found here:wiki

Any questions/issues/suggestions could be submitted to github

9 Likes

Is it possible to use this solution to toggle an smart switch? I have a very basic setup for my sprinklers. Just a smart switch that will turn on/off my waterpump. I was looking for something like this and it’s all I want, but I need to be able to set an other action.

Thanks.

Yes, you can.

Can you give some directions? :slight_smile:

Follow the wiki. You can open issues in the GitHub

@hhaim Have you thought off adding your app to HACS? This would make it available for many more people?!

3 Likes

Just getting this set up, thanks for sharing! Is is possible for it to water twice per day? Ie morning and evening?

Hi @hhaim
I got extremely excited when I found your irrigation solution as this is exactly what I have been looking for :slight_smile: … Thank you that you made a “really” smart irrigation solution not dumb on/off thingie.
I tried to walk through everything few times but I must be doing something wrong.

This is what I see in AppDeamon4 log:

020-04-12 00:16:06.066584 INFO AppDaemon: App 'hello_world' added
2020-04-12 00:16:06.067305 INFO AppDaemon: App 'wb_irrigation' added
2020-04-12 00:16:06.068265 INFO AppDaemon: Found 2 total apps
2020-04-12 00:16:06.068845 INFO AppDaemon: Starting Apps with 2 workers and 2 pins
2020-04-12 00:16:06.070087 INFO AppDaemon: Running on port 5050
2020-04-12 00:16:06.136710 INFO HASS: Evaluating startup conditions
2020-04-12 00:16:06.203941 INFO AppDaemon: Got initial state from namespace default
2020-04-12 00:16:08.076149 INFO AppDaemon: Scheduler running in realtime
2020-04-12 00:16:08.078619 INFO AppDaemon: Adding /config/appdaemon/apps to module import path
2020-04-12 00:16:08.079089 INFO AppDaemon: Adding /config/appdaemon/apps/ada to module import path
2020-04-12 00:16:08.089451 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/wb_irrigation_app.py - ignoring
2020-04-12 00:16:08.090357 INFO AppDaemon: Loading App Module: /config/appdaemon/apps/hello.py
2020-04-12 00:16:08.122207 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/ada/schedule.py - ignoring
2020-04-12 00:16:08.123962 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/ada/test.py - ignoring
2020-04-12 00:16:08.129051 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/ada/util.py - ignoring
2020-04-12 00:16:08.129928 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/ada/__init__.py - ignoring
2020-04-12 00:16:08.132710 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/ada/temp_sensor.py - ignoring
2020-04-12 00:16:08.133697 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/ada/temp.py - ignoring
2020-04-12 00:16:08.137232 INFO AppDaemon: Initializing app hello_world using class HelloWorld from module hello
2020-04-12 00:16:08.232406 INFO hello_world: Hello from AppDaemon
2020-04-12 00:16:08.235201 INFO hello_world: You are now ready to run Apps!
2020-04-12 00:16:08.238400 INFO AppDaemon: App initialization complete

Have I cutted too much from your repo ? or WBI does not work yet with AppDaemon 4 ?

In *_app.py I left only imports in the header and “class CWBIrrigation(HassBase): …”
In apps.yaml i put only section “wb_irrigation: …”
In irrigation.yaml I only adopted switches to my needs.

PS:
Forgot to mention that I’m newbie in AppDeamon … :slight_smile: so sorry if my question is trivial .

Hi, try with earlier AppDaemon version (start with 3) I didn’t upgrade to 4.0 yet

Looking into the logs it does not seems as AppDaemon version issue.
Please share more info

Any idea what’s wrong here please @hhaim?

 Log
[s6-init] making user provided files available at /var/run/s6/etc...exited 0.
[s6-init] ensuring user provided files have correct perms...exited 0.
[fix-attrs.d] applying ownership & permissions fixes...
[fix-attrs.d] done.
[cont-init.d] executing container initialization scripts...
[cont-init.d] 00-banner.sh: executing... 
-----------------------------------------------------------
 Add-on: AppDaemon 4
 Python Apps and Dashboard using AppDaemon 4.x for Home Assistant
-----------------------------------------------------------
 Add-on version: 0.2.3
 There is an update available for this add-on!
 Latest add-on version: null
 Please consider upgrading as soon as possible.
 System: HassOS 3.12  (armv7 / raspberrypi3)
 Home Assistant Core: 0.108.3
 Home Assistant Supervisor: 216
-----------------------------------------------------------
 Please, share the above information when looking for help
 or support in, e.g., GitHub, forums or the Discord chat.
-----------------------------------------------------------
[cont-init.d] 00-banner.sh: exited 0.
[cont-init.d] 01-log-level.sh: executing... 
[cont-init.d] 01-log-level.sh: exited 0.
[cont-init.d] appdaemon.sh: executing... 
[cont-init.d] appdaemon.sh: exited 0.
[cont-init.d] done.
[services.d] starting services
[services.d] done.
[10:42:29] INFO: Starting AppDaemon...
2020-04-12 10:42:33.729936 INFO AppDaemon: AppDaemon Version 4.0.3 starting
2020-04-12 10:42:33.731412 INFO AppDaemon: Python version is 3.8.2
2020-04-12 10:42:33.733208 INFO AppDaemon: Configuration read from: /config/appdaemon/appdaemon.yaml
2020-04-12 10:42:33.734619 INFO AppDaemon: Added log: AppDaemon
2020-04-12 10:42:33.736228 INFO AppDaemon: Added log: Error
2020-04-12 10:42:33.737614 INFO AppDaemon: Added log: Access
2020-04-12 10:42:33.739420 INFO AppDaemon: Added log: Diag
2020-04-12 10:42:33.828296 INFO AppDaemon: Loading Plugin HASS using class HassPlugin from module hassplugin
2020-04-12 10:42:33.917521 INFO HASS: HASS Plugin Initializing
2020-04-12 10:42:33.919108 INFO HASS: HASS Plugin initialization complete
2020-04-12 10:42:33.922185 INFO AppDaemon: HTTP is disabled
2020-04-12 10:42:45.049478 WARNING AppDaemon: Threads directive is deprecated apps - will be pinned. Use total_threads if you want to unpin your apps
2020-04-12 10:42:45.058611 INFO HASS: Connected to Home Assistant 0.108.3
2020-04-12 10:42:50.507582 INFO AppDaemon: App 'wb_irrigation' added
2020-04-12 10:42:50.511823 INFO AppDaemon: Found 1 total apps
2020-04-12 10:42:50.514462 INFO AppDaemon: Starting Apps with 1 workers and 1 pins
2020-04-12 10:42:57.272060 INFO HASS: Evaluating startup conditions
2020-04-12 10:42:57.621802 INFO AppDaemon: Got initial state from namespace default
2020-04-12 10:42:58.771980 INFO AppDaemon: Scheduler running in realtime
2020-04-12 10:42:58.788862 INFO AppDaemon: Adding /config/appdaemon/apps to module import path
2020-04-12 10:42:58.791577 INFO AppDaemon: Adding /config/appdaemon/apps/config-check to module import path
2020-04-12 10:42:58.794129 INFO AppDaemon: Adding /config/appdaemon/apps/ada to module import path
2020-04-12 10:42:58.842792 INFO AppDaemon: Loading App Module: /config/appdaemon/apps/heat_app.py
2020-04-12 10:42:58.901103 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/config-check/checkconfig.py - ignoring
2020-04-12 10:42:58.904916 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/ada/util.py - ignoring
2020-04-12 10:42:58.908922 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/ada/schedule.py - ignoring
2020-04-12 10:42:58.912954 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/ada/test.py - ignoring
2020-04-12 10:42:58.917091 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/ada/temp_sensor.py - ignoring
2020-04-12 10:42:58.921070 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/ada/__init__.py - ignoring
2020-04-12 10:42:58.924808 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/ada/temp.py - ignoring
2020-04-12 10:42:58.928267 INFO AppDaemon: Initializing app wb_irrigation using class CWBIrrigation from module heat_app
2020-04-12 10:42:58.933384 WARNING wb_irrigation: ------------------------------------------------------------
2020-04-12 10:42:58.935390 WARNING wb_irrigation: Unexpected error initializing app: wb_irrigation:
2020-04-12 10:42:58.937125 WARNING wb_irrigation: ------------------------------------------------------------
2020-04-12 10:42:58.943376 WARNING wb_irrigation: Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/appdaemon/app_management.py", line 820, in check_app_updates
    await self.init_object(app)
  File "/usr/lib/python3.8/site-packages/appdaemon/app_management.py", line 279, in init_object
    "object": app_class(
  File "/usr/lib/python3.8/site-packages/appdaemon/plugins/hass/hassapi.py", line 46, in __init__
    adbase.ADBase.__init__(self, ad, name, logging, args, config, app_config, global_vars)
  File "/usr/lib/python3.8/site-packages/appdaemon/adbase.py", line 75, in __init__
    self.dashboard_dir = self.AD.http.dashboard_dir
AttributeError: 'NoneType' object has no attribute 'dashboard_dir'
2020-04-12 10:42:58.946113 WARNING wb_irrigation: ------------------------------------------------------------
2020-04-12 10:42:58.948777 WARNING AppDaemon: Unable to find module wb_irrigation - initialize() skipped
2020-04-12 10:42:58.952582 INFO AppDaemon: App initialization complete

I would do this

  1. Move back to AppDaemon 3.0.5
  2. Keep the python code as it is. Don’t change it
    https://github.com/hhaim/hass/blob/fe26bcfbd3ac10bd27652e217741b2f1fa79e531/apps/heat_app.py
  3. Change only apps.yaml keeping only the wbi part

but how to move back to v3 if is not available in app-store anymore :frowning:

It should work on v4. I’m using the same integration on v4 without any issue.

I used (as you suggested) full heat_app.py code :slight_smile: and corrected my mistakes in yaml file (I missed the fact that name of my switches is not switch.wbi_p1 etc :))
Anyway now I see WBi working in the log file :slight_smile:

020-04-12 16:44:51.945200 INFO AppDaemon: Initializing app wb_irrigation using class CWBIrrigation from module heat_app
2020-04-12 16:44:52.037822 INFO wb_irrigation: start irrigation app
2020-04-12 16:44:52.819016 INFO wb_irrigation: irrigation init p1 sun,mon,thu 16:48:00 
2020-04-12 16:44:53.619558 INFO wb_irrigation: irrigation init p2 sun,tue,thu 16:46:00 
2020-04-12 16:44:53.624830 INFO AppDaemon: App initialization complete
2020-04-12 16:46:00.014930 INFO wb_irrigation:  irrigation event for p2
2020-04-12 16:46:00.020542 INFO wb_irrigation:  irrigation nothing to do queue: 500.0 
2020-04-12 16:48:00.024865 INFO wb_irrigation:  irrigation event for p1
2020-04-12 16:48:00.026314 INFO wb_irrigation:  irrigation nothing to do queue: 500.0 

but do not understand why WBI decided not to start irrigation today.
There was no rain since days.
Could you please give me some guidance where I did misunderstood logic ?

Second thing/idea :slight_smile: is that would it be possible to add sensor showing what is the plan for next irrigation phase (per tap) ? … just to see how WBI calculating/planning next irrigation time :slight_smile: + sensors with start time & days in order to make it visible in UI

Last thing :slight_smile: is a super kind request to add possibility (option) to use service call in place of switch state change.
I’m using RainBird device to control which taps are working and integration with RainBird (https://www.home-assistant.io/integrations/rainbird/) is giving a possibility to use switches but they are working with fixed time per tap.
Better option is to use service call where we could dynamically define irrigation duration time.

Is it much difficult to implement such extra option ?


Have a look how to tune it (once).Ev is 500 (More than zero) this is the reason it does not irrigate

hmmm I’ve read it few times :slight_smile: … and I did adjusted m_temp_celsius , m_temp_hours and also max week duration … ev is always 500 calculated somehow by WBI … does not matter whether I turn on tap manually or wait couple of hours.

image

image

Seems I’m missing something and do not understand how ev is being calculated and what exactly must happen to change this value :frowning: …
In my simplified way of thinking I thought that more time without rain or irrigation means ev goes down … more irrigation or rain mans ev goes up. Irrigation starts only when ev goes below 0.

Forgive me please but seems I need small explanation on top of what you provided in wiki.

Second unknown for me is how to check whether we receive accurate data from openweathermap ? can we check it somehow ? Just wants to be sure that I’m not getting data from a station which is very very far from my location :slight_smile:


fao59 should be in the range of 50-400 every day.

I would enable the component debug in hass and look into the log. the AppDaemon will work after the sensor will have a valid value.
The Queue size (wbi_p1/wbi_p2) in your case 500, could be tune manually using the service, but start with the sensor first (fao59)