Tutorial: how to make a water heater timer using ESPhome, a Sonoff Basic, and contactor

Hi all,

I’m posting this partly as a tutorial, and partly as an obscure method of backing up my YAML file. Also just randomly showing how I did something in case anyone ever searches for how to do this. This community has helped me a lot and I’d like to give something back, however obscure and useless.

Today I’m going to show you how to make a water heater timer using ESPhome and an appropriately sized contactor.

My needs are for my water heater to turn on twice a day for 90 minutes - once in the morning, once in the evening. I could do this easily by just exposing the relay of a Sonoff Basic to HomeAssistant, but the problem is that there are a million reasons why an ESPHome node can’t speak to HA right now, and I don’t want a wifi outage or a crash on my RPI to in any way prevent the water from being hot when I need it to be. Therefore, I’m putting the timer schedule for the water heater inside the yaml. That way, it’ll happen even if the node can’t, for whatever reason (I’m looking at you 1.14.3) speak to HA.

To follow along, you will need an ESP8266-based smart switch like a Sonoff Basic, and a contactor capable of handling at least 20amps of AC current.

You see, a smart switch is generally a poor choice for a switching high power applications because anything with a heating element will generally draw more current than the feeble 10 amps that the average smart switch is rated for. This will lead to the magic smoke escaping from the relay inside the smart switch, and possibly a house fire. Instead, we’ll use the smart switch to drive an appropriately-sized contactor, which in turn will switch the water heater on and off. Incidentally, I use this method for switching big pumps as well, and it works great.

You can buy a contactor at any electronics supply store - the kind of place that will also sell cable and conduits. A full discussion of the miracle of contactors is outside the scope of this post, but basically, you can think of them like a really big, punchy relay that gets switched with high voltage AC current. Contactors have 2 inputs (Live and Neutral) for the switching current, and 4 parallel channels for the device being switched. And yes, 4 parallel channels means you could technically switch 4 different devices at once, but only simultaneously.

So, let’s suppose you’ve got a smart switch and a contactor, and you’re going to use ESPhome to build a water heater timer that integrates with HomeAssistant. We want manual control to turn the thing on and off at will, but we also want the water heater to switch on and off on a schedule.

First thing to do is flash the smart switch (see YAML below), and test it on a workbench to make sure everything is working, because where this is going, you don’t want to take it back out.

  
esphome:
  name: your_node_name
  platform: ESP8266
  board: esp01_1m

# I do static IPs because HA tends to lose track of ESPHome nodes that have dynamic IPs for some reason
wifi:
  networks:
  - ssid: "the_wifi_at_my_workbench"
    password: "password"
  - ssid: "the_wifi_where_the_node_will_be_deployed"
    password: "password"
  manual_ip:
    static_ip: 192.168.1.whatever
    gateway: 192.168.1.1
    subnet: 255.255.255.0
    dns1: 192.168.1.whatever

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

binary_sensor:
# this is so the button on the face of the Sonoff works
  - platform: gpio
    id: button
    pin:
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: True
    on_press:
      - switch.toggle: relay

switch:
# this is so you can have a manual switch in HA
  - platform: gpio
    name: "Switch - Geyser"
    pin: GPIO12
    id: relay

time:
# the morning cycle
  - platform: sntp
    id: cycle_morning
    on_time:
      - seconds: 0
        minutes: 30
        hours: 4
        days_of_week: MON-SUN
        then:
          - switch.turn_on: relay
          - delay: 5400s
          - switch.turn_off: relay
# the evening cycle
  - platform: sntp
    id: cycle_evening
    on_time:
      - seconds: 0
        minutes: 0
        hours: 16
        days_of_week: MON-SUN
        then:
          - switch.turn_on: relay
          - delay: 5400s
          - switch.turn_off: relay

Most of the yaml is straightforward, but the important bit from an automation point of view is the time: section. You will want a new platform: sntp section for each schedule instance you want the thing to run. It’s possible to sync the time with HomeAssistant instead of sntp, but, we’re assuming that HA might go down, or the API might disconnect repeatedly, or whatever (ahem1.14.3ahem), so we want to sync with something else.

Next you specify the seconds, minutes, and hour you want the thing to trigger, and the days of the week. After that, you use a regular then: section to specify what steps you want the node to take on the trigger. Mine are simply turn on, wait a while, turn off.

Once you’ve confirmed that the code is working for you, it’s time to install the hardware. Because you are not stupid, you hire a professional electrician to open your distribution board, and install the contactor inside it after the geyser breaker - so the Live from the geyser breaker passes through one (or more if you feel like looping) of the channels through the contactor. You don’t do this yourself because it’s probably illegal, and it’s definitely dangerous.

Some people might say, hey, it’s as simple as dropping the mains at the box outside, and then wiring the contactor inline after the geyser breaker. Those people would be right, but, any time you open the distribution board without knowing what you’re doing, it’s on you. I did not tell you to do that. I specifically said it was stupid. Don’t do that.

Anyhoo. Once the contactor is inline with the geyser, have your electrician (NOT YOU) install the smart switch on the wall next to the distribution box. They can use common neutral, and take Live from the same breaker that the geyser/contactor is on. The output of the smart switch will be attached to the switching circuit on the contactor.

And that’s about it. You can integrate the switch into your Lovelace in the usual way in case you want to manually trigger the water heater at any point, and the button on the Sonoff works too.

I hope you find this helpful.

2 Likes

Amazing, great little tutorial. Learned something about on-board scheduling, IP settings, multiple WiFi and time synchronization.

Only question is: if the alternate wifi is different ip settings, can these be specified per WiFi connection?
Thanks

1 Like

Hi @dougle03,

Honestly I don’t know. In my specific circumstance, both wifi APs are part of the same network, but the place in which this particular device is deployed can’t reach the main house’s mesh. Instead, it gets wifi from an AP in the building it’s in. I’d like to extend the mesh to reach it, but unfortunately I bought into Airties, and no one in my country stocks them anymore. It sucks.

But anyway, that’s why I can use the same static IP on both APs: they both attach to the same network.

1 Like

This is most helpful. For similar reasons to you I try to make my ESPHome nodes independent of HA when they are critical.

The one bit that missing for me is ESPHome support for a RTC, rather than having to use internet based time as you have.

If you wish to be independent of the network for time, you csn use a gps device :wink: