Companion to the harizanov.com post on garden irrigation. Anonymized: replace the Zigbee2MQTT device names and the helper names with yours.
The obvious way to run a valve for N minutes is switch.turn_on → delay → switch.turn_off.
It works until Home Assistant restarts, or you reload scripts/automations from the UI, in the
middle of a run. The delay dies with the script and the valve stays open. With six zones and a
03:00 start you find out in the morning.
The SONOFF SWV has its own timer. Zigbee2MQTT exposes it as cyclic_timed_irrigation; send one
command and the valve opens, counts the seconds, and closes itself. Home Assistant never has
to send "off". If HA is dead ten seconds after the command, the zone still closes on time.
Publish to zigbee2mqtt/<friendly name>/set:
{
"cyclic_timed_irrigation": {
"current_count": 0,
"total_number": 1,
"irrigation_duration": 1200,
"irrigation_interval": 0
}
}total_number: 1= run once. Higher values cycle (irrigation_intervalseconds of pause between runs) — useful for pulsing a drip line, not needed for sprinklers.irrigation_durationis seconds (0–86400).current_countmust be present and 0; it is the valve's own progress counter.- All four keys are required in the same message. Sending only
irrigation_durationdoes nothing. - To stop early,
switch.turn_offthe valve's switch entity. That cancels the running cycle. - The valve reports
cyclic_timed_irrigation,irrigation_start_time/irrigation_end_time,real_time_irrigation_durationanddaily_irrigation_volume(litres, device-side counter that resets when the run ends) back over MQTT, so you can verify a run without trusting HA's own timer.
auto_close_when_water_shortageis ENABLED from the factory. Fine on a zone valve. Fatal on a master valve that sits ahead of closed zone valves: it sees zero flow, decides there is a water shortage, and closes itself about 30 minutes after opening. Disable it on the master. A factory reset or re-pair turns it back on.- Set
retain: truefor the master valve in Zigbee2MQTT (device options). Without it the switch isunknownafter every HA restart and a gate likestate: 'on'silently skips the run. - Do not gate on
state: 'on'at all. A dead battery makes the entityunavailable, which also fails that condition, and the 03:00 run is skipped for as long as you do not notice. Gate on "not confirmed closed" instead (condition: not+state: 'off'), see the automation. - Zones run one at a time, so each gets full pressure. The automation's
delayafter each zone is only there to space the zones out; it is not what closes the valve. If the delay dies, the next zone simply starts late (or not at all), the open zone still closes itself. - Use
mode: singleon the sequence automation so a second trigger cannot interleave zones, and keep the scriptmode: parallelso a manual tap on the dashboard works while the sequence runs.
helpers.yaml— the helpers (put it inpackages/, or create them in the UI).scripts.yaml—swv_irrigation(the one that matters) andswv_irrigate_or_stop(dashboard tap: start or cancel).automations.yaml— the nightly sequence for two zones; copy the block per zone.
Tested with Zigbee2MQTT 2.14 and Home Assistant 2026.9, SONOFF SWV-BSP.