One thing that’s always bugged me about smart switches is that once they’re flipped by an automation, the physical switch doesn’t necessarily reflect the state. So you go into a room, reach out to the switch on the wall to turn the lights on (because you’re a neanderthal who doesn’t have presence detection in every room) and the switch is already up. Egads!
I was able to use esphome’s on_multi_click
to provide a way to fix this. If you flip the switch, it toggles like normal (after a very-short-but-still-perceptible delay). If instead you quickly double-flip the switch – from off to on to off, or from on to off to on – the light will be set to the physical position of the switch. So if you find the switch in the “off” position but the light is on, you can quickly (and I do mean quickly) toggle the switch on and back off, and esphome will turn the light off to match.
config
I’m using a Shelly 1L, but that’s not really important. I experimented a little to get the timing acceptable; I wanted the light to come on immediately when the switch is flipped, but a bit of delay is required to enable the “click” states without having the light flash. The double-click action is pretty quick, so you’ve gotta be intentional about it.
output:
- platform: gpio
pin: GPIO5
id: relay1
light:
- platform: binary
name: "${name_prefix} Light"
id: light1
output: relay1
restore_mode: RESTORE_DEFAULT_OFF
binary_sensor:
## reads the state of the #1 connected switch
- platform: gpio
name: "Switch 1"
id: switch1
pin: GPIO4
## don't really need this added to a dashboard, probably
entity_category: diagnostic
## this multi_click allows resetting the switch, so that the light
## reflects the selected position.
on_multi_click:
## [off] on then off: set to off
- timing:
- ON for at most 0.18s
- OFF for at least 0.25s
then:
- light.turn_off: light1
- logger.log: reset to off
## [on] off then on: set to on
- timing:
- OFF for at most 0.18s
- ON for at least 0.25s
then:
- light.turn_on: light1
- logger.log: reset to on
## toggle via switch to on
- timing:
- ON for at least 0.18s
then:
- light.toggle: light1
- logger.log: toggle, via switch to on
## toggle via switch to off
- timing:
- OFF for at least 0.18s
then:
- light.toggle: light1
- logger.log: toggle, via switch to off