Posting by request from https://www.reddit.com/r/homeassistant/comments/1hufw9c/i_got_my_shellys_to_keep_working_in_case_of_a/
My ESPHome file is higly modularized with a lot of other functionality that is not relevant right now, so here's an extract of the relevant bits. It's a bit more verbose than usual because it's the output of ESPHome validation process, which dumps the processed YAML after "expanding" it.
Context:
- light switch is a Shelly, but not really relevant — any ESP relay with a button would work
- connected to the relay are smart lights talking Zigbee
- when switch is "smart", relay remains on all the time and switch talks to HASS that turns on/off the light accordingly
- when switch is "dumb", it takes control by turning the relay on/off instead
- this requires that the light is configured to turn on when power is cut and back on, i.e., acts as a dumb light
- I have installed springs behind every light switch, so they act as momentary switches instead of flipping
- one click toggles the light on/off
- multiple clicks or holding the button does other stuff (omitted here for brevity)
How it works:
- there is a switch component that controls if the relay is in dumb mode or not
- when disconnected from Home Assistant, dumb mode is assumed automatically irrespective of the state of this switch
- Shelly has a multi-click handler attached to the button that calls the relevant scripts (for brevity I included only
button_click_single
) - when not in dumb mode:
- send event to home assistant indicating which light to turn on
- wait to see if light changes state
- if light has not changed state, assume there's something wrong in HASS side (misconfiguration, Zigbee is not working, etc.):
- when turning on the light, toggle the relay off and back on to force it to turn on (actually it is done twice in quick succession because this makes Philips Hue lights revert to maximum brightness)
- when turning off the light, just turn off the relay
- enter dumb mode automatically
- when in dumb mode, just toggle the relay
- Home Assistant notices any Shelly changing to unavailable or dumb mode and will:
- notify me so I know something's off
- turn off the dumb mode to make the light switch smart again, if it concludes that it was due to a temporary disconnection
Other implementation notes:
- the functions in C act as a glorified "macro", so it's shorter to refer to them than repeating the same logic everywhere
- state of the light in ESPhome side is
text
and notboolean
so it can differentiate a light beingoff
and beingunavailable
- if the light itself is offline for some reason (let's say Zigbee network down), it will make Shelly enter dumb mode
The result of this is that a single press of the light switch will always work, and will always succeed in toggling the light even if:
- the Wi-Fi is down
- Home Assistant is down
- Zigbee network is down
- everything is up but a misconfiguration is preventing the click on the switch from "reaching" the right light
- the smart light has been substituted with a dumb light