DIY Automate Existing Light Switch: ESPHome on a Sonoff Basic in the gang box!

With the recent work on ESPHome (thanks @OttoWinter) and the new direct ESPHome API integration for HA, I finally pulled the trigger on swooping up some Sonoff basics and converting some of my existing switches to smart switches, similar to the approach by @DrZzs:

However, there were a couple issues for me to overcome:

  1. The new Sonoff R2 doesn’t have an extra pin out for GPIO
  2. I didn’t know how to get ESPHome configs to simulate the pushbutton switch similar to Tasmota
  3. I didn’t want to deal with the ESPHome firmware going into a reboot loop if Wifi/MQTT/HA went down (this is a feature of the firmware because the network stack can get funky)

After digging into the ESPHome docs, I put together a config for ESPHome that is attached below that does this exactly, and I’ll explain it a bit.

1. GPIO input on Sonoff basic R2

Found the answer to that one here: GitHub - arendst/Tasmota: Alternative firmware for ESP8266 and ESP32 based devices with easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX. Full documentation at

GPIO14 is not inuse anymore. Instead you can use GPIO2 labled as IO2 on the board. Unfortunately the GPIO Point is not prepared for a Pin, you will need to solder your cable directly on the Board. Be carefull, to high or long temperatures can damage the spot and its connectivity. You should also make sure, that there is no traction on the cable. Fix the cable with a cable tie.

This is true… that pad is super small and I was worried I wouldn’t get it soldered on there properly. I did though. check the link for photos of the pad (on the backside of the Sonoff)

2. Getting ESPHome to trigger the relay based on a physical switch:

This one relied on me first figuring out ESPHome, so that took a while. The first step is defining an output for the main relay on the Sonoff (hooked to GPIO12)

output:
  - platform: gpio
    pin: GPIO12
    id: main_relay

The second is creating a light for the relay:

light:
  - platform: binary
    name: "Kitchen Sconces"
    id: kitchen_sconces
    output: main_relay

At this point, whether you configure ESPHome for MQTT or the HA API… you’ll have a functional light that can be operated through the HA interface. The next trick is getting that light to trigger based on a physical switch. This should just require shorting that IO2 pin I soldered on the back of the board with GND. This relies on setting up a binary_sensor as follows

binary_sensor:
  - platform: gpio
    pin: 
      number: GPIO2
      mode: INPUT_PULLUP
      inverted: True
    name: "Kitchen Sconce Physical Switch Sensor"
    on_press:
      then:
        - light.toggle: kitchen_sconces
    on_release:
      then:
        - light.toggle: kitchen_sconces

The trick is to turn on the built in pull-up resistor with mode: INPUT_PULLUP. You might want different behavior, but I want the physical switch to toggle the lights whether the switch is turned on or off. This relies on using the on_press and on_release options for the sensor to toggle the kitchen_sconces light. This also means that if you turn the light on through HA, turning the physical switch “on” will turn off the lights. I’m OK with this behavior, but you might want physical on to always mean on and physical off to always mean off, which would look like this:

    on_press:
      then:
        - light.turn_on: kitchen_sconces
    on_release:
      then:
        - light.turn_off: kitchen_sconces

The coolest thing about this and other powerful portions of ESPHome is that this “automation” will work whether HA is active or not. this is an important goal for my house: stuff should not break if the internet or HA goes down

Which leads me to my last problem…

3. ESPHome should never reboot if Wifi/MQTT/HA goes down

ESPHome has a feature that will automatically reboot the Sonoff after 5 minutes of Wifi being down, MQTT being disconnected, or the HA API being inaccessible. This functionality can be disabled by setting reboot_timeout: 0s on the mqtt, api, and wifi configuration settings in the config.

This is a feature because apparently the network stack on the ESP can get screwed up if any of these things happen. However, a reboot with the lights on would mean the lights going off (since the relay will lose coil voltage)… this is a hard no for me. Physical switches need to work 100% of the time.

However, I am concerned about the risk of the switch no longer responding to HA commands… so I do need a way to restart it if necessary. Given that it’s hardwired behind a switch in a gangbox, I needed an alternate solution. Enter the awesome functionality of on_multi_click for the GPIO binary_sensor! We also need a “reboot” switch.

switch:
  - platform: restart
    name: "Reboot Kitchen Sconce Sonoff"
    id: kitchen_sconces_restart

binary_sensor:
  - platform: gpio
    pin: 
      number: GPIO2
      mode: INPUT_PULLUP
      inverted: True
    name: "Kitchen Sconce Physical Switch Sensor"
    on_press:
      then:
        - light.toggle: kitchen_sconces
    on_release:
      then:
        - light.toggle: kitchen_sconces
    on_multi_click:
    - timing:
        - ON for at most 0.5s
        - OFF for at most 0.5s
        - ON for at most 0.5s
        - OFF for at most 0.5s
        - ON for at most 0.5s
        - OFF for at most 0.5s
        - ON for at most 0.5s
        - OFF for at least 0.2s
      then:
        - switch.turn_on: kitchen_sconces_restart

This configuration allows me to rapidly turn the physical light switch on and off 4 times to reboot the Sonoff!

Anyhow, hope this helps someone try out ESPHome on their ESPs… Full config below.

esphome:
  name: kitchen_sconces
  platform: ESP8266
  board: esp01_1m
  board_flash_mode: dout

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  reboot_timeout: 0s
  fast_connect: true

api:
  password: !secret ota_api_password
  reboot_timeout: 0s

ota:
  password: !secret ota_api_password

# Enable logging
logger:
  
output:
  - platform: gpio
    pin: GPIO12
    id: main_relay
    
switch:
  - platform: restart
    name: "Reboot Kitchen Sconce Sonoff"
    id: kitchen_sconces_restart

light:
  - platform: binary
    name: "Kitchen Sconces"
    id: kitchen_sconces
    output: main_relay
    
binary_sensor:
  - platform: gpio
    pin: 
      number: GPIO2
      mode: INPUT_PULLUP
      inverted: True
    name: "Kitchen Sconce Physical Switch Sensor"
    on_press:
      then:
        - light.toggle: kitchen_sconces
    on_release:
      then:
        - light.toggle: kitchen_sconces
    on_multi_click:
    - timing:
        - ON for at most 0.5s
        - OFF for at most 0.5s
        - ON for at most 0.5s
        - OFF for at most 0.5s
        - ON for at most 0.5s
        - OFF for at most 0.5s
        - ON for at most 0.5s
        - OFF for at least 0.2s
      then:
        - switch.turn_on: kitchen_sconces_restart
19 Likes

I literally just started getting set up to flash some sonoff’s with ESPHome for the first time in the last hour or so. I didn’t know about the reboot function of ESPHome. I’ll definitely be implementing your reboot_timeout & multi-click functionality in my code.

What does the “fast_connect:” entry do?

1 Like

based on the docs, fast_connect should only be off if you are connecting to hidden networks and will speed up boot and wifi connect time considerably by turning it on. If you are connecting to a broadcasted SSID, it seems like a good option to turn it on. My reboot cycles were < 5s.

That works fantastic mate. Thanks!!! Do you have a config example for Sonoff T1 and T2?

thanks

unfortunately no, i’ve never used either of them.

Cheers. I’m using below config on my T1 was the same from other forum for a son off basic and is working ok but not sure if this could be an issue later…

esphome:
  name: dinnertablelight
  platform: ESP8266
  board: esp01_1m

wifi:
  ssid: 'yourssid'
  password: '**********************'

# Enable logging
logger:

# Enable Home Assistant API
api:
  password: 'your password'

ota:
  password: 'your password'

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: True
    name: "Dinner Table Light"
    on_press:
      - switch.toggle: fakebutton

switch:
  - platform: template
    name: "Dinner Table Light"
    optimistic: true
    id: fakebutton
    turn_on_action:
    - switch.turn_on: relay
    - light.turn_on: led
    turn_off_action:
    - switch.turn_off: relay
    - light.turn_off: led
  - platform: gpio
    id: relay
    pin: GPIO12

output:
  - platform: esp8266_pwm
    id: basic_blue_led
    pin:
      number: GPIO13
      inverted: True

light:
  - platform: monochromatic
    name: "Dinner Table Light Blue LED"
    output: basic_blue_led
    id: led

sensor:
  - platform: wifi_signal
    name: "Dinner Table Light WiFi Signal"
    update_interval: 60s
  - platform: uptime
    name: "Dinner Table Light Uptime"[quote="hmbarbosa, post:6, topic:99272, full:true"]
1 Like

Thank you @snicker for the great post!

I found it hard to solder to GPIO2 but it seems using RX would work fine instead. See this post: http://www.thesmarthomehookup.com/new-sonoff-basic-wires-inside-sonoff-basic-rf-r2/

1 Like

@snicker are you able to post a pic of inside your plate? I’ve soldered on to IO2 no problems but it still ain’t working for me with your config. I’m starting to think my wiring to the switch might be wrong.

In the pic above I connect GPIO2 to L1 on the wall plate and Ground pin to ground on the plate. Is that right?

i actually can’t post a pic inside my plate as i’ve wrapped the whole thing up in electrical tape!

However, the easiest way to test this is to touch the wire you have on IO2 to the GND pin. You should hear the relay click.

I am not sure how your particular wall switch works, but generally you only need something to complete the circuit from IO2 to GND. Most single way switches in the US will have a ground terminal (green) and two other terminals that are shorted/continuous when the switch is “on” and broken when the switch is “off”. Nothing needs to be connected to the ground terminal in this application. Your situation is probably similar.

I ordered a T1 today as i think i have a good application for it (pantry light where the switch is in a dumb place inside the pantry and a reed switch to turn on and off). When it arrives i plan to flash with ESPHome and figure it all out so i may be able to offer assistance (if you haven’t figured it out by now!)

I actually figured it out the next day thanks to your help. When I connected the GND cable to the free live loop slot in my pic, it worked! The Sonoff Basic is still a big large though so I have ordered some Shelly 1’s instead to hopefully do the trick for me. Thanks!

THANK YOU very much!
I was getting crazy. Installed Tasmota on NodeMCU v3, using two relays with different wall switches (1 relay controlled with 3 wall switches). All worked fine except ghost switchings… Try to fix the configuration with retain but no succeed (It happened every time lose wifi connection).

I installed ESPHome but I wasn’t able to turn on the relays with the wall switches. Thanks very much!.

Now finger crossed for no more ghost switchings (or my wife is going to kill me :D)

Best regards!

You can do a little easier.

binary_sensor:
  - platform: gpio
    pin: 
      number: GPIO5
      mode: INPUT_PULLUP
    id: s
    filters:
      - invert:
      - delayed_on: 30ms
      - delayed_off: 30ms
    on_state:
      then:
        light.toggle: rele
1 Like

Thanks so much for this, snicker. I’m just going down the road of Sonoffs and am still deciding whether to use ESPHome or Tasmota - perhaps you can answer a question.

Like you, I want physical light switches to be able to control the lights, as well as HA. I’ve done things in reverse a bit, gotten smart bulbs (Yeelights) and now I’m going to have the switch become smart with some Sonoffs.

With Tasmota, I know I can control Yeelights via HA using MQTT. So if I flick the switch, Tasmota will send an MQTT command to HA which will then activate the Yeelights. The Yeelights effectively will always be on, just waiting for a command to turn them on or off - the command either me flicking the physical switch or a pressing a button in Lovelace. This allows me to also maintain control over colours/brightness/temperature, et cetera.

But the way automations work in ESPHome (as far as I can tell), I’m not sure this will be possible. ESPHome automations are really only going to turn on a dumb bulb by turning power onto it - there’s no actual command going to the bulb, just electricity. ESPHome is great in that it somewhat bypasses HA to do automations, but in my scenario, is probably a weakness.

Am I right in my understanding?

(As an edit, I understand this would work with say, the Mirabella Genio Bulb as listed on the ESPHome site as it’s a direclty supported platform but my house is full of Yeelights so…)

I’m not actually sure, I’m not quite an ESPHome or Yeelight expert. It sounds like that is something pretty different from what I’ve set up!

In theory you can also call HA services from esphome, so you should able to control yeelights that way, without yeelights being directty supported.

if the goal is to just create a switch that publishes to an MQTT topic, esphome can do that, you wouldn’t need HA as a middleman (though you would need an mqtt server). you could bypass the switch for powering the yeelight entirely, powering it with mains always on, power the sonoff using the same hot and neutral, and use the switch as a sensor to trigger sending the on/off topic to the yeelight

Which I suppose puts ESPHome in front, as it only relies on HA to work for what I’m after, rather than both HA and the MQTT server.

Yes, that is also my understanding

I can confirm that the RX pin works fine as an alternative to the GPIO2 or GPIO14 pin. It’s easier to solder and i’m not worried about needing the Rx pin anymore since i’ll be doing OTA flashes from here on out.

1 Like