I’m pretty experienced with HA but relatively new to Esphome and I’m wondering if this is somehow possible.
What I have right now:
Shelly i3 flashed with Esphome with one of it’s inputs connected to a standard rocker type wall switch. It reports a state of that switch to HA in form of a binary sensor. The HA automation then toggles lights every time the binary sensor changes states between ON and OFF.
What I would like to achieve:
Keep the existing functionality, so flipping that rocker switch will still toggle the same lights. Add additional functionality where if I quickly toggle the wall switch twice (up->down->up or down->up->down), HA will then toggle different lights.
Would it be possible to maybe add some additional binary sensor in esphome and then write automation where toggling the wall switch twice in a quick succesion will toggle a state of that virtual binary sensor? Or am I overcomplicating it and there’s an easier way?
Then make your existing sensor (the one connected to your toggle switch) internal: true and add on_state and on_click events (for example - have a look at the available options to see which one fits your use case):
Do the same for the on_click event, or whatever else you choose. Note you can have multiple on_click events with different timers - this makes binary sensors pretty flexible.
Hi, apologies for the delay in coming back with an update.
I built a test circuit and flashed the i3 with the following code:
# Physical wall switch sensor automation
binary_sensor:
- platform: gpio
pin:
number: GPIO12
mode: INPUT
name: i3-kitchen Input 1
id: wallswitch1
internal: true
filters:
- delayed_on_off: 200ms
on_state:
then:
- if:
condition:
lambda: 'return id(template_sw1).state;'
then:
- binary_sensor.template.publish:
id: template_sw1
state: OFF
else:
- binary_sensor.template.publish:
id: template_sw1
state: ON
on_multi_click:
- timing:
- ON for at most 1s
- OFF for at most 1s
- ON for at most 1s
then:
- binary_sensor.template.publish:
id: template_sw2
state: OFF # <<< how to toggle status?
- timing:
- OFF for at most 1s
- ON for at most 1s
- OFF for at most 1s
then:
- binary_sensor.template.publish:
id: template_sw2
state: OFF # <<< how to toggle status?
# Virtual switches
- platform: template
name: "Kitchen counter LED switch"
id: template_sw1
- platform: template
name: "Kitchen cabinets LED switch"
id: template_sw2
I came across a few problems, I couldn’t figure out.
First is probably very easy - how to set default states for the virtual switches? When I power the device, it reports to HA like this:
Kitchen cabinets LED switch - status Unknown
Kitchen counter LED switch - status On
I would like both sensors to start with an OFF status on boot.
The other question is how to ‘toggle’ the virtual sensors (see comments in the code)?
Hi, I’m starting to understand the logic of esphome code and I realize now that my previous post had some silly questions. Please disregard them.
I got it all working with the following code:
esphome:
name: i3-kitchen
on_boot:
priority: 600
then:
- binary_sensor.template.publish:
id: template_sw1
state: ON
- binary_sensor.template.publish:
id: template_sw2
state: OFF
esp8266:
board: esp01_1m
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "####################################"
ota:
password: "###############################"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "I3-Kitchen Fallback Hotspot"
password: "##############"
captive_portal:
# Physical wall switch sensor automation
binary_sensor:
- platform: gpio
pin:
number: GPIO12
mode: INPUT
name: i3-kitchen Input 1
id: wallswitch1
internal: true
filters:
- delayed_on_off: 50ms
on_state:
then:
- if:
condition:
lambda: 'return id(template_sw1).state;'
then:
- binary_sensor.template.publish:
id: template_sw1
state: OFF
else:
- binary_sensor.template.publish:
id: template_sw1
state: ON
on_multi_click:
- timing:
- ON for at most 500ms
then:
- if:
condition:
lambda: 'return id(template_sw2).state;'
then:
- binary_sensor.template.publish:
id: template_sw2
state: OFF
else:
- binary_sensor.template.publish:
id: template_sw2
state: ON
- timing:
- OFF for at most 500ms
then:
- if:
condition:
lambda: 'return id(template_sw2).state;'
then:
- binary_sensor.template.publish:
id: template_sw2
state: OFF
else:
- binary_sensor.template.publish:
id: template_sw2
state: ON
# Virtual switches
- platform: template
name: "Kitchen counter LED switch"
id: template_sw1
- platform: template
name: "Kitchen cabinets LED switch"
id: template_sw2
There is just one small issue with the above code. When I quickly flip the wall switch ON->OFF->ON or OFF->ON->OFF, the on_multi_click automation works and it toggles the value of the template_sw2 but it also momentarily changes the value of the template_sw1 which is undesirable behaviour.
Thanks Daryl. Thinking along the same lines, I also tried the below code but the problem is that Esphome will run through all my trigger conditions and trigger all events for all matching conditions. That means a single input event (for example flipping the switch ON/OFF quickly) will not only trigger the intended action under these conditions:
- timing:
- OFF for at most 500ms
- ON for at least 501ms
but it won’t stop there and it will also trigger this one:
- timing:
- ON for at least 501ms
Full code:
binary_sensor:
- platform: gpio
pin:
number: GPIO12
mode: INPUT
name: i3-kitchen Input 1
id: wallswitch1
internal: true
filters:
- delayed_on_off: 50ms
on_multi_click:
- timing:
- ON for at most 500ms
- OFF for at least 501ms
then:
- if:
condition:
lambda: 'return id(template_sw2).state;'
then:
- binary_sensor.template.publish:
id: template_sw2
state: OFF
else:
- binary_sensor.template.publish:
id: template_sw2
state: ON
- timing:
- OFF for at most 500ms
- ON for at least 501ms
then:
- if:
condition:
lambda: 'return id(template_sw2).state;'
then:
- binary_sensor.template.publish:
id: template_sw2
state: OFF
else:
- binary_sensor.template.publish:
id: template_sw2
state: ON
- timing:
- OFF for at least 501ms
then:
- if:
condition:
lambda: 'return id(template_sw1).state;'
then:
- binary_sensor.template.publish:
id: template_sw1
state: OFF
else:
- binary_sensor.template.publish:
id: template_sw1
state: ON
- timing:
- ON for at least 501ms
then:
- if:
condition:
lambda: 'return id(template_sw1).state;'
then:
- binary_sensor.template.publish:
id: template_sw1
state: OFF
else:
- binary_sensor.template.publish:
id: template_sw1
state: ON
I am using this code to make my double click and long click work, but is there a way to have the clicks behave like buttons instead of switches?
Now every time I click the state changes from OFF to ON or vice versa, while I would love to just have the impulse going from OFF to ON and back to OFF.