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:
- The new Sonoff R2 doesn’t have an extra pin out for GPIO
- I didn’t know how to get ESPHome configs to simulate the pushbutton switch similar to Tasmota
- 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