Universal Smart Irrigation
This hardware-agnostic Home Assistant Blueprint is a professional-grade solution for garden irrigation. It is designed to handle everything from simple flower bed setups to complex multi-zone systems with precision and intelligence.
Key Features
1. Intelligent Queue Management (Mutex-Lock)
- Feature: Prevents multiple irrigation zones from running at the same time.
- Benefit: Ensures stable water pressure and protects pumps from overload.
- Prioritization: Use a configurable “Start Delay” to determine which zone wins the race (e.g., prioritize your vegetable patch over the lawn).
2. Dual-Layer Weather Safety
- Preventive (Forecast): Checks the rain forecast (mm) before starting. If the predicted rainfall exceeds your threshold, the irrigation is skipped.
- Reactive (Live Veto): A physical rain sensor (e.g., Netatmo) can immediately abort an active irrigation cycle if it starts raining unexpectedly.
3. Flexible Operation Modes
- Sequential: Valves in a single zone are processed one after the other (ideal for low water pressure).
- Parallel: All valves in a zone open simultaneously (ideal for large areas with high-capacity pumps).
4. Advanced Sensor Logic
- Soil Moisture: Controlled by minimum and maximum thresholds. Irrigation only stops once the target moisture level is reached.
- Temperature Protection: Optional frost protection—irrigation will not start if the outside temperature is below X °C.
5. Hardware & Pump Support
- Pump Control: Configurable delay between valve opening and pump start to prevent pressure spikes (water hammer).
- Hardware Timers: Support for devices with internal safety timers (e.g., Gardena Bluetooth valves).
Prerequisites & Setup
To unlock the full potential of this blueprint, the following preparations are required in Home Assistant:
Required (Basic)
- Global Irrigation Lock: A manually created helper (
input_boolean.irrigation_lock) that must be selected in all instances of this blueprint.
- Zone Switch: One helper (
input_boolean.zone_x_active) per zone to enable/disable the automation.
- Soil Moisture Sensor: An entity providing moisture levels in percentage (%).
Optional (Advanced Features)
- Weather Forecast: A sensor or helper providing the expected rainfall for the next 24 hours in mm.
- Note: For services like DWD or Met.no, you may need a small template helper or a helper automation to fetch the forecast data (as modern HA weather entities require a service call).
- Mobile App: The Home Assistant app installed on your smartphone for push notifications.
- Physical Rain Sensor: A binary sensor or measurement sensor for the “Live Veto” function.
Limitations & Important Notes
- One Sensor per Zone: The logic is based on one central soil moisture sensor per blueprint instance. If you have 5 valves in one zone, they all react to this single sensor.
- Manual Helper Creation: Home Assistant cannot automatically create the required
input_boolean (Lock). This must be done manually once.
- Weather Data Fetching: This blueprint does not perform an active weather service call. it reads existing sensor data. Users must ensure their rain forecast sensor is updated regularly.
- Pump Logic: The pump is defined per zone. If multiple zones share one physical pump, the “Global Lock” is mandatory for the system to function correctly.
Installation & Quick Start
- Import the blueprint into Home Assistant.
- Create your global
input_boolean (Lock) for the main water line.
- Create a new automation from the blueprint for each zone.
- Assign your sensors and valves.
- Pro-Tip: Use different Start Delays (0s, 5s, 10s) for your zones to establish a clear hierarchy in the queue.
Notification Preview: Push messages are formatted as: [Zone Name]: [Custom Message] (Soil Moisture: X%). You’ll always know exactly what’s happening in your garden.
Disclosure: This blueprint has been AI generated. I have reviewed the code to the best of my abilities and I deem the code to be good.
Hello TheFreaker68,
sounds promising for my garden irrigation (16 Sonoff ZBV, 2 deep well pumps, maybe Gardena BT stuff later).
I failed importing the blueprint. The message is:
while parsing a block mapping in "", line 12, column 5: zone_name: ^ expected , but found '' in "", line 70, column 7: name: Max humidity (%) ^
Maybe you can help here?
best regards Holger
Hello,
A small error has crept in, but it can be fixed quickly.
The description for the minimum soil moisture ended up under the maximum soil moisture section.
The keyword description: is missing before it.
Here is the corrected YAML file:
# This blueprint is provided as it is. Use at your own risk!
# for full description see https://community.home-assistant.io/t/multi-zone-irrigation-multi-valve-sensor-driven/1006378
blueprint:
name: "Universal Smart Irrigation"
description: >
Contains: Multi-zone, Mutex-Lock, Priority handling,
Forecast-Check (DWD), Live-Rain-Veto, valve Parallel/Sequential-Mode,
Sun-Trigger for irrigation start time with offset and adaptable notifications.
domain: automation
input:
# --- BASIS & IDENTIFIKATION ---
zone_name:
name: Name of the irrigation zone
default: Garden
irrigation_switch:
name: Main switch (Helper)
description: "A switch to enable or disable the automation. You need to create a switch helper and select it here."
selector: { entity: { domain: input_boolean } }
water_source_lock:
name: Mutual exclusion helper (Lock)
description: "this switch ensures that no other instance of the blueprint runs in parallel in order to keep the water pressure up."
selector: { entity: { domain: input_boolean } }
start_delay:
name: Start-delay (Priority)
description: "This helps to set priority to the blueprint instance if more than one runs in parallel. The least delayed runs before the other"
default: 0
selector: { number: { min: 0, max: 60, unit_of_measurement: s } }
# --- BETRIEBSMODUS ---
valve_mode:
name: Valve-Mode
description: "Open the valves in parallel or sequentially?"
default: "sequential"
selector:
select:
options:
- label: "Sequential"
value: "sequential"
- label: "Parallel"
value: "parallel"
# --- Start Mode ---
start_mode:
name: Start-Mode
default: "time"
selector:
select:
options:
- { label: "Fixed Time", value: "time" }
- { label: "Sunrise", value: "sunrise" }
- { label: "Sunset", value: "sunset" }
fixed_time:
name: Start time
default: "06:00:00"
selector: { time: {} }
sun_offset:
name: Sun-Offset (Minutes)
default: 0
selector: { number: { min: -120, max: 120, unit_of_measurement: min } }
# --- Soil humidity ---
moisture_sensor:
name: Soil humidity sensor
selector: { entity: { domain: sensor } }
min_moisture:
name: Min humidity (%)
description: "When the soil reaches the defined percentage the irrigation starts"
default: 30
selector: { number: { min: 0, max: 100, unit_of_measurement: "%" } }
max_moisture:
name: Max humidity (%)
description: "When the soil reaches the defined percentage the irrigation stops"
default: 80
selector: { number: { min: 0, max: 100, unit_of_measurement: "%" } }
# --- Rain Forecast ---
rain_forecast_sensor:
name: Rain forecast sensor
default: []
selector: { entity: { domain: [sensor, input_number] } }
rain_threshold:
name: Rain threshold Forecast (mm)
default: 2
selector: { number: { min: 0, max: 50, unit_of_measurement: mm } }
# --- RAIN-VETO (PHYSICAL SENSOR) ---
live_rain_sensor:
name: Live-Rainsensor (Veto)
description: "Physical Sensor (e.g. Netatmo), which stops the irrigation in case of rain."
default: []
selector: { entity: { domain: sensor } }
live_rain_threshold:
name: Veto-threshold (mm)
description: "When the rain sensor value reaches the threshold the irrigation stops."
default: 0.5
selector: { number: { min: 0.1, max: 10, step: 0.1, unit_of_measurement: mm } }
# --- DEVICES ---
valve_entities:
name: Ventile
selector: { entity: { domain: [switch, valve], multiple: true } }
pump_entity:
name: Pumpe (Optional)
default: []
selector: { entity: { domain: [switch, plug] } }
max_duration:
name: Max. Duration (Minutes)
default: 15
selector: { number: { min: 1, max: 60, unit_of_measurement: min } }
# --- NOTIFICATIONS ---
notification_device:
name: Notification devices
default: []
selector: { device: { filter: [{ integration: mobile_app }] } }
notify_on_start:
name: Start Notification
default: false
selector: { boolean: {} }
notify_on_stop:
name: End Notification
default: false
selector: { boolean: {} }
msg_start:
name: Start-Message
default: "Irrigation started."
selector: { text: {} }
msg_stop:
name: End-Message
default: "Bewässerung beendet."
selector: { text: {} }
variables:
valves: !input valve_entities
v_mode: !input valve_mode
lock_ent: !input water_source_lock
pump_ent: !input pump_entity
moisture_ent: !input moisture_sensor
max_m: !input max_moisture
min_m: !input min_moisture
max_d: !input max_duration
forecast_ent: !input rain_forecast_sensor
forecast_thresh: !input rain_threshold
live_rain_ent: !input live_rain_sensor
live_threshold: !input live_rain_threshold
zone: !input zone_name
notif_device: !input notification_device
msg_s: !input msg_start
msg_e: !input msg_stop
start_mode: !input start_mode
delay_seconds: !input start_delay
trigger:
- platform: time
at: !input fixed_time
id: "time_trigger"
- platform: sun
event: sunrise
offset: !input sun_offset
id: "sunrise_trigger"
- platform: sun
event: sunset
offset: !input sun_offset
id: "sunset_trigger"
condition:
- condition: state
entity_id: !input irrigation_switch
state: "on"
- condition: template
value_template: >
{% if start_mode == 'time' and trigger.id == 'time_trigger' %} true
{% elif start_mode == 'sunrise' and trigger.id == 'sunrise_trigger' %} true
{% elif start_mode == 'sunset' and trigger.id == 'sunset_trigger' %} true
{% else %} false
{% endif %}
- condition: template
value_template: "{{ states(moisture_ent) | float < min_m | float }}"
action:
- delay: { seconds: "{{ delay_seconds }}" }
- wait_template: "{{ is_state(lock_ent, 'off') }}"
# original value 06:00:00
timeout: "00:15:00"
- service: input_boolean.turn_on
target: { entity_id: !input water_source_lock }
# Start-Meldung
- if:
- condition: template
value_template: "{{ notify_on_start and notif_device != [] }}"
then:
- domain: mobile_app
type: notify
device_id: !input notification_device
title: "{{ zone }}"
message: "{{ msg_s }} (Feuchte: {{ states(moisture_ent) }}%)"
# IRRIGATION STARTS (If Forecast OK)
- if:
- condition: template
value_template: >
{% set forecast_val = states(forecast_ent) | float(0) if forecast_ent != [] else 0 %}
{{ (forecast_ent == [] or forecast_val < forecast_thresh | float) }}
then:
- choose:
# --- MODE: PARALLEL ---
- conditions: "{{ v_mode == 'parallel' }}"
sequence:
- service: homeassistant.turn_on
target: { entity_id: "{{ valves }}" }
- if:
- condition: template
value_template: "{{ pump_ent != [] }}"
then:
- delay: "00:00:03"
- service: homeassistant.turn_on
target: { entity_id: !input pump_entity }
- wait_for_trigger:
- platform: template
value_template: "{{ states(moisture_ent) | float >= max_m | float }}"
id: "moisture_reached"
- platform: template
value_template: "{{ live_rain_ent != [] and states(live_rain_ent) | float(0) >= live_threshold | float }}"
id: "rain_veto"
timeout: { minutes: "{{ max_d }}" }
- if:
- condition: template
value_template: "{{ pump_ent != [] }}"
then:
- service: homeassistant.turn_off
target: { entity_id: !input pump_entity }
- delay: "00:00:02"
- service: homeassistant.turn_off
target: { entity_id: "{{ valves }}" }
- if:
- condition: template
value_template: "{{ wait.trigger != none and wait.trigger.id == 'rain_veto' }}"
then: { stop: "Live-Regen Veto" }
# --- MODE: SEQUENTIAL ---
- conditions: "{{ v_mode == 'sequential' }}"
sequence:
- repeat:
for_each: "{{ valves }}"
sequence:
- service: homeassistant.turn_on
target: { entity_id: "{{ repeat.item }}" }
- if:
- condition: template
value_template: "{{ pump_ent != [] }}"
then:
- delay: "00:00:03"
- service: homeassistant.turn_on
target: { entity_id: !input pump_entity }
- wait_for_trigger:
- platform: template
value_template: "{{ states(moisture_ent) | float >= max_m | float }}"
id: "moisture_reached"
- platform: template
value_template: "{{ live_rain_ent != [] and states(live_rain_ent) | float(0) >= live_threshold | float }}"
id: "rain_veto"
timeout: { minutes: "{{ max_d }}" }
- if:
- condition: template
value_template: "{{ pump_ent != [] }}"
then:
- service: homeassistant.turn_off
target: { entity_id: !input pump_entity }
- service: homeassistant.turn_off
target: { entity_id: "{{ repeat.item }}" }
- if:
- condition: template
value_template: "{{ wait.trigger != none and wait.trigger.id == 'rain_veto' }}"
then: { stop: "Live-Regen Veto" }
# FINISH
- service: input_boolean.turn_off
target: { entity_id: !input water_source_lock }
# Ende-Meldung
- if:
- condition: template
value_template: "{{ notify_on_stop and notif_device != [] }}"
then:
- domain: mobile_app
type: notify
device_id: !input notification_device
title: "{{ zone }}"
message: "{{ msg_e }} (Feuchte: {{ states(moisture_ent) }}%)"
Thx for this Blueprint TheFreaker86. It works perfect.