0% found this document useful (0 votes)
5 views30 pages

Auto DDD

Download as pdf or txt
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 30

Topics

More
DIY 8 station irrigation based
Categories on ESPhome on KC868-A8
Blog relay board
Configuration

Voice Assistant Contest mr.sneezy Sep '22

Blueprints Exchange Project status: Work in progress.


I wanted to replace a very unsmart 24V AC irrigation
Installation
timer system with something not too expensive and
All categories fully controllable by Home Assistant. I initially
considered buying OpenSprinkler, but it’s actually not
Tags very cheap when you convert $US to AU and add the
shipping. However, it’s would save a lot of work
automation
So when the KC868-A8 ESP32 relay module popped
templates onto AliExpress last year I thought that had great
potential as a DIY irrigation controller board, bought
mqtt
one to try out.
switch So far so good. I have it mounted in a smallish
electrical enclosure. It has a 24V AC to 12V DC
zwave
SMPS to supply regulated 12V DC to the KC868
All tags board. The 24V AC is wired to each relay to drive
solenoids.
I’ve added a big 16x2 LCD I had kicking around in
my parts box, and also four push buttons for future
use for saving the trouble of getting my phone out to
do basic stuff.

Update: The system just got commissioned


(24-10-2022), just in time for the Aussie summer.
Even when setting it up and then just checking the
zones for broken sprayers and pop-ups it became
obvious how much time is saves me I can control any
zone from my phone while anywhere in the garden…
8 Station Sprinkler Controller (NodeMCU Lua) …
Irrigation controller with EspHome
Irrigation controller with EspHome

mr.sneezy Sep '22

The initial code I’m testing currently. By no means


finished or complete but the basics are running.

# 8 Zone Version and compiled via ESPhome


substitutions:
devicename: irrigation-controller

esphome:
name: $devicename
# platformio_options:
# build_flags:
# - -DCONFIG_ARDUINO_LOOP_STACK_SIZE=16384
# includes:
# - irrigation.h

esp32:
board: nodemcu-32s
framework:
type: arduino

#esp32:
# board: nodemcu-32s
# variant: esp32
# framework:
# type: arduino
# version: 2.0.4
# source: https://github.com/espressif/arduino-esp32.g
# platform_version: https://github.com/platformio/plat

wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password

# Enable fallback hotspot (captive portal) in case wifi


ap:
ssid: "Esp32-Irrigation"
password: !secret ap_password

# Enable logging
logger:

# Enable Home Assistant API


api:
reboot_timeout: 0s

ota:

# I2C bus config


i2c:
sda: 4
scl: 5
scan: true
id: bus_a

# I2C I/O expander config


pcf8574:
- id: 'pcf8574_output_hub'
address: 0x24
pcf8575: false
- id: 'pcf8574_input_hub'
address: 0x22

# 16x2 LCD config


display:
- platform: lcd_pcf8574
dimensions: 16x2
address: 0x27
lambda: |-
// Print the zone switch status
it.printf(0, 0, "Zone1: %s", id(zone_valve_sw1).sta
it.printf(0, 1, "Remaining: %3.1d", id(esp32_sprink
// Print the current time
//it.strftime(0, 1,"Time %H:%M:%S", id(homeassistan
//it.printf(0, 1, "Duration: %3.1d", id(esp32_sprin

# Main sprinkler code


sprinkler:
- id: esp32_sprinkler_ctrlr
main_switch: "Master Run/Stop"
auto_advance_switch: "Zones Auto Advance"
reverse_switch: "Zones Reverse"
valve_overlap: 1s
valves:
- valve_switch: "Zone 1"
enable_switch: "Zone 1 Enable"
run_duration: 900s
valve_switch_id: zone_valve_sw1
valve_switch: "Zone 2"
- valve_switch: "Zone 2"
enable_switch: "Zone 2 Enable"
run_duration: 900s
valve_switch_id: zone_valve_sw2
- valve_switch: "Zone 3"
enable_switch: "Zone 3 Enable"
run_duration: 900s
valve_switch_id: zone_valve_sw3
- valve_switch: "Zone 4"
enable_switch: "Zone 4 Enable"
run_duration: 900s
valve_switch_id: zone_valve_sw4

ESP32 + Ethernet + 8 or 16 relays + voltage re…

mr.sneezy Sep '22

Initially I had tried to run code from the project here


but after expanding it out to the 8 zones I needed I
ran into trouble. It ran the ESPhome out of resources
(stack overflow issues) and also would not compile
with ESPhome running on my Home Assistant Rpi4. I
had to compile using ESPhome via Python on my
desktop Windows 10 machine each time I wanted to
work on the code. This was quite a discouragement
as it was awkward to use (and setup) so I was happy
when ESPhome added a native sprinkler component
now.
The top blocks of #commented out code above
reflects some of the things I had to add to get it to
compile because of the resource issues, and gives
context to why I have moved to the native sprinkler
component.

mr.sneezy Sep '22

Things missing currently are:


Code to use the buttons
Internal or external schedules (easy fix if using HA
frontend).
Code to display the actual running zones run time
and remaining time on the LCD

bremby Oct '22


@mr.sneezy , great job
can you share some details on schematic/wired
connection?

mr.sneezy Oct '22

Hi bremby.
I don’t have any schematic as I just build up as I go.
The connections are this:

The four buttons share one common ground, and


each button goes to an input on ‘IN5 - IN8’.

The 16x2 LCD has a I2C converter attached like


found on AliExpress or Ebay.
https://www.aliexpress.com/
item/32713904220.html?
It connects to the header designated ‘IIC’ but has
ground connected to the spare ground pin on header
‘P2’.

Board power comes from the 24V AC irrigation


transformer (black wires seen in the bottom of build
image), the transformer is also connected to each
relay by ‘daisy chained’ wire links as seen in the
image.
The 24V AC is converted to 12V DC for the KC868
board. To do that I used a small 2 Amp bridge
rectifier that in turn feeds a 36V DC to 12V DC
converter module (which sits at the top behind the
LCD). Both are soldered to small Vero board (AKA
perf board) strip to make it easy to mount to the box.
My DC-DC module is obsolete, but any module with
greater than 36V DC input and at least 12V DC
output at 2A or more will be fine…
The 12V DC output is wired direct to the KC868
+12V power input.

Output for the 8x irrigation valves is via the Normally


Open contact of each zone relay (not yet connected).
Each relay Common contact is connected to one side
of the 24V AC transformer via the row of tinned wire
links.
mr.sneezy Oct '22

This is my code currently below. I’ve added ability to


change the LCD display to follow the status of the
running zone. I don’t have any internal scheduling
yet, and I’m not sure I need too, maybe a default
program if HA is off-air and one button assigned to
start a manual watering.
Not sure yet if I should use HA automations for
scheduling or create of borrow something for Node-
Red…

# 8 Zone Version and compiled via ESPhome and Python3.10.


substitutions:
devicename: irrigation-controller

esphome:
name: $devicename

esp32:
board: nodemcu-32s
framework:
type: arduino

wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password

# Enable fallback hotspot (captive portal) in case wifi


ap:
ssid: "Esp32-Irrigation"
ssid: "Esp32-Irrigation"
# password: !secret ap_password

# Enable logging
logger:

# Enable Home Assistant API


api:
reboot_timeout: 0s
services:
- service: pause
then:
- sprinkler.pause: esp32_sprinkler_ctrlr
- service: resume
then:
- sprinkler.resume: esp32_sprinkler_ctrlr

ota:

# I2C bus config


i2c:
sda: 4
scl: 5
scan: true
id: bus_a

# I2C I/O expander config


pcf8574:
- id: 'pcf8574_output_hub'
address: 0x24
pcf8575: false
- id: 'pcf8574_input_hub'
address: 0x22

# 16x2 LCD config


display:
- platform: lcd_pcf8574
dimensions: 16x2
address: 0x27
update_interval: 2s
lambda: |-

switch (id(esp32_sprinkler_ctrlr).active_valve().

case 0: //valve0, zone1, internal


it.printf(0, 0, "Front Lawn: %s"
if (id(zone_valve_sw1).state) {
if (id(zone_valve_sw1).state) {
it.printf(0, 1, "Mins: %2d of", id(esp32_sprink
it.printf(12, 1, "%2d", id(esp32_sprinkler_ctrl
} else {
it.printf(0, 1, "Mins Set %2d "
}
break;

case 1: //valve1, zone2,


it.printf(0, 0, "Back Lawn: %s",
if (id(zone_valve_sw2).state) {
it.printf(0, 1, "Mins: %2d of", id(esp32_sprink
it.printf(12, 1, "%2d", id(esp32_sprinkler_ctrl
} else {
it.printf(0, 1, "Mins Set %2d "
}
break;

case 2: //valve2, zone3,


it.printf(0, 0, "Front middle: %s"
if (id(zone_valve_sw3).state) {
it.printf(0, 1, "Mins: %2d of", id(esp32_sprink
it.printf(12, 1, "%2d", id(esp32_sprinkler_ctrl
} else {
it.printf(0, 1, "Mins Set %2d "
}
break;

case 3: //valve3, zone4


it.printf(0, 0, "West Fence: %s"
if (id(zone_valve_sw4).state) {
it.printf(0, 1, "Mins: %2d of", id(esp32_sprink

bremby Oct '22

@mr.sneezy thank you so much,


I worked a little bit around you example and I stolen
also something from ESPHome Sprinkler YAML -
ESPHome - Home Assistant Community (home-
assistant.io)

sharing back where I’m now

ESP Code

# Enable logging
logger:
logger:

#########################################################
##### I/O expander hub definition
#########################################################
mcp23017:
- id: 'mcp23017_hub'
address: 0x20
#nodemcu devkit v4.0
i2c:
sda: 21
scl: 22
scan: True
#########################################################
#########################################################

#########################################################
# Enable Home Assistant APIs
api:
reboot_timeout: 0s
services:
- service: set_multiplier
variables:
multiplier: float
then:
- sprinkler.set_multiplier:
id: esp32_sprinkler_ctrlr
multiplier: !lambda 'return multiplier;'

- service: start_full_cycle
then:
- sprinkler.start_full_cycle: esp32_sprinkler_ctr

- service: start_single_valve
variables:
valve: int
then:
- sprinkler.start_single_valve:
id: esp32_sprinkler_ctrlr
valve_number: !lambda 'return valve;'

- service: next_valve
then:
- sprinkler.next_valve: esp32_sprinkler_ctrlr

- service: previous_valve
then:
then:
- sprinkler.previous_valve: esp32_sprinkler_ctrlr

- service: shutdown
then:
- sprinkler.shutdown: esp32_sprinkler_ctrlr

- service: pause
then:
- sprinkler.pause: esp32_sprinkler_ctrlr

- service: resume
then:
- sprinkler.resume: esp32_sprinkler_ctrlr

- service: resume_or_full_cycle
then:
- sprinkler.resume_or_start_full_cycle:

- service: repeat_2
then:
- sprinkler.set_repeat:
id: esp32_sprinkler_ctrlr
repeat: 2 # would run three cycles

- service: repeat_3
then:
- sprinkler.set_repeat:
id: esp32_sprinkler_ctrlr
repeat: 3 # would run three cycles

# Main sprinkler code


sprinkler:
- id: esp32_sprinkler_ctrlr
main_switch: "Master Run/Stop"
auto_advance_switch: "Zones Auto Advance"
reverse_switch: "Zones Reverse"
valve_open_delay: 2s
valves:
- valve_switch: "Zone 1"
enable_switch: "Zone 1 Enable"
run_duration: 900s
valve_switch_id: zone_valve_sw1
- valve_switch: "Zone 2"
enable_switch: "Zone 2 Enable"
run_duration: 900s
valve_switch_id: zone_valve_sw2
- valve_switch: "Zone 3"
enable_switch: "Zone 3 Enable"
LOVELACE
run_duration: 900s
valve_switch_id: zone_valve_sw3
- theme: Backend-selected
- valve_switch: "Zone 4"
title: Sprinkler
enable_switch: "Zone 4 Enable"
path: sprinkler
run_duration: 900s
type: panel
valve_switch_id: zone_valve_sw4
badges: []
- valve_switch: "Zone 5"
cards:
enable_switch: "Zone 5 Enable"
- type: vertical-stack
run_duration: 900s
cards:
valve_switch_id: zone_valve_sw5
- type: horizontal-stack
- valve_switch: "Zone 6"
cards:
enable_switch: "Zone 6 Enable"
- show_name: true
run_duration: 900s
show_icon: true
valve_switch_id: zone_valve_sw6
show_state: true
type: glance
# Valve control outputs config via I/O expander
entities:
switch:
- entity: sensor.sprinklers_status
#########################################################
- entity: sensor.zone_active_sensor
####### CONTROL SWITCH
- entity: sensor.zone_time_remaining_se
#########################################################
state_color: false
- platform: template
- type: entities
id: esp32_sprinkler_ctrlr_run
entities:
name: "Sprinkler Controller Run"
- entity: number.run_duration_multiplie
optimistic: true
- entity: number.sprinkler_repeat_cycle
on_turn_on:
- type: horizontal-stack
- text_sensor.template.publish:
cards:
id: esp32_sprinkler_ctrlr_status
- show_name: true
state: "Running"
show_icon: true
- sprinkler.resume_or_start_full_cycle:
type: button
- switch.turn_off: esp32_sprinkler_ctrlr_pause
entity: switch.zone_1
- switch.turn_off: esp32_sprinkler_ctrlr_stop
icon: mdi:sprinkler
show_state: false
- platform: template
hold_action:
id: esp32_sprinkler_ctrlr_stop
action: none
name: "Sprinkler Controller Stop"
- show_name: true
optimistic: true
show_icon: true
on_turn_on:
type: button
- text_sensor.template.publish:
entity: switch.zone_2
id: esp32_sprinkler_ctrlr_status
icon: mdi:sprinkler
state: "Stopped"
show_state: false
- sprinkler.shutdown: esp32_sprinkler_ctrlr
hold_action:
- switch.turn_off: esp32_sprinkler_ctrlr_pause
action: none
- switch.turn_off: esp32_sprinkler_ctrlr_run
switch.turn_off: esp32_sprinkler_ctrlr_run
- show_name: true
show_icon: true
- platform: template
type: button
id: esp32_sprinkler_ctrlr_pause
entity: switch.zone_3
name: "Sprinkler Controller Pause"
icon: mdi:sprinkler
optimistic: true
show_state: false
hold_action:
turn_on_action:
action: none
- delay: 500ms
- show_name: true
- lambda: |-
show_icon: true
if(id(esp32_sprinkler_ctrlr_status).state != "R
type: button
{
entity: switch.zone_4
id(esp32_sprinkler_ctrlr_pause).turn_off();
icon: mdi:sprinkler
}
show_state: false
- lambda: |-
hold_action:
if(id(esp32_sprinkler_ctrlr_status).state == "R
action: none
{
- show_name: true
id(esp32_sprinkler_ctrlr_status).publish_stat
show_icon: true
id(esp32_sprinkler_ctrlr).pause();
type: button
}
entity: switch.zone_5
icon: mdi:sprinkler
on_turn_off:
show_state: false
lambda: |-
hold_action:
if(id(esp32_sprinkler_ctrlr_status).state == "Pau
action: none
{
- show_name: true
id(esp32_sprinkler_ctrlr_status).publish_state(
show_icon: true
id(esp32_sprinkler_ctrlr).resume();
type: button
}
entity: switch.zone_6
icon: mdi:sprinkler
- platform: template
show_state: false
id: esp32_sprinkler_ctrlr_resume
hold_action:
name: "Sprinkler Controller Resume"
action: none
optimistic: true
- type: horizontal-stack
cards:
#########################################################
- show_name: false
####### I/0 SWITCH
show_icon: true
#########################################################
type: button
- platform: gpio
entity: switch.zone_1_enable
id: zone_valve_sw1
icon: mdi:toggle-switch-outline
name: "MCP23017 Pin B2"
show_state: false
pin:
hold_action:
mcp23xxx: mcp23017_hub
action: none
# Use pin B2
- show_name: false
number: 10
show_icon: true
# One of INPUT or OUTPUT
type: button
mode:
entity: switch.zone_2_enable
output: true
entity: switch.zone_2_enable
output: true
icon: mdi:toggle-switch-outline
inverted: true
show_state: false
internal: true
hold_action:
- platform: gpio
action: none
id: zone_valve_sw2
- show_name: false
name: "MCP23017 Pin B3"
show_icon: true
pin:
type: button
mcp23xxx: mcp23017_hub
entity: switch.zone_3_enable
# Use pin B3
icon: mdi:toggle-switch-outline
number: 11
AUTOMATION
show_state: false
# One of INPUT or OUTPUT
hold_action:
- id: mode:
'1665523175659'
action: none
alias:output: true
Sprinkler Controller
- show_name: false
inverted:
description: '' true
show_icon: true
internal: true
trigger:
type: button
- platform:
- platform: state
gpio
entity: switch.zone_4_enable
id: zone_valve_sw3
entity_id:
icon: mdi:toggle-switch-outline
name:
- "MCP23017 Pin B4"
switch.sprinkler_controller_stop
show_state: false
pin:
to: 'on'
hold_action:
mcp23xxx:
id: mcp23017_hub
SprinklerStop
action: none
# Use pin
- platform: B4
state
- show_name: false
number: 12
entity_id:
show_icon: true
- # One of INPUT or OUTPUT
switch.master_run_stop
type: button
mode:
from: 'on'
entity: switch.zone_5_enable
to: output:
'off' true
icon: mdi:toggle-switch-outline
inverted:
id: EndCycletrue
show_state: false
- internal:
platform: true
state
hold_action:
- platform:
entity_id:gpio
action: none
id: zone_valve_sw4
- switch.sprinkler_controller_resume
- show_name: false
name: "MCP23017 Pin B5"
to: 'on'
show_icon: true
pin:
id: SprinklerResume
type: button
mcp23xxx:
condition: [] mcp23017_hub
entity: switch.zone_6_enable
# Use pin B5
action:
icon: mdi:toggle-switch-outline
number: 13
- if:
show_state: false
# One of INPUT
- condition: or OUTPUT
trigger
hold_action:
mode:
id: SprinklerStop
action: none
then:output: true
- type: horizontal-stack
- inverted:
delay: true
cards:
internal:
hours:true
0
- show_name: false
- platform: gpio
minutes: 0
show_icon: false
id: zone_valve_sw5
seconds: 2
type: button
name: "MCP23017 Pin
milliseconds: 0 B6"
entity: number.zone_1_duration
pin:
- type: toggle
icon: ''
mcp23xxx:
device_id:mcp23017_hub
2a2143a5268d8661b4ce50e2807dcd62
show_state: true
# Use pin B6
entity_id: switch.sprinkler_controller_stop
hold_action:
number:
domain: 14
switch
action: none
action: none
# One of INPUT or OUTPUT
- if:
- show_name: false
mode:
- condition: and
show_icon: false
output: true
conditions:
type: button
inverted:
- condition:true
not
entity: number.zone_2_duration
internal: true
conditions:
icon: ''
- platform: gpio
- condition: state
show_state: true
id: zone_valve_sw6
entity_id: sensor.sprinklers_status
hold_action:
name: "MCP23017 Pin B7"
state: Paused
action: none
pin:
then:
- show_name: false
- mcp23xxx:
type: toggle mcp23017_hub
show_icon: false
# Use pin B7
device_id: 2a2143a5268d8661b4ce50e2807dcd62
type: button
number: 15
entity_id: switch.sprinkler_controller_stop
entity: number.zone_3_duration
# One ofswitch
domain: INPUT or OUTPUT
icon: ''
mode:
- if:
show_state: true
output: true
- condition: trigger
hold_action:
inverted: true
id: SprinklerResume
action: none
internal:
then: true
- show_name: false
- type: turn_off
show_icon: false
#- platform:
device_id: template #this switch doesn't work properl
2a2143a5268d8661b4ce50e2807dcd62
type: button
# id: pause_switch
entity_id: switch.sprinkler_controller_pause
entity: number.zone_4_duration
# name:
domain:"Pause Irrigation Switch"
switch
icon: ''
# -turn_on_action:
type: turn_off
show_state: true
# then:
device_id: 2a2143a5268d8661b4ce50e2807dcd62
hold_action:
# - sprinkler.pause: esp32_sprinkler_ctrlr
entity_id: switch.sprinkler_controller_resume
action: none
# turn_off_action:
domain: switch
- show_name: false
#
mode:then:
single
show_icon: false
# - sprinkler.resume: esp32_sprinkler_ctrlr
type: button

ESPHome Sprinkler YAML


bremby Oct '22

I have something to fix/understand:

1. when I disable a zone, if I use the Next or


Previous button the zone isn’t skipped. It works
if I toggle the switch. any idea where is my
error?
2. I would like to have to total amout cycle
remaing time and if i’m running more cycles
what is the actual cycle eg 2/3, 3/6, etc
3. can be possible to pass the zone value with
sprinkler.start_single_valve directly by
sprinkler.start_single_valve directly by
the UI with a drop down list menu? eg. press
the single button and then select which valve to
control
4. how to use/interact with the queue (add/
remove, see the queue list, etc)

I found a response for point 1

The next_valve, previous_valve and


start_single_valve actions ignore
whether a valve is enabled via its enable
switch.

mr.sneezy Oct '22

Not sure I can help with points 2, 3, 4 as your Yaml


skills are well above mine. Nice frontend cards by the
way
I found an issue with ‘resume’ myself but have not
tried to fault find it. I can Pause via GUI but Resume
does not work.
Yes it would be better if previous/next did check the
valve enable state. Perhaps this should be raised in
the ESPhome Sprinkler git issues.

For my build I probably won’t use any Repeat cycle


function, as I think the Multiplier is the way I’d change
a cycle.

bremby Oct '22

I’m experimenting a little bit with the “challenge” n#2

UI

- theme: Backend-selected
title: Sprinkler
path: sprinkler
type: panel
badges: []
badges: []
cards:
- type: vertical-stack
cards:
- type: horizontal-stack
cards:
- type: entities
entities:
- entity: sensor.sprinklers_status
icon: mdi:list-status
secondary_info: none
- entity: timer.sprinklercountdown
name: Sprinkler Countdown
secondary_info: none
- entity: sensor.zone_active_sensor
icon: mdi:map-marker-path
secondary_info: none
- entity: sensor.zone_time_remaining_se
icon: mdi:history
secondary_info: none
state_color: true
- type: entities
entities:
- entity: number.run_duration_multiplie
icon: mdi:chart-multiline
secondary_info: none
- entity: number.sprinkler_repeat_cycle
icon: mdi:repeat
secondary_info: none
state_color: true
- type: horizontal-stack
cards:
- show_name: true
show_icon: true
type: button
entity: switch.zone_1
icon: mdi:sprinkler
show_state: false
hold_action:
action: none
- show_name: true
show_icon: true
type: button
entity: switch.zone_2
icon: mdi:sprinkler
show_state: false
hold_action:
action: none
- show_name: true
show_icon: true
type: button
entity: switch.zone_3
icon: mdi:sprinkler
show_state: false
hold_action:
action: none
- show_name: true
show_icon: true
type: button
entity: switch.zone_4
icon: mdi:sprinkler
show_state: false
hold_action:
action: none
- show_name: true
show_icon: true
type: button
entity: switch.zone_5
icon: mdi:sprinkler
show_state: false
hold_action:
action: none
- show_name: true
show_icon: true
type: button
entity: switch.zone_6
icon: mdi:sprinkler
show_state: false
hold_action:
action: none
- type: horizontal-stack
cards:
- show_name: false
show_icon: true
type: button
entity: switch.zone_1_enable
icon: mdi:toggle-switch-outline
show_state: false
hold_action:
action: none
- show_name: false
show_icon: true
show_icon: true
AUTOMATION
type: button
entity: switch.zone_2_enable
- id: '1665523175659'
icon: mdi:toggle-switch-outline
alias: Sprinkler Controller
show_state: false
description: ''
hold_action:
trigger:
action: none
- platform: state
- show_name: false
entity_id:
show_icon: true
- switch.sprinkler_controller_stop
type: button
to: 'on'
entity: switch.zone_3_enable
id: SprinklerStop
icon: mdi:toggle-switch-outline
from: 'off'
show_state: false
- platform: state
hold_action:
entity_id:
action: none
- switch.master_run_stop
- show_name: false
from: 'on'
show_icon: true
to: 'off'
type: button
id: EndCycle
entity: switch.zone_4_enable
- platform: state
icon: mdi:toggle-switch-outline
entity_id:
show_state: false
- switch.sprinkler_controller_resume
hold_action:
to: 'on'
action: none
id: SprinklerResume
- show_name: false
- platform: state
show_icon: true
entity_id:
type: button
- switch.sprinkler_controller_run
entity: switch.zone_5_enable
to: 'on'
icon: mdi:toggle-switch-outline
id: Sprinkler Controller Start
show_state: false
from: 'off'
hold_action:
- platform: state
action: none
entity_id:
- show_name: false
- switch.sprinkler_controller_pause
show_icon: true
id: Sprinkler Controller Pause
type: button
from: 'off'
entity: switch.zone_6_enable
to: 'on'
icon: mdi:toggle-switch-outline
condition: []
show_state: false
action:
hold_action:
- choose:
action: none
- conditions:
- type: horizontal-stack
- condition: trigger
cards:
id: SprinklerStop
- show_name: false
sequence:
show_icon: false
- delay:
type: button
hours: 0
entity: number.zone_1_duration
minutes: 0
icon: ''
seconds: 2
show_state: true
show_state: true
milliseconds: 0
hold_action:
- type: toggle
action: none
device_id: 2a2143a5268d8661b4ce50e2807dcd62
- show_name: false
entity_id: switch.sprinkler_controller_stop
show_icon: false
domain: switch
type: button
- service: timer.finish
entity: number.zone_2_duration
data: {}
icon: ''
target:
show_state: true
entity_id: timer.sprinklercountdown
hold_action:
- conditions:
action: none
- condition: trigger
- show_name: false
id: EndCycle
show_icon: false
- condition: and
type: button
conditions:
entity: number.zone_3_duration
- condition: not
icon: ''
conditions:
show_state: true
- condition: state
hold_action:
entity_id: sensor.sprinklers_status
action: none
state: Paused
- show_name: false
sequence:
show_icon: false
- type: toggle
type: button
device_id: 2a2143a5268d8661b4ce50e2807dcd62
entity: number.zone_4_duration
entity_id: switch.sprinkler_controller_stop
icon: ''
domain: switch
show_state: true
- conditions:
hold_action:
- condition: trigger
action: none
id: SprinklerResume
- show_name: false
sequence:
show_icon: false
- type: turn_off
type: button
device_id: 2a2143a5268d8661b4ce50e2807dcd62
entity: number.zone_5_duration
entity_id: switch.sprinkler_controller_pause
icon: ''
domain: switch
show_state: true
- type: turn_off
hold_action:
device_id: 2a2143a5268d8661b4ce50e2807dcd62
action: none
entity_id: switch.sprinkler_controller_resume
- show_name: false
domain: switch
show_icon: false
- service: timer.start
type: button
data: {}
entity: number.zone_6_duration
target:
icon: ''
entity_id: timer.sprinklercountdown
show_state: true
- conditions:
hold_action:
- condition: trigger
action: none
id: Sprinkler Controller Start
- square: false
sequence:
columns: 3
- service: timer.start
type: grid
data:
data:
cards:
duration: '{{ ( (states(''number.zone_1_durati
- show_name: true
(states(''number.zone_3_duration'')|int*60)+
show_icon: true
(states(''number.zone_5_duration'')|int*60)+
type: button
) | timestamp_custom("%H:%M:%S", 0) }}
tap_action:
target:
action: call-service
entity_id: timer.sprinklercountdown
service: esphome.sprinkler_previous_val
mr.sneezy Oct '22

Cool. Nothing quite so interesting here. Installed the


four physical buttons on the box lid and configured
ESPhome to read them. Working fine. Now to do
something useful with them.
(also adding a power input fuse to the box from the
24V AC transformer)

bremby Oct '22

thank you @mr.sneezy , as you are some “steps”


ahead me… shall you share how you wired the
buttons and how configured the inputs?
I will try my best to get to the same page:D

mr.sneezy Oct '22

I added four buttons using normally open momentary


switches I had in my parts box. Kinconys diagram
shows how to wire them. I picked I2C I/O hub inputs
5-8 because they were close to the ground pin which
needs to be connected to one side of each button.
You could use 1-4 etc to be more logical.

Here is a closer image of the wiring as seen on the


circuit board showing the 5 wires to the I2C I/O hub
inputs.
Here’s a image of the back of the buttons in case it
helps, really nothing to see though.

I’ve added a small inline fuse and holder to the main


24V AC input, as the transformer has none. It’s to
protect the transformer if a valve cable in the garden
is damged (shorted).
Like the LCD mount and the button mount, it’s 3D
printed on my old but reliable Prusa i3 clone.
Code associated with the buttons for testing them.
Results are seen in the ESPhome logs live view after
flashing if you don’t have the LCD…

# I2C bus config


i2c:
sda: 4
scl: 5
scan: true
id: bus_a

# I2C I/O expander config


pcf8574:
- id: 'pcf8574_output_hub'
address: 0x24
pcf8575: false
- id: 'pcf8574_input_hub'
address: 0x22

binary_sensor:
- platform: gpio
id: button_1 #push button on front of controller encl
pin:
pcf8574: pcf8574_input_hub
# Use pin number 4 (starting at 0)
number: 4
# One of INPUT or OUTPUT
mode:
input: true
inverted: true
internal: true
on_click:
- min_length: 50ms
max_length: 350ms
then:
- sprinkler.resume_or_start_full_cycle:

- platform: gpio
- platform: gpio
id: button_2 #push button on front of controller encl
pin:
pcf8574: pcf8574_input_hub
# Use pin number 5 (starting at 0)
number: 5
# One of INPUT or OUTPUT
mode:
input: true
inverted: true
internal: true
on_click:
- min_length: 50ms
max_length: 350ms
then:
- sprinkler.next_valve: esp32_sprinkler_ctrlr

- platform: gpio
id: button_3 #push button on front of controller encl
pin:
pcf8574: pcf8574_input_hub
# Use pin number 6 (starting at 0)
number: 6
# One of INPUT or OUTPUT
mode:
input: true
inverted: true
internal: true
on_click:
- min_length: 50ms
max_length: 350ms
then:
- sprinkler.previous_valve: esp32_sprinkler_ctrlr

- platform: gpio
id: button_4 #push button on front of controller encl
pin:
pcf8574: pcf8574_input_hub
# Use pin number 7 (starting at 0)
number: 7
# One of INPUT or OUTPUT
mode:
input: true
inverted: true
internal: true
on_click:
- min_length: 50ms
max_length: 350ms
then:
- sprinkler.pause: esp32_sprinkler_ctrlr
- min_length: 500ms
max_length: 2000ms
then:
- sprinkler.shutdown: esp32_sprinkler_ctrlr

mr.sneezy Oct '22

Now that the buttons do useful stuff, I need to show


that on the LCD (i.e paused status).
The paused valve number apparently is available
internally form what I see on Github references, but I
will need to make my LCD cases more complex or
rethink that method…

paused_valve()

Fallingaway24 Justin Oct '22

This is awesome! I just finished a basic irrigation


controller 4 or 5 months before they introduced the
sprinkler component but, doing it over had been on
my to do list. Reading through the docs, I’ve been
excitedl to take on this challenge and thanks to your
awesome post I’ll have something to look st for help.
Thank you for taking your time and sharing this with
us! I appreciate this very much!

bremby Nov '22

@mr.sneezy , I did something to simplify (I guess)


the code for the SWITCH portion; this should safe a
lot of rows…, let me know what do you think

lambda: |-
switch (id(esp32_sprinkler_ctrlr).active_valve().

case -1:
it.strftime(0, 0, "%a", id(homeassistant_time).
it.strftime(10, 0, "%d-%m-%Y", id(homeassistant
it.strftime(12, 1,"%H:%M:%S", id(homeassistant_
it.printf(0, 3, "Status: %s", id(esp32_sprinkle

if (id(esp32_sprinkler_ctrlr_status).state ==
it.printf(0, 2, "Zone %s", id(zone_active_senso
it.printf(10, 2, "T: %s", id(zone_time_remainin
}

break;

default:
it.printf(0, 0, "Zone %s:", id(zone_active_sens
it.printf(8, 0, "%s", id(zone_active_sensor).st
it.printf(0, 1, "Time Letf: %s", id(zone_time_r
break;
}

I also made the LCD “dimmable” following these


instructions from @LUNZ

[Dimmable PCF8574 LCD Display with ESPHome]


(Dimmable PCF8574 LCD Display with ESPHome
)

here is the full code, just in case

# Establish Substitutions
substitutions:
device_name: sprinkler
friendly_name: "Sprinkler"
device_platform: ESP32
device_board: esp32dev
device_ip: X.X.X.X
sensor_update_frequency: 1s
sprinkler_name: esp32_sprinkler_ctrlr

packages:
wifi: !include common/device_wifi.yaml
device_base: !include common/device_base_ESP32.yaml
home_assistant_api: !include common/device_api.yaml
sensor_wifi_ip_address: !include common/sensor_wifi_ip_

# Enable logging
logger:
#########################################################
##### I/O expander hub definition
#########################################################
mcp23017:
- id: 'mcp23017_hub'
address: 0x20
#nodemcu devkit v4.0
i2c:
sda: 21
scl: 22
scan: True
frequency: 200kHz
#########################################################
# 10x4 LCD config
display:
- platform: lcd_pcf8574
dimensions: 20x4
address: 0x27
update_interval: 1s
lambda: |-
switch (id(esp32_sprinkler_ctrlr).active_valve().

case -1:
it.strftime(0, 0, "%a", id(homeassistant_time).
it.strftime(10, 0, "%d-%m-%Y", id(homeassistant
it.strftime(12, 1,"%H:%M:%S", id(homeassistant_
it.printf(0, 3, "Status: %s", id(esp32_sprinkle

if (id(esp32_sprinkler_ctrlr_status).state
it.printf(0, 2, "Zone %s", id(zone_active_senso
it.printf(10, 2, "T: %s", id(zone_time_remainin
}

break;

default:
it.printf(0, 0, "Zone %s:", id(zone_active_sens
it.printf(8, 0, "%s", id(zone_active_sensor).st
it.printf(0, 1, "Time Letf: %s",
break;
}

output:
- platform: ledc
pin: GPIO14
id: sprinkler_backlight

light:
light:
- platform: monochromatic
output: sprinkler_backlight
name: "LCD Display Sprinkler Backlight"
id: light_backlight
restore_mode: ALWAYS_ON

#########################################################
#########################################################
# Enable Home Assistant APIs
api:
reboot_timeout: 0s
services:
- service: set_multiplier
variables:
multiplier: float
then:
- sprinkler.set_multiplier:
id: esp32_sprinkler_ctrlr
multiplier: !lambda 'return multiplier;'
- service: start_full_cycle
then:
- sprinkler.start_full_cycle: esp32_sprinkler_ctr
- service: start_single_valve
variables:
valve: int
then:
- sprinkler.start_single_valve:
id: esp32_sprinkler_ctrlr
valve_number: !lambda 'return valve;'
- service: next_valve

aruffell Mar '23

@mr.sneezy Very nice implementation of your


ESPHome based irrigation system. I have an old
RainMachine that is about to die and their
replacement is both expensive and old so I think I will
build my own. One thing I was curious about your
setup is how the time is tracked as I did not see any
reference to an RTC on the board. Did you add one?
Or is time completely dependent on HA which may
be an issue in case the system needs to operate on
its own for some time.

mr.sneezy Apr '23


mr.sneezy Apr '23

I didn’t worry about RTC until it proves necessary yet.


So far the network time has been reliable so the
watering has been reliable.
Oddly enough I did another recent small project for
somebody else that uses a $5 RTC module on an
ESP32. I used this one below, but it needed four pull
up resistors removed to make the SDA and SCL
lines 3.3V compatible. As this module is I2C driven it
should be not hard to add to the 8ch relay board in
parallel with the LCD if I need too.
RTC Clock & EEPROM Module, I2C, DS1307,
AT24C32 - 99Tech

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy