My Garden Irrigation

Because the file “view_garden_v2.yaml” must be in the /config directory. And also the two directory “includes” and “includes_garden” must be in te /config directory.

Hi @klogg, i have see now that you have upload the version2 with some correction. I have rewrite the garden_irrigation.yaml file for receive notifications in telegram.

This is my code:


#===================
#=== Input Booleans
#===================
input_boolean:
  irrigation_notify_user1:
    name: Notify Edoardo of events
    icon: mdi:message-text-outline

  irrigation_notify_user2:
    name: Notify Sabrina of events
    icon: mdi:message-text-outline

#================
#=== Automations
#================
automation:

  #===================================================
  #=== Notify about irrigation events
  #===================================================
  - alias: Irrigation Notify About Irrigation Events User1
    trigger:
      - platform: state
        entity_id:
        - input_boolean.irrigation_cycle1_running
        - input_boolean.irrigation_cycle2_running

    condition:
      - condition: state
        entity_id: input_boolean.irrigation_notify_user1
        state: 'on'        

    action:
      - service: telegram_bot.send_message
        data_template:
          target: !secret chat_id_edoardo
          title: '*IRRIGATION SYSTEM*'
          message: >
            {% if trigger.entity_id == 'input_boolean.irrigation_cycle1_running' %}
              {% set cycle = 'cycle1' %}
            {% else %}
              {% set cycle = 'cycle2' %}
            {% endif %}

            {% set cycle_name = states('input_text.irrigation_' ~ cycle ~ '_name') %}

            {% if trigger.to_state.state == 'on' %}
              {% set ns = namespace(total_time = 0) %}
              {% for zone in states.input_number if zone.entity_id.startswith('input_number.irrigation_' ~ cycle ~ '_zone') and
                                                    zone.entity_id.endswith('_duration') %}
                {% if is_state('input_boolean.irrigation_' ~ cycle ~ '_zone' ~ loop.index ~ '_skip', 'off') %}
                    {# Adjust for rainfall #}
                    {% if is_state('input_boolean.irrigation_' ~ cycle ~ '_adjust_for_rainfall', 'on') %}
                      {% set ns.total_time = ns.total_time * states('input_number.irrigation_rainfall_multiplier') | float %}
                    {% elif is_state('input_boolean.irrigation_' ~ cycle ~ '_adjust_for_temperature', 'on') %}
                      {% set ns.total_time = ns.total_time * states('input_number.irrigation_temp_multiplier') | float %}
                    {% else %}
                      {% set ns.total_time = ns.total_time + states(zone.entity_id) | float %}
                    {% endif %}
                {% endif %} 
              {% endfor %}
              
              I thought you'd like to know that the {{ cycle_name }} cycle has just started.


            The total watering time should be about {{ (ns.total_time * 60) | timestamp_custom('%H:%M', false) }} but I'll let you know when it has finished.
            {% else %}
              All the {{ cycle_name }} cycle watering is done.
            {% endif %}
  
  #===================================================
  #=== Notify about irrigation events
  #===================================================
  - alias: Irrigation Notify About Irrigation Events User2
    trigger:
      - platform: state
        entity_id:
        - input_boolean.irrigation_cycle1_running
        - input_boolean.irrigation_cycle2_running

    condition:
      - condition: state
        entity_id: input_boolean.irrigation_notify_user2
        state: 'on'         

    action:
      - service: telegram_bot.send_message
        data_template:
          target: !secret chat_id_sabrina
          title: '*IRRIGATION SYSTEM*'
          message: >
            {% if trigger.entity_id == 'input_boolean.irrigation_cycle1_running' %}
              {% set cycle = 'cycle1' %}
            {% else %}
              {% set cycle = 'cycle2' %}
            {% endif %}

            {% set cycle_name = states('input_text.irrigation_' ~ cycle ~ '_name') %}

            {% if trigger.to_state.state == 'on' %}
              {% set ns = namespace(total_time = 0) %}
              {% for zone in states.input_number if zone.entity_id.startswith('input_number.irrigation_' ~ cycle ~ '_zone') and
                                                    zone.entity_id.endswith('_duration') %}
                {% if is_state('input_boolean.irrigation_' ~ cycle ~ '_zone' ~ loop.index ~ '_skip', 'off') %}
                    {# Adjust for rainfall #}
                    {% if is_state('input_boolean.irrigation_' ~ cycle ~ '_adjust_for_rainfall', 'on') %}
                      {% set ns.total_time = ns.total_time * states('input_number.irrigation_rainfall_multiplier') | float %}
                    {% elif is_state('input_boolean.irrigation_' ~ cycle ~ '_adjust_for_temperature', 'on') %}
                      {% set ns.total_time = ns.total_time * states('input_number.irrigation_temp_multiplier') | float %}
                    {% else %}
                      {% set ns.total_time = ns.total_time + states(zone.entity_id) | float %}
                    {% endif %}
                {% endif %} 
              {% endfor %}
              
              I thought you'd like to know that the {{ cycle_name }} cycle has just started.


              The total watering time should be about {{ (ns.total_time * 60) | timestamp_custom('%H:%M', false) }} but I'll let you know when it has finished.
            {% else %}
              All the {{ cycle_name }} cycle watering is done.
            {% endif %}
          

I have also fixed many other small errors, including: cycle 3 could not be edited from the interface, the valves turned on but did not turn off (I rewrite the template), I added the pulsetime for each valve and I removed the master valve which I do not have, fixed some settings that were not seen.

I have yet to take a look at the new changes you’ve uploaded and the temperature and rainfall part because I don’t have smartweather sensors in my area.

This is being caused by the darksky sensor. I have changed the prerequisite description on GitHub to try and make it clearer. There is one line you need to change as your sensor will not have the same name as mine:

In the file item_schedule_cycle_header.yaml you must change from:

label: "[[[ return 'Weather Outlook: ' + states['sensor.dark_sky_current_minutely_summary'].state.replace(',', ',<br>'); ]]]"

to:

label: "[[[ return 'Weather Outlook: ' + states['sensor.dark_sky_minutely_summary'].state.replace(',', ',<br>'); ]]]"

Then your cycle headers should show and if you click on it you can rename them.

@http_edo13, Nice work with the notifications.

I think I have included all the bugs found so far in the new version. I have also removed the use of a Sonoff as I found a way to include the failsafe time directly on the ESP32 in ESPHome.

If you still want to use the temperature adjustments, that only needs DarkSky or some other source of temperature. To be honest since I came up with those algorithms in version 1 I have never actually used them much :blush:.

Actually, if I’m totally honest I pretty much only even use the schedules when I’m on holiday. My wife likes to press the Dash button to make it work :wink:

Hi klogg, I would like to implement this…would you mind sharing hardware information/configuration in ESPhome as that is likely the direction I would pursue.

(This all relates to Version 2 of course, Version 1 used a simple Sonoff 4ch flashed with Tasmota)


I will be implementing a hardware solution pretty much exactly as described by @sparkydave
here, and from here onwards but as of yet it is only the ESP32 and the relay board sitting on my desk. So I know the software driven ‘relay-on-and-off’ bit works, I just need to install the electrics on the other side of the relays to actually control the valves :slight_smile:

My ESPHome config is here. As always, suggestions for improvements are welcome:


#==================
#=== Uses ESP32-03
#==================

#==================
#=== Substitutions
#==================
substitutions:
  device_name: esphome_irrigation_controller
  friendly_name: ESPHome Irrigation Controller
#==================

# Board
esphome:
  name: ${device_name}
  platform: ESP32
  board: mhetesp32devkit

# WiFi
wifi:
  ssid: !secret not_wifi_ssid
  password: !secret not_wifi_password
  fast_connect: True
  ap:
    ssid: Irrigation Fallback Hotspot
    password: some.random.fallback.password!

# Fallback portal 
captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:

# Enable Over-The-Air updates
ota:

# # Enable Web server.
# web_server:
#   port: 80

    
#=== Sensors
sensor:
  #=== Uptime
  - platform: uptime
    name: ${friendly_name} Uptime

  #=== WiFi Signal
  - platform: wifi_signal
    name: ${friendly_name} WiFi Signal
    update_interval: 60s

  #=== Failsafe time
  - platform: homeassistant
    id: failsafe_time
    name: ${friendly_name} Failsafe Time
    entity_id: input_number.irrigation_failsafe_time_in_seconds


#=== Switches
switch:
  #=== Zone Relay 1
  - platform: gpio
    pin: 
      number: 21
      inverted: True
    name: Garden Irrigation Relay Zone1
    id: relay1
    restore_mode : ALWAYS_OFF
    interlock: &interlock_group [relay1, relay2, relay3, relay4, relay5, relay6, relay7, relay8]
    on_turn_on:
      - script.execute: failsafe
    on_turn_off:
      - script.stop: failsafe

  #=== Zone Relay 2
  - platform: gpio
    name: Garden Irrigation Relay Zone2
    id: relay2
    pin: 
      number: 22
      inverted: True
    restore_mode : ALWAYS_OFF
    interlock: *interlock_group
    on_turn_on:
      - script.execute: failsafe
    on_turn_off:
      - script.stop: failsafe
      
  #=== Zone Relay 3
  - platform: gpio
    name: Garden Irrigation Relay Zone3
    id: relay3
    pin: 
      number: 23
      inverted: True
    restore_mode : ALWAYS_OFF
    interlock: *interlock_group
    on_turn_on:
      - script.execute: failsafe
    on_turn_off:
      - script.stop: failsafe
      
  #=== Zone Relay 4
  - platform: gpio
    name: Garden Irrigation Relay Zone4
    id: relay4
    pin: 
      number: 14
      inverted: True
    restore_mode : ALWAYS_OFF
    interlock: *interlock_group
    on_turn_on:
      - script.execute: failsafe
    on_turn_off:
      - script.stop: failsafe

  #=== Zone Relay 5
  - platform: gpio
    name: Garden Irrigation Relay Zone5
    id: relay5
    pin: 
      number: 25
      inverted: True
    restore_mode : ALWAYS_OFF
    interlock: *interlock_group
    on_turn_on:
      - script.execute: failsafe
    on_turn_off:
      - script.stop: failsafe

  #=== Zone Relay 6
  - platform: gpio
    name: Garden Irrigation Relay Zone6
    id: relay6
    pin: 
      number: 26
      inverted: True
    restore_mode : ALWAYS_OFF
    interlock: *interlock_group
    on_turn_on:
      - script.execute: failsafe
    on_turn_off:
      - script.stop: failsafe

  #=== Zone Relay 7
  - platform: gpio
    name: Garden Irrigation Relay Zone7
    id: relay7
    pin: 
      number: 27
      inverted: True
    restore_mode : ALWAYS_OFF
    interlock: *interlock_group
    on_turn_on:
      - script.execute: failsafe
    on_turn_off:
      - script.stop: failsafe

  #=== Zone Relay 8
  - platform: gpio
    name: Garden Irrigation Relay Zone8
    id: relay8
    pin: 
      number: 18
      inverted: True
    restore_mode : ALWAYS_OFF
    interlock: *interlock_group
    on_turn_on:
      - script.execute: failsafe
    on_turn_off:
      - script.stop: failsafe

  #=== Reboot
  - platform: restart
    name: ${friendly_name} Reboot
    id: reboot


#=== Scripts
script:

  #=== Set failsafe time converted to milliseconds
  - id: failsafe
    then:
      - delay: !lambda |-
          return id(failsafe_time).state * 1000;
      - switch.turn_off: relay1
      - switch.turn_off: relay2
      - switch.turn_off: relay3
      - switch.turn_off: relay4
      - switch.turn_off: relay5
      - switch.turn_off: relay6
      - switch.turn_off: relay7
      - switch.turn_off: relay8

Awesome thank you :slight_smile:

@http_edo13 thanks, all of the config is currently in /config. It was the DarkSky sensor causing the issue

This has been a massive learning curve for me so far and i’m really grateful for the advise and help so far. Now trying to get the below sorted

Now trying to get the below sorted


Sensors to show detail Unless i need to wait a bit.
image

@klogg i’m using mqtt to control my 8 channel relay. Apologies for the stupid question. Can the below switch be changed to use mqtt instead to turn the zones on and off?

#=== Switches
switch:
  #=== Zone Relay 1
  - platform: gpio
    pin: 
      number: 21
      inverted: True
    name: Garden Irrigation Relay Zone1
    id: relay1
    restore_mode : ALWAYS_OFF
    interlock: &interlock_group [relay1, relay2, relay3, relay4, relay5, relay6, relay7, relay8]
    on_turn_on:
      - script.execute: failsafe
    on_turn_off:
      - script.stop: failsafe

if necessary I can share the code of the changes made, but I hope they have been resolved in the new commit of version 2

Regarding the temperature history, yes you need to wait for those figures to become populated over time.

The graph though should display but it has the same darksky sensor problem. I’ll update the readme but in the meantime you need to edit one line in section_settings_temperature.yaml

Line103:

- entity: sensor.dark_sky_forecast_daytime_high_temperature_0d

needs to be:

- entity: sensor.dark_sky_daytime_high_temperature_0d


I’m not really the person to ask this, I’m still finding my way a bit with ESP32 etc.

Maybe someone else can help?

Hello
I tried to install the package but I’m having problems.
with Lovelace, I get an error unknown tag !<!include>
if I insert:
views:

  • !include lovelace/view_garden_v2.yaml
    thanks for your great work

In the esphome config file you can enable MQTT control as well.
By default it uses HA’s own api between HA and ESP32.

my my_esp32.yaml includes:

# Enable Home Assistant API
api:

mqtt:
  broker: 192.168.100.xxx
  username: xxx
  password: xxx

see: https://esphome.io/components/mqtt.html?highlight=mqtt

So far for me irrigation works with esp32 + relays + a simple cron job that sends mqtt messages, to add more flexibility for the config I’m trying to configure this package.
Now I’m stuck at lovelace not displaying anything and trying to sort out this:
Secret smartweather_location_code_1 not defined

Do you have any pointers if I’m not able to use smartweather as no stations are around, nor darksy, what to use instead?

@klogg thanks for the updated readme file it helped a lot!

I think you may not have lovelace_gen installed.
Did you go through the prerequisites?

For rainfall I have no other suggestions I’m afraid. Getting rainfall data in a way that is useable is a real problem. In version 1 I attempt to use darksky but the method is not very reliable and relies on constantly updating the figures (I think I have it updating every 30 minutes).

For temperature, an alternative could be openweathermap. Since the Apple/Darksky announcemnet I think they have decided to try and capture some of the Darksky users. They have a new api too I think.

At some point I will probably change to openweathermap as I will lose access to darksky in 2021.

… I think no… Ok I read about it, thanks

line 37 of section_settings_rainfall.yaml error:

change from:

- !include
    - item_settings_line.yaml
      name: Number of days history to use
    - entity: input_number.irrigation_days_of_rainfall_history_used

to:

- !include
    - item_settings_line.yaml
    - name: Number of days history to use
      entity: input_number.irrigation_days_of_rainfall_history_used
1 Like

@klogg it seems this code return always UNKNOWN instead default values CYCLE 1 NAME, CYCLE 2 NAME, CYCLE 3 NAME:

name: “[[[ var entity_id = ‘input_text.irrigation_cycle1_name’; return states[entity_id].state.toUpperCase(); ]]]”

name: “[[[ var entity_id = ‘input_text.irrigation_cycle2_name’; return states[entity_id].state.toUpperCase(); ]]]”

name: “[[[ var entity_id = ‘input_text.irrigation_cycle3_name’; return states[entity_id].state.toUpperCase(); ]]]”

I’d like to do something like this:

- ../../includes/button_boolean_select.yaml
      - entity: input_boolean.irrigation_show_cycle3
        {% if states[input_text.irrigation_cycle3_name].state.toUpperCase() == "UNKNOWN" %}
        name: "MANUAL CYCLE"
        {% else %}
        name: "[[[ return states[input_text.irrigation_cycle3_name].state.toUpperCase(); ]]]"
        {% endif %}
        card_font_size: 16px
        card_font_family: Oswald

but I get error.

usefull for new installation

Yeah, that won’t work.
I think the only way to do it is in an automation.

I’ve updated the file garden_ui_control.yaml on github, hopefully that should work.

1 Like

It works perfectly! Very usefull for a new fresh installation!

1 Like

Hi @klogg, first I’ve to said your work is fantastic!
I’ve found your first garden system " Logic processing and other issues" and the the new one.
I have the same old Gardena 6 water distributor and I’m looking to have a single eletrovalve that open/close in order to use 4 or 5 water zone in our garden (under Her Majesty The Wife supervision).
Do you think it’s possible to use your latest HA-Irrigation-Version1 only with just one valve and 4 or 5 zones? Could you help me about the changes I need to do in your code?
Thanks a lot!