Disclosure: This article may contain affiliate links. If you decide to make a purchase, I'll make a small commission at no extra cost to you.
Project: Smart light switch with offline fail-over
- Create a light switch that is decoupled from power delivery so the 9 Hue Bulbs in my Dining Room Chandelier can always be powered, while allowing use of the light switch on/off paddle.
- Provide a fail-over mechanism that allows the switch to operate even when Home Assistant is unavailable.
- Shelly1 (or a Sonoff Basic, or other ESPHome compatible board).
- Electrical wire (Romex 12/2, solid wire, 2 covered conductors plus one ground conductor).
- Wire Nuts, Non-twist Connectors, or Wago Connectors.
Goal #1: Make the dumb light switch talk to Home Assistant
I started with the following ESPHome code fragment which uses the Home Assistant API to toggle the smart bulbs on or off when the wall switch is flipped. This worked great and I could have stopped there. But I want to make it work if Home Assistant wasn’t available.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 binary_sensor: - platform: gpio pin: number: GPIO5 name: Wall Switch id: button filters: - delayed_on: 10ms - delayed_off: 10ms on_state: - homeassistant.service: service: light.toggle data: entity_id: light.dining_room switch: platform: gpio id: relay pin: GPIO4 restore_mode: ALWAYS_ON
Goal #2: Fail-over
So, we need a way to check to see if Home Assistant is connected, so we can toggle the light with the relay instead. Luckily ESPHome provides a condition for checking if Home Assistant is connected: api.connected.
1 2 3 4 if: condition: api.connected: then:
Next, we check to see if the relay is on, and if it is off turn it on. We need the relay to be on before Home Assistant can turn on our smart bulbs on.
In theory the relay should always be on. However there is one scenario, which will be revealed soon, in which the relay would be off.
1 2 3 4 5 6 7 8 9 10 - if: condition: switch.is_off: relay then: - switch.turn_on: relay - homeassistant.service: service: light.turn_on data: entity_id: light.dining_room
If the relay is already on then ask Home Assistant to toggle the light on or off.
1 2 3 4 5 6 else: - homeassistant.service: service: light.toggle data: entity_id: light.dining_room
Now we come to the “fail-over” bit. This is the else condition for when
api.connected is false, meaning that ESPHome has lost connection to Home Assistant!
1 2 else: - switch.toggle: relay
This code fragment simply turns the Shelly1’s internal relay from on to off or off to on when the physical light switch is toggled.
If you have ever done programming before you know may be aware a common practice is to define “constant” variables at the top of your code. Well, that is what ESPHome’s substitutions feature provides.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 --- # Shelly 1 Power Module # Location: Dining Room Light Switch # substitutions: project: Shelly1 01 id: shelly1_01 button_gpio: GPIO5 relay_gpio: GPIO4 hass_light: light.dining_room esphome: name: $id platform: ESP8266 board: esp01_1m wifi: ssid: !secret wifi_ssid password: !secret wifi_pass ota: logger: # Home Assistant API api: script: - id: hass_light_toggle then: if: condition: api.connected: then: - if: condition: switch.is_off: relay then: # Turn the relay back on and turn on the light. - switch.turn_on: relay - homeassistant.service: service: light.turn_on data: entity_id: $hass_light else: # Have Home Assistant toggle the light. - homeassistant.service: service: light.toggle data: entity_id: $hass_light else: # When HA is unavailable, toggle the relay. - switch.toggle: relay binary_sensor: - platform: gpio pin: number: $button_gpio name: $project Wall Switch id: button filters: - delayed_on: 10ms - delayed_off: 10ms on_state: - script.execute: hass_light_toggle switch: platform: gpio id: relay pin: $relay_gpio restore_mode: ALWAYS_ON
It’s not a bug, its a feature
The relay can only be turned off when Home Assistant is offline when the light was turned off by the wall switch. So, when Home Assistant comes back online that smart light will be unavailable until the wall switch is flipped again.
Let’s call this an intended side-effect. If we made the relay somehow turn back on automatically when it connects to Home Assistant again, the smart bulb would turn on! I can tell you from experience wives really don’t like your Home Automation hobby when the bedroom lights turn on in the middle of the night!
Thank you to Mauricio Bonani (@mbonani) of bonani.tech for encouraging me to create a blog as a knowledge dump that I can refer back to in the future. I hope others find some of my articles as useful and I have found Mauricio’s articles.
Thank you for visiting my new blog! This is my first article, and I would really appreciate your feedback. Please stick around as I will be posting articles at least once a week for the next few months. I already have ideas set aside for 29 more articles on Home Assistant and ESPHome, not to mention potential tips on creating designs for laser cutters!
To hold you until my next article please visit my ESPHome Github Repository.