View on GitHub

Smart Irrigation

A Home Assistant integration to optimize irrigation

General configuration

Main page: Configuration
Previous: Guided setup
Next: Zone configuration

This page provides the following global settings:

Automatic weather data update

If enabled, specify how often sensor update should happen (minutes, hours, days). You can also set up an update delay to be used to delay the first update. THis is useful in case your sensors do not provide a value immediately after Home Assistant starts.

As calculation needs weatherdata make sure to update your weather data at least once before calculating.

Automatic duration calculation

If enabled, set the time of calculation (HH:MM). Calculation uses weatherdata that is collected in updates to determine irrigation duration.

Each zone reads only the readings that arrived since its own last calculation, and remembers how far it has read. Readings are dropped once every zone using that sensor group has consumed them, so two zones sharing a group can calculate at different times without either of them losing data.

Irrigation usually starts hours after the calculation, and it can rain in between. When the start trigger is reached, each automatic zone's duration is reworked against the rain collected since its calculation, so a night of rain shortens the run or cancels it instead of watering the full calculated amount on wet ground.

The bucket itself is left alone by that. It is a running balance: irrigation credits it by the water actually applied and the next calculation adds the whole interval's rain, so crediting the rain at the start as well would count it twice. A run is only ever shortened this way, never lengthened, and a dry night leaves the calculated duration exactly as it is.

Note that the run still starts at the time it was scheduled for. A trigger set to finish at sunrise works back from the duration known at calculation time, so a run shortened by rain finishes early rather than starting late.

Calculate evapotranspiration hour by hour (beta)

On for a new installation, off for one that already existed. A fresh installation starts on it, because it is the better arithmetic; an installation set up before it arrived keeps the daily equation until its owner switches, because the two give different numbers and nobody's watering should change on an update without being asked. When on, PyETO sums the FAO-56 hourly equation (Eq. 53) over each hour of the zone's window instead of running the daily equation on the window's averages. The daily form is biased by cloudiness, because an average day hides whether the sun and the heat came together; summing the hours removes most of that bias. Calculating hour by hour at all is an idea taken from JustChr's Irrigation Plus fork, which is where it was first tried on this integration; the equations here are written from FAO-56 itself and checked against the paper's own worked example.

It needs temperature, humidity and wind speed in the sensor group (a sensor or a weather service), and the site's coordinates.

It is worth having when readings arrive through the day. Each hour is priced from the readings of that hour, so an update interval of minutes or an hour is what the form is for. One update a day leaves a single reading held across twenty-four hours: it still runs, and it does not produce nonsense, but the hours then differ only by the sun and the result is no more trustworthy than the daily equation's on the same data. Measured on a synthetic clear day, which of the two lands closer to the truth in that case depends on the hour the samples fell in. If your sensor group updates once or twice a day, raise the update frequency before reading anything into either form.

Solar radiation without a sensor. The hourly equation needs the sun of each hour, and there are three ways it can have it. A group with a radiation or illuminance sensor reads its own, as before. A group without one whose weather service can be asked reads the service's own hourly history, which measures and models it: Open-Meteo publishes it, and OpenWeatherMap or Pirate Weather answer through the Open-Meteo fallback they already use for radiation.

An installation with neither, a set of plain sensors and no weather service, estimates it: the day's temperature range gives the day's radiation (FAO-56 Eq. 50, the same equation the daily form falls back on), and the sun's own path over that day says which hours received it. Summed over a day the estimate is exactly what the daily equation would have used, so the amount of sun credited does not change; what changes is that it is placed on the hours it belongs to, which is the bias the hourly form exists to remove. The calculation log records whether the sun of a run was measured or estimated.

A greenhouse is the exception and keeps the daily equation when it has no sensor of its own: no reading of the sky describes what reaches a plant under glass, so there is nothing to estimate from. A lux sensor on the inside answers that properly, and the sensor group takes one.

Forecast days. A zone whose engine looks ahead waters on the mean of today and the days to come, so a hot tomorrow raises today's run. Those days are now read hour by hour as well: each one is priced as its own 24 hours, and the measured window joins the average as the rate per day it implies. Every term of that mean is then hourly, which is the point, since averaging an hourly sum with a day computed from its own averages would put the bias straight back in.

With any other module, or when the hours cannot be reconstructed (no readings, a field missing everywhere, a greenhouse with no radiation or illuminance sensor, or fewer forecast days available than the engine asks for), the daily equation keeps being used, so switching it on never leaves a zone without a calculation. The calculation explanation says which form was used.

Automatic weather data pruning (removed)

Weather data used to be cleared on a timer, and that setting no longer does anything.

It existed to stop the collected data growing without end, which pruning after each calculation now handles by itself. What it also did was throw away readings nobody had consumed: the clear ran at a fixed time while the calculation time is yours to choose, so moving the calculation earlier silently lost everything collected between the two, every night. A calculation at 18:55 against the default clear at 23:59 discarded five hours of evaporation a day, and the next calculation was short by that much.

Readings are also capped at a week, so nothing accumulates even if a zone stops calculating. The Clear all weather data action is still there for a deliberate reset.

Days between irrigation events

Configure the minimum number of days that must pass between irrigation events. This setting allows you to control how frequently irrigation can occur, which is useful for:

How it works:

The value is the length of the watering cycle in calendar days: set to N, irrigation happens every N days.

Example scenarios:

The system automatically tracks the number of days since the last irrigation event. The counter is incremented once per calendar day, at midnight, whether or not irrigation happened that day. If an irrigation trigger occurs but insufficient days have passed, the event is skipped and the counter simply keeps running. When enough days have passed, the next trigger will fire the irrigation event and reset the counter to 0.

This feature works alongside existing precipitation forecasting - if both restrictions apply, both must be satisfied for irrigation to occur.

Skipping a run

A start trigger can be held back by the conditions below, all off by default. They are checked once a day, when the first start trigger is reached, and the Info page shows each of them with its numbers: whether it is off, could not be checked, is not blocking or is blocking. When a run is skipped, the smart_irrigation_irrigation_skipped event fires with the reason.

A condition that cannot be checked, because its sensor is unavailable or the weather service cannot be read, never stops a run: watering goes ahead as it would without it.

Thresholds are entered in your unit system and a sensor is read in its own unit, so a sensor in °F works on a metric installation.

Soil moisture is set on each zone rather than here. Give a zone a soil moisture sensor and a threshold in %, 50 unless you set one, and while the reading is at or above it that zone sits the run out and the others water. Its duration for that run goes to 0 and its bucket is kept, so the deficit rolls over to the next run.

Continuous updates (experimental)

Continuous updates is an experimental feature that tries to capture more granular weather data to avoid missing chunks of weather patterns. For a zone to be continuous updated, it needs to:

Any zone that does not meet the above requirements is not included in the continuous updates and instead will be included in the automatic update and calculation at the time configured. Any zone that does meet this requirement will not be included in the automatic update and calculation.

A sensor debounce setting is also provided to provide control over the speed of continuous updates.

Please note that this is experimental right now and will have bugs.

For continous updates, in the future, it will likely use specific set of aggregates (last for all data points except for solar radiation which will use average of riemann integral) and also requires current precipitation to be mapped in the sensor group.

Calculation log

Two days with what looks like nearly identical weather can produce very different watering volumes, and once a calculation has run there is normally no way to see why. Enable Calculation log to append one record per zone calculation to config/smart_irrigation/calc_log.jsonl (one JSON object per line, in metric units), so days can be compared afterwards instead of reconstructed by hand.

Each record holds the complete chain:

Dry runs (the dry_run option of the calculate services) are logged too - they are exactly when you ask "why this number?" - but every record carries a dry_run flag, so a dry run is never mistaken for a real calculation.

The setting is off by default. The file is capped at 2 MB and rotated (one backup kept), so it can be left on for a whole season. The most recent records are also included in the diagnostics download with coordinates rounded and entity ids removed, so they can be attached to an issue in one step.

To compare two days, for example with jq:

jq -c 'select(.zone.name == "Lawn") | {t: .timestamp, eto: .module.days[0].eto, sol_rad: .module.days[0].sol_rad, estimated: .module.days[0].sol_rad_estimated, bucket: .outputs.bucket_after, duration: .outputs.duration}' calc_log.jsonl

Unit System Responsiveness

Smart Irrigation automatically detects and responds to changes in your Home Assistant unit system setting (metric/imperial). When you change the unit system in Home Assistant:

This ensures seamless transitions between unit systems without losing your configuration data.

Main page: Configuration
Previous: Guided setup
Next: Zone configuration