Simple, Reliable Sprinkler Controller with ESPHome

Thank you for the great project idea reggleston4!! I just implemented this for my house and works great!
I was curious, do you know if it would be possible to add an oled i2c display? I saw from the esp8266 12e that pins 4 and 5 are the SDA / SCL pins, however they are being used to control some relays. Do you know if any other pins from the header could control the display? (Sorry I’m a bit of a new learner with esphome).

First of all thank you so much for setting this up. Ive been looking to try and make one myself but have been having a hard time with it. I do have a couple of questions please
I am so confused as to how to setup zone watering. Say i want zone 1 to come on schedule 1 on tuesday and friday and then zone 2 to come on schedule 2 on wednesday and thursday, how to i get them to save so i can do each zone differently. Ican get 1 zone to work perfectly but unsure how to then move on to setting the next zone etc.
alsoI know you have included manual buttons for rain delay, but is there any way to use Openweathermaps precipitation to automatically delay watering?
Thank you very much
Macca

Do you consider adding rain sensors for detection and interrupting watering operations during rainy weather

@nahwel Hello, I’m happy to hear you got it working. As you have pointed out, the default I2C pins on the ESP8266 are used. I believe the GPIO pins across the bottom of the ESP8266 are unused (on the 8 channel board), so you may be able to use software I2C on those pins. It is unclear to me if this will work, but you can certainly try specifying a different set of pins in your I2C setup! That would probably be the fastest way to find out!

Hello @merlinmac, I’m glad you got it working. Unfortunately, the way this device is configured doesn’t allow for what you are trying to do. As it is, it only allows a custom duration for each zone, and you have the option of running 1, 2, or 3 times each day at your programmed start time.

This ESPHome configuration is not as β€œfeature complete” as commercial apps like Orbit’s b-hyve. After all, I just whipped this up quickly in my spare time. You can certainly extend the configuration to add the features you want! In the future (probably distant future), I may write a more complex configuration that allows independent scheduling for each zone. If you do that, it ends up being a LOT of buttons and switches. You can do it though!

Regarding automatic rain delay, you could use an automation within Home Assistant to automatically delay watering. You can source data from the web using an integration, or you can integrate your own independent rain sensor into your local Home Assistant. Then just create an automation to set the rain delay to ON.

Good luck!

Thank you so much for getting back to me. That certainly explains why I spent 2 days playing with it and not getting anywhere. I will put it to good use for sure :slight_smile:

Hi guys thanks for your Great work. I am doing the Same at the Moment with a few switches in esphome that control my valves and I was thinking of converting to the sprinkler feature.

Do you know if it is possible to use a Main Switch outside of the esp controller?

I have a Main valve that is Controller via zigbee from HA and also has a Timer shutdown. After the Main valve I will have three solenoids that are Controller with an esp. I wanted to have Both systems as I Like to have sone redundance in my setup when dealing with Mains water.

@BugFixx I don’t know what you mean by β€œmain switch outside of the controller”. You can have multiple valves in any configuration you want, however, this ESPHome configuration was not written with the intent to operate with a main valve. I believe the Sprinkler Controller component that this is based upon does have a means of activating an upstream valve, however it is called a β€œpump” in the documentation (it could be a valve or a pump, either way). You could easily modify this integration to incorporate that functionality by adding a β€œpump_switch_id” for each valve, and then connecting your main valve to that switch/relay. Sorry, I cannot help with that, but good luck!

@nahwel I pulled out an I2C OLED display for another project, so I quickly tested if I could connect it to this board. The answer is YES, it works. I was also able to do it easily by using the pins already broken out on the header (instead of trying to connect to the unused GPIO pins along the bottom row, which do not have thru holes).

Because you will need to use the RX and TX pins for initial programming, first, do not connect the I2C display, and program only with this simple relay configuration. Substitute your own passwords and keys:

esphome:
  name: 8-channel-relay-with-i2c-oled
  friendly_name: 8 Channel Relay with I2C OLED

esp8266:
  board: esp12e
  restore_from_flash: True

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: [add your key]

ota:
  password: [add your password]

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "8-Channel-Relay-With-I2C-Oled"
    password: [add your password]

captive_portal:
    
switch:
  - platform: gpio
    pin: GPIO16   
    name: "R1" 
    id: R1
    restore_mode: ALWAYS_OFF
  - platform: gpio 
    pin: GPIO14
    name: "R2"
    id: R2
    restore_mode: ALWAYS_OFF
  - platform: gpio 
    pin: GPIO12
    name: "R3" 
    id: R3
    restore_mode: ALWAYS_OFF
  - platform: gpio 
    pin: GPIO13
    name: "R4" 
    id: R4
    restore_mode: ALWAYS_OFF
  - platform: gpio 
    pin: GPIO15
    name: "R5" 
    id: R5
    restore_mode: ALWAYS_OFF
  - platform: gpio 
    pin: GPIO0
    name: "R6" 
    id: R6
    restore_mode: ALWAYS_OFF
  - platform: gpio 
    pin: GPIO4
    name: "R7" 
    id: R7
    restore_mode: ALWAYS_OFF
  - platform: gpio 
    pin: GPIO5
    name: "R8" 
    id: R8
    restore_mode: ALWAYS_OFF

Then, turn off the device and disconnect your programmer.

Now you can connect the I2C display:
display VIN pin to relay board 5V pin
display GND pin to relay board GND pin
display SDA pin to relay board TXD pin
display SCL pin to relay board RXD pin
display RST pin to relay board IO2 pin

Boot the device.

Now you can add these lines to your configuration and upload the new program wirelessly:

i2c:
  sda: GPIO1
  scl: GPIO3

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x32"
    reset_pin: GPIO2
    address: 0x3C
    lambda: |-
      it.print(0, 0, id(roboto_16), "Hello World!");

font:
  - file:
      type: gfonts
      family: Roboto
    id: roboto_16
    size: 16

That’s it! Enjoy!

As I said my Main valve is controlled via zigbee and cannot be controlled with the esp that controlles the valves.
But thanks I will try or just Stick to the switches and automate everything in HA using the Switch components.

@raythefourth you are awesome!!! Thanks for testing that out! I will try to take a look at it and see if I can make it work with the new code :smiley:

@raythefourth - Awesome write up! Thank you. Got the board hooked up and working with ease. Once the weather clears up I’ll replace my crappy rainbird controller with this and do a live test. One thing I was trying to figure out is if the code currently has any way to set certain switches to go active on particular days.

for example:
switch/zone 1, 2, 3 run on Monday and Thursday at 8am
switch/zone 4, 5 on Wednesday at 8am

I see scheduled start times and day selection toggles but no way to specify completely different switch/zone + day/time combos. I could be over looking it but just wanted to check before I started writing custom code for it.

Hi, I setup the 4relay version of this board and I have it wired like this with incoming 24VAC:


I used a AC to DC converter to accept the incoming 24VAC, this then jumps to the relays to send 24VAC to the valves. The reduced converted 5VDC goes to ESP 5V input.

Hope this helps.

Hi, great write up really appreciate it.

I wanted to give the I2C a shot using the 4relay version. Is there a way to add codes so that it shows status of the running valve/if it’s off/ and possibly runtime left? Or better yet, what are you using it to display, mind sharing code?

Thanks

Think it would be best to use an automation for that

Here is my display settings, and a link to the display I used. Note I converted switch one to pump to completely cutoff other side of 24VAC from valves when not running.

https://www.amazon.com/dp/B08V8KWXM6?psc=1&ref=product_details

wifi_icon.h

const char * wifi_icon(float wifi_strength) {
if (isnan(wifi_strength)) return β€œ\U000F092B”; // No-wifi
else if (wifi_strength < 20) return β€œ\U000F0920”; // low-wifi
else if (wifi_strength < 45) return β€œ\U000F091F”; // wifi-1
else if (wifi_strength < 65) return β€œ\U000F0922”; // wifi-2
else if (wifi_strength < 80) return β€œ\U000F0925”; // wifi-3
else return β€œ\U000F0928”; // wifi-4
}

##################### yaml

i2c:
sda: GPIO1
scl: GPIO3
frequency: 800kHz

display:

  • platform: ssd1306_i2c
    id: SSD1315
    model: β€œSSD1306 128x64”
    address: 0x3C
    update_interval: 5s
    lambda: |-
    if ( id(wifi_signal_pct).has_state() ) {
    it.print(110, 0, id(mdi_medium), wifi_icon(id(wifi_signal_pct).state));
    it.print(20, 16, id(roboto_12), " : 1");
    it.print(20, 28, id(roboto_12), " : 2");
    it.print(20, 40, id(roboto_12), " : 3");
    it.print(20, 52, id(roboto_12), " : 4");
    it.print(75, 16, id(roboto_12), " : 5");
    it.print(75, 28, id(roboto_12), " : 6");
    it.print(75, 40, id(roboto_12), " : 7");
    it.print(75, 52, id(roboto_12), " : 8");
    it.printf(5, 0, id(roboto_12), β€œx%.1f”, id(controller_multiplier_number).state );
    if ( id(${id_prefix}_auto_advance_switch_id).state ) { it.print(40, 0, id(mdi_medium), β€œ\U000F1060”); } else { it.print(40, 0, id(mdi_medium), β€œ\U000F03E7”); }
    if ( id(${id_prefix}_raindelay_24h_enabled).state ) { it.print(70, 0, id(mdi_medium), β€œ\U000F0597”); } else { it.print(70, 0, id(mdi_medium), β€œ\U000F0599”); }
    if ( id(${id_prefix}_raindelay_48h_enabled).state ) { it.print(85, 0, id(mdi_medium), β€œ\U000F0597”); } else { it.print(85, 0, id(mdi_medium), β€œ\U000F0599”); }
    }
    if ( id(${id_prefix}_main_switch_id).state) {
    if ( id(${id_prefix}_pump_sw1).state ) { it.print( 5, 16, id(mdi_medium), β€œ\U000F058C” ); } else { it.print( 5, 16, id(mdi_medium), β€œ\U000F1508” ); }
    if ( id(${id_prefix}_valve_sw2).state ) { it.print( 5, 28, id(mdi_medium), β€œ\U000F058C” ); } else { it.print( 5, 28, id(mdi_medium), β€œ\U000F1508” ); }
    if ( id(${id_prefix}_valve_sw3).state ) { it.print( 5, 40, id(mdi_medium), β€œ\U000F058C” ); } else { it.print( 5, 40, id(mdi_medium), β€œ\U000F1508” ); }
    if ( id(${id_prefix}_valve_sw4).state ) { it.print( 5, 52, id(mdi_medium), β€œ\U000F058C” ); } else { it.print( 5, 52, id(mdi_medium), β€œ\U000F1508” ); }
    if ( id(${id_prefix}_valve_sw5).state ) { it.print(64, 16, id(mdi_medium), β€œ\U000F058C” ); } else { it.print(64, 16, id(mdi_medium), β€œ\U000F1508” ); }
    if ( id(${id_prefix}_valve_sw6).state ) { it.print(64, 28, id(mdi_medium), β€œ\U000F058C” ); } else { it.print(64, 28, id(mdi_medium), β€œ\U000F1508” ); }
    if ( id(${id_prefix}_valve_sw7).state ) { it.print(64, 40, id(mdi_medium), β€œ\U000F058C” ); } else { it.print(64, 40, id(mdi_medium), β€œ\U000F1508” ); }
    if ( id(${id_prefix}_valve_sw8).state ) { it.print(64, 52, id(mdi_medium), β€œ\U000F058C” ); } else { it.print(64, 52, id(mdi_medium), β€œ\U000F1508” ); }
    } else {
    it.print( 5, 16, id(mdi_medium), β€œ\U000F1508” );
    it.print( 5, 28, id(mdi_medium), β€œ\U000F1508” );
    it.print( 5, 40, id(mdi_medium), β€œ\U000F1508” );
    it.print( 5, 52, id(mdi_medium), β€œ\U000F1508” );
    it.print(64, 16, id(mdi_medium), β€œ\U000F1508” );
    it.print(64, 28, id(mdi_medium), β€œ\U000F1508” );
    it.print(64, 40, id(mdi_medium), β€œ\U000F1508” );
    it.print(64, 52, id(mdi_medium), β€œ\U000F1508” );
    }

font:

  • file:
    type: gfonts
    family: Roboto
    id: roboto_12
    size: 12
  • file: β€˜fonts/materialdesignicons-webfont.ttf’
    id: mdi_medium
    size: 15
    glyphs:
    • β€œ\U000F0928” # wifi-4
    • β€œ\U000F0925” # wifi-3
    • β€œ\U000F0922” # wifi-2
    • β€œ\U000F091F” # wifi-1
    • β€œ\U000F0920” # Low-wifi
    • β€œ\U000F092B” # No-wifi
    • β€œ\U000F18F6” # cloudy clock
    • β€œ\U000F0597” # raining
    • β€œ\U000F0599” # sunny
    • β€œ\U000F058C” # drop
    • β€œ\U000F1508” # drop off
    • β€œ\U000F1060” # sprinkler
    • β€œ\U000F03E7” # pause
1 Like

Do you mind sharing all the files? Thank you