Garden Irrigation

Hi folks,

Well this looks like a go ahead. I’ve just about completed a prototype garage multi device (temp, humidity, lux, 5v relay for garage door toggling, 2 x reed sensors to detect the open/close/ajar states) and to be honest it went better+easier than I expected. It’s all done with comms over wifi and using MQTT for commands.

The hardware for the garden irrigation will be even simpler than this. The activation side of the code will also be fairly simple. It’s the decision based code I think that might get complex…

But I’m encouraged now - I know I can get it done! Stay tuned!

Any update to this?
Did you succeed?

Hi brendanheyu,

How are you getting on?

I’m very interested as I’m planning on undertaking a similar project this year. I too have been debating whether to go down the OpenSprinkler project route and have the smarts in the controller vs having the smarts in Home Assistant and/or Node-Red and using MQTT go communicate with a relatively dumb controller.

I’m leaning slightly towards the OpenSprinkler project route to benefit from the knowledge and experimentation of those that have been playing with the scheduling logic for far longer than I. However, I reserve the right to change my mind - particularly depending on how your investigations go.




Hi Folks,

Well - I’ve racked up some experience on a few things and do feel a lot more comfortable with HASS, Arduino and MQTT. I can’t see any blockers at this stage that don’t begin with a dollar sign.

I have an 8 channel relay board that have hooked to an ESP8266:

  1. Each channel is connected in a “normally open” state - so that on a power off state at the controller all relays will be off - it won’t irrigate if the power fails
  2. The ESP boots, connects to wifi and subscribes to an ‘irrigation’ topic on the MQTT server
  3. The message sent to the topic has the region name of the garden area to irrigate and the total time to irrigate (in minutes). The irrigate time/length means the ESP will count down and switch off of it’s own accord in the event that the ESP can’t communicate with MQTT for an “stop” type message
  4. Upon a successful irrigation the ESP sends a “success” with a “total time watered” back to MQTT
  5. Will halt all on a “stop” message via MQTT

The hard bit is now learning the automation part and being able to express it in YAML:

  1. It needs to have a tab with a group of garden region irrigation states/override buttons
  2. It needs to automate scheduled watering (no UI for this, just scripts)
  3. It needs to irrigate based on triggers (weather is over 38c, bushfire alert within home zone)
  4. Needs to show the success/fail state of irrigation attempts

But that’s it. It needs a nice water tight project case, and I could put in a impulse based flow meter at the tap end of the irrigation. It would give me:

  1. Alerts of water flow outside of a trigger, schedule or manual switching (leak alert)
  2. Litres used total[today|this month|etc] / litres used per zone
  3. Litres based irrigation*

This last* one would combine with my pool water height sensor. When the “pool level too low” state trips, I could ‘dose’ the pool with a couple of hundred litres to top up.

WAIT A MINUTE - lol. I just reread my opening thread. I basically repeated myself. I will leave this here as vindication of my current thought process!

I also have my garage door hooked up via a 5v relay and a reed switch to detect state, controlled via MQTT. I have connected my three aircon units via ESP with infrared LEDs, with an additional RF output to control some power outlets - you guessed it, all via MQTT. I have also started integrating the TTS abilities. All in all, HASS is just bloody amazing. Everything works flawlessly.


1 Like

Do you have your ESP8266 code you would be willing to share? I’m wanting to accomplish something similar to what you are doing.

Hi Guys,

I’d thought I’d add my two penneth worth.

Initially I had considered going the OpenSprinkler route, but at the end I decided to save the money or effort and go my tried and tested route. So what I’ve used:

  • 1 x Wemos D1 Mini - to drive relays and sensors
  • 1 x Wemos D1 Mini + OLED to show zones states. This one is yet to be implemented, but I’m nearly there. The way I have set it up means that it’s an independent piece that plugs in my PCB once it is ready. It has no effect on the main function.
  • 4 x Wemos relay shields
  • 5 x momentary push buttons. Four of which are a manual override for the watering of my four zones. The last is a “all zones off” soft kill switch. If things were going pear-shaped there is a 240V mains switch as well.
  • 4 x LEDs to show state of play on my 4 zones. I decided for this addition, as my OLED display code was slow coming and in my opinion is is quicker and more obvious to see the state on LEDs than on a small little 1" display.
  • 1 x 240V - 24VAC transformer
  • 1 x 240V - 5VDC transformer
  • 4 x Hunter 24VAC solenoids (PGV-101G and PGV-101JT - G)
  • a few other bits like PCB development boards and connectors.
  • and … hass, obviously.

The main wemos (ESP8266 board) control board is running the brilliant arendst/TASMOTA firmware and communicates with the Home Assistant via MQTT.

The firmware sports options for driving relays, as well as switches that are internally coupled with the relay controls. This means that you can equip your design with hardware over-ride buttons, eliminating the sole dependency on HA to be the ring master. In my designs I always like to introduce manual redundancy control mechanisms, just in case the WiFi is down, the Home Assistant goes down or is experiencing issues, etc.

The only stumbling block was a flexible enough system for automating the sprinklers. I had considered using a 3rd party solution, such as OpenSpinkler or custom development app Blynk. After much deliberation I scrapped those plans and instead decided to keep all control to HA. That means there is one app to control everything, it minimises and communication issues between systems and reduces complexity for users, aka my wife.

Creating a scheduling system is not HA’s strength though, certainly not on par with OpenSprinkler. But it is possible to have something pretty near good.

I have built upon the solution detailed in this community forum “Creating a[sic] alarm clock”. Basically, hardcoding four Zones with control i.e. enhanced “an alarm clock” for each of them. Currently I have UI elements allowing the user to set time and duration of watering upon the condition there is no rain predicted (WUnderground). This is executed everyday according to the schedule. I will further enhance the logic with a slider dictating repeating pattern from hours to days. Whilst not perfect this should cover most automatic situations. If there is any other situation when the user wants the sprinklers to come on there is the HA manual control via the standard interface, manual buttons on the control box and voice activation via Google Home + IFTTT.

If there is any interest I can show the code and hardware solution.

Now off to plant some veggies! :tomato::hot_pepper::smile:


I would be interested to see the hardware solution. I have a greenhouse and looking for inspiration on how to improve.

@phdelodder have a look at this complete project (of raised garden). Electronics at the bottom of the pictures.


Nice job!

Where did you buy the valves?

An irrigation supply shop. (NZ based). But Amazon does them too. About NZ$35/piece, which is a steal.

They are the non-latching type. Again, if things go sour, they’ll close when power is cut, thus not flooding the garden.

Being 24VAC, it’s a bit of a pain. The OpenSprinkler system/board can control them from 5VDC due to some clever electronics design. In my case, I just used a step-down transformer.

1 Like

I think I’m gonna go even a bit smaller scale, there are similiar way smaller normally closed valves selling on ebay for 3usd. Also dunno if I should go with a dedicated software -

In any case I’d be interested in all your code :slight_smile: and yaml for this stuff :). Very nice! So you think that Sonoff 4CH Pro, would be a nice controller once Tasmota fw supports it :slight_smile: ?

I have finally got everything in hass to work as desired. Configuring the automation was “baptism by fire”, due to some undocumented quirks… Let’s say don’t use now() function as a trigger in automation… more on it in “Having Trouble with Template Trigger”.

For now as a teaser, I’ post a couple of pics from my “Garden Irrigation Dashboard” and when I get chance, I’ll post the code too. Hopefully, tonight.

All .yaml files. Names denoted at the top of each section.

- platform: template
        value_template: '{{ "{:02d}".format(states.input_slider.timer_hours_1.state|int) }}:{{ "{:02d}".format(states.input_slider.timer_minutes_1.state|int) }}'
        friendly_name: "Time"
        friendly_name: "Last Run"
        value_template: '{{ (as_timestamp(states.switch.zone_1.last_changed)) |   timestamp_custom("%A, %d %h %H:%M") }}'
        friendly_name: "Next Run"
        value_template: '{{states.sensor.zone_1_timer_reset_sensor.state}}'

        friendly_name: "Zone 1 Timedelta"
        value_template: '{{states.input_slider.repeat_1.state|int * 3600}}'
        value_template: '{{states.input_slider.duration_1.state | int}}mins'
        friendly_name: "Duration"
        value_template: '{{ "{:02d}".format(states.input_slider.repeat_1.state|int)}}hrs'
        friendly_name: "Repeat in"
        friendly_name: "Rainfall Threshold Sensitivity"
        value_template: >-
          {% if states.sensor.pws_precip_1d.state <= states.input_slider.pws_precip_1d_sensitivity.state and states.sensor.pws_precip_today_metric.state <= states.input_slider.pws_precip_today_metric_sensitivity.state %}
          {% else %}
            too wet
          {% endif %}

switch mqtt:
  - platform: mqtt
    name: "Zone 1"
    state_topic: "stat/irrigation/POWER1"
    command_topic: "cmnd/irrigation/POWER1"
    payload_on: "ON"
    payload_off: "OFF"
    qos: 0
    retain: true

binary_sensor mqtt:
  - platform: mqtt
    name: "ZONE 1"
    device_class: moisture
    state_topic: "cmnd/irrigation/POWER1"
    payload_on: "ON"

sensor mqtt:
  - platform: mqtt
    name: "Zone 1 Timer Reset Sensor"
    state_topic: "cmnd/zone_1_control/TIMER"

    name: Reset Next Run Timer
    initial: off
    icon: mdi:lock-reset

    name: "Minutes"
    initial: 0
    min: 0
    max: 55
    step: 1
    icon: mdi:timer
    name: "Hour"
    initial: 6
    min: 0
    max: 23
    step: 1
    icon: mdi:timer
    name: "Set Duration"
    initial: 3
    min: 0
    max: 15
    step: 1
    icon: mdi:camera-timer
    name: "Set Repeat"
    initial: 24
    min: 0
    max: 48
    icon: mdi:repeat
    name: "Rainfall mm Sensitivity"
    initial: 0.1
    min: 0
    max: 2
    step: 0.1
    icon: mdi:contrast
    name: "Rainfall Probability Sensitivity"
    initial: 40
    min: 0
    max: 100
    step: 10
    icon: mdi:contrast

  view: yes
  control: hidden
  name: "Garden"
   - group.solenoids
   - group.irrigation_timer_1
   - group.rain_sensor
   - sensor.pws_precip_today_metric
   - sensor.pws_precip_1d
   - binary_sensor.zone_1

  view: no
  name: "Back Garden Irrigation"
  icon: 'mdi:flower'
    - switch.zone_1

  view: no
  name: "Rainfall Sensitivity"
  icon: mdi:contrast
    - sensor.rain_sensor
    - input_slider.pws_precip_today_metric_sensitivity
    - input_slider.pws_precip_1d_sensitivity

  view: no
  name: "Sprinklers Zone 1"
  icon: mdi:clock
    - sensor.last_run_zone_1
    - sensor.next_run_zone_1
    - sensor.duration_1
    - sensor.repeat_1
    - group.setting_zone_1
    - automation.activate_zone_1_timer

  view: no
  control: hidden
  name: "Settings"
  icon: mdi:settings
    - sensor.zone_1_timer
    - input_slider.timer_hours_1
    - input_slider.timer_minutes_1
    - input_slider.duration_1
    - input_slider.repeat_1
    - input_boolean.reset_zone_1

- id: "Activate_Zone_1_Timer"
  alias: "Activate Zone 1 Timer"
    - platform: time
      minutes: '/1'
    condition: and
    - condition: template
      value_template: '{{(as_timestamp(now()) | timestamp_custom("%A, %d %h %H:%M"))  == states.sensor.next_run_zone_1.state}}'
    - condition: state
      entity_id: sensor.rain_sensor
      state: 'dry'
    - service: script.turn_on
      entity_id: script.activate_irrigation_zone_1

- id: "Zone_1_ON_Notification"
  alias: "Zone 1 Active Notification"
  hide_entity: False
    - platform: state
      entity_id: switch.zone_1
      from: 'off'
      to: 'on'
    - service: notify.pushbullet
        title: "Irrigation Zone 1"
        message: "Watering has started"
- id: "Zone_1_OFF_Notification"
  alias: "Zone 1 Completed Notification"
  hide_entity: False
    - platform: state
      entity_id: switch.zone_1
      from: 'on'
      to: 'off'
    - service: notify.pushbullet
        title: "Irrigation Zone 1"
        message: "Watering has completed"

- id: "Zone_1_Timer_Reset"
  alias: "Zone 1 Timer Reset"
    - platform: state
      entity_id: input_boolean.reset_zone_1
      from: 'off'
      to: 'on'
    - service: mqtt.publish
        topic: "cmnd/zone_1_control/TIMER"
        retain: 1
        payload_template: >-
          {%if now().strftime("%H:%M") > states.sensor.zone_1_timer.state %}
            {{(as_timestamp(now() )+24*3600 ) | timestamp_custom("%A, %d %h ")}}{{states.sensor.zone_1_timer.state}}
            {{(as_timestamp(now() ) ) | timestamp_custom("%A, %d %h ")}}{{states.sensor.zone_1_timer.state}}
    - delay:
        seconds: 1
    - service: input_boolean.turn_off
        entity_id: input_boolean.reset_zone_1
- id: "Extend_Zone_1_Timer_When_Wet"
  alias: "Extend Zone 1 Timer When Wet"
    - platform: time
      minutes: '/1'
    condition: and
    - condition: template
      value_template: '{{(as_timestamp(now()) | timestamp_custom("%A, %d %h %H:%M"))  == states.sensor.next_run_zone_1.state}}'
    - condition: state
      entity_id: sensor.rain_sensor
      state: 'too wet'
    - service: mqtt.publish
        topic: "cmnd/zone_1_control/TIMER"
        retain: 1
        payload_template: '{{(as_timestamp(now() )+ states.sensor.time_delta.state | int) |   timestamp_custom("%A, %d %h %H:%M") }}'

  alias: "Activate Irrigation Zone 1"
    - alias: "Switch on Zone 1"
      service: switch.turn_on
      entity_id: switch.zone_1
    - delay: '00:{{ states.input_slider.duration_1.state | int }}:00'
    - alias: "Switch off Zone 1"
      service: switch.turn_off
      entity_id: switch.zone_1
    - alias: "Update Next Run Time"
      service: mqtt.publish
        topic: "cmnd/zone_1_control/TIMER"
        retain: 1
        payload_template: '{{ (as_timestamp(states.switch.zone_1.last_changed)+ states.sensor.time_delta.state | int) |   timestamp_custom("%A, %d %h %H:%M") }}'

All settings are shown for a single Zone. In pictures you can see multiple zones… just copy all settings, like there’s no tomorrow :smiley:


@marksev1 there was something about those smaller valves that my irrigation shop told me that made me pass on them… if I could just remember…hmmm At any rate the obvious considerations are water pressure, driving voltage, size, connection to your pipes…etc.

That Sonoff product looks very nice. Had I found that earlier, I’d probably not had bothered with my project :joy:

I’ve just noticed that TASMOTA now supports it!

Very nice set up. So you have a “rain sensor”? What about integration with an online meteo-api? That it would also take that into account?

It’s a pretend rain sensor… I’m using a local WU station… about 2km as the crow flies. So far it’s been fairly spot on.

Petr why is it turning the system on and off so much times during the day, based on the red lines in the history thing? Wouldnt that fatigue the system, shouldn’t the grass need irrigation less times a day.

That’s just me testing the automation rules, as I pointed out, there is a quirk that took me a while to crack.

Also, that history is not really the irrigation switching on/off, but me pressing the “Reset Next Run Timer” button. This also shows a bit of a limitation of HA and an unusual phenomenon, I’ll call “ghosting”. Which ever element is listed last in the group, will be reflected at the top of this modal window. Including the state of the element. So if it’s a switch, as in my case, it keeps showing on/off state. In the upper screen in the view “Sprinklers Zone 1” > Settings, you can also see the state of the switch. It would be nice to be able to specify your own text, but I can live with that.

Ideally, the whole sprinkler Zone should be an “installable” component. The whole premise is fairly simple, flexible and universal, provided your controller supports MQTT.

I might order myself the Sonoff 4CH PRO, just for fun and once it’s flashed with TASMOTA it should work without any further tweaks. Thinking about it, it’s pretty much exactly the same thing I built. :smiley: Hand on my heart, I had not known about the Sonoff 4CH PRO.

Hi. Just FYI - latest model of Sonoff might have some “improvements” that require additional steps when flashing. I’ve just received Sonoff Dual. It has one more microchip onboard. That’s why regular procedure does not work. Possible solution explained in this video Keep it in mind when taking final decision.

can you tell me which provider use for weather or what to change to make work with weatherundergroud.


Using the hard work of @petr I have managed a zone irrigation system. I made a few small changes:

  • Include a boolean to disable/enable the rain sensor
  • Save the next run in a different format
  • Small changes

The configuration can be found here