ESPHome buttons

Hello everyone,

I need to setup a group of buttons, driven by an ESP32 programmed with ESPHome.

I already figured out the simple part, I setup the esp32 pins as binary sensors that actually do nothing, and the HA checks for the binary sensors state to trigger the automation, but I would love to have these buttons do different things reacting to click, double click or hold actions.

I know that ESPHome can already detect these with the multi_click option, but at this stage of the project I would like the device to send HA what happened and let HA act on that without hardcoding the ESPhome device with the action, so the question is, since the binary sensor is on the esphome, how do I communicate HA what happened to the sensor ?

Thanks in advance for any hint.

Ciao
Claudio

3 Likes

I think with a lambda and publish_state https://esphome.io/components/binary_sensor/index.html#lambda-calls

Thank you,

but doesnā€™t a binary state only have two states, or is it just a label I can change ?

Ciao

Claudio

Recently wrote something that supports short and long presses of esphome buttons handled by hass.
You can check it out here and maybe work from there?

Right now i cant think of how you could implement double-clicks but if i think of something ill let you know :slight_smile:

edit: maybe have each short click add +1 to a variable, and at the end of the first press start a ~2sec timer. At the end of the timer check the value of the variable, clear the variable and act accordingly?
Or perhaps im overthinking it and thereā€™s a simpler way :slight_smile:

Hello Harry,

thank you, I would like to keep the short , long or double click handling on the esphome, using its built in functions, what Iā€™m looking for is how to send the result of the button action to HA.
when I wasnā€™t using esphome I used mqtt, now Iā€™m looking for some more ā€˜nativeā€™ ways to achieve this, maybe using template or text sensors or something similar, but Iā€™m still investigating , if this doesnā€™t work I will revert the communication to mqtt.

Ciao

Claudio

Ah sorry, I misunderstood.
Hope you figure it out.

BTW, canā€™t you make ā€œdummyā€ binary sensors on the esphome and publish their state to HA through lambdas with the .publish_state(true) thingy?

Iā€™m new to esphome but Iā€™ll keep a eye out

Perhaps you are looking for something along the lines of the following code. Basically, you define the different clicks in the binary sensor, but you perform the actual actions in various template switches. If you define a name: for these switches they will show up in HA and you will be able to fire them there as well. The lambda: bit is how you evaluate what you report to HA as far as the switch status (off or on). Iā€™d have to see the rest of your code to help you more there. What I didnā€™t include in the code below is another switch that controls a relay (id: relay).

If you donā€™t want to perform any action on the ESP, you could use template binary sensors to report back to HA instead of switches in the same way I am with switches. The key to reporting back the state is the lambda section along with defining a name. If you have numeric data you need to report back you would use a template sensor instead of binary sensor or switch.

Hopefully, this makes some sense.

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO0
      inverted: True
    id: button_id
    on_press:
      then:
        - switch.toggle: single_click_switch
    on_double_click:
      then:
        - switch.toggle: double_click_switch

switch:
  - platform: template
    id: single_click_switch
    name: "Single Click Action"
    icon: ${icon}
    lambda: |-
      if (id(relay).state) {
        return true;
      } else {
        return false;
      }
    turn_on_action:
        - switch.turn_on: relay
    turn_off_action:
        - switch.turn_off: relay

  - platform: template
    id: double_click_switch
    name: "Double Click Action"
    lambda: |-
      if (id(relay).state) {
        return true;
      } else {
        return false;
      }
    turn_on_action:
        - switch.turn_on: relay
    turn_off_action:
        - switch.turn_off: relay
2 Likes

I think this functionality is already in esphome through the on-multi-click call:

Never really used it though

If you donā€™t want to perform any action on the ESP, you could use template binary sensors to report back to HA instead of switches in the same way I am with switches.

Hi , youā€™re right, my goal is to have the esphome device handle the local keyboard and just ā€˜tellā€™ HA what to do, Iā€™m doing some testing with template sensors and weā€™ll see.

Thank you

Claudio

Hello everyone,

to close properly the thread, I completed my testing and I came up with the solution

I setup the gpio needed as a binary sensor and I check for actions with the on_multi_click automation, for now I tested single click, double click, long click and hold presses.

I tried the template sensor, but it wasnā€™t suitable for my need, since to work properly I would need to reset the value after each action, and Home Assistant has some issues with this, at least in my tests.

I worked out a good solution using the homessistant.event automation, which simply creates an event in the HA bus, the event id has to begin with esphome. and can have or have not some data in it, I chose to do it, for better readability.
Plus I donā€™t need to create sensors of any kind, and also the binary sensors attached to the GPIOs can be internal to esphome, so there is less communication to and from HA and they donā€™t need to show up in HA dashboard

Anyway now I can fire any automation on HA from the esphome device buttons.

Thank you all for helping out.

Ciao

Claudio


Here is a sample binary sensor setup

  - platform: gpio
    pin:
      number: GPIO25
      mode: INPUT_PULLUP
      inverted: True
    name: "Puls_32_01_25"
    on_multi_click:
    - timing:
      - ON for at most 1s
      - OFF for at most 1s
      - ON for at most 1s
      - OFF for at least 0.2s
      then:
        - logger.log: "Double Clicked"
        - homeassistant.event:
            event: esphome.puls_32_01_25
            data:
              title: dbl_click
    - timing:
      - ON for 1s to 2s
      - OFF for at least 0.5s
      then:
        - logger.log: "Single Long Clicked"
        - homeassistant.event:
            event: esphome.puls_32_01_25
            data:
              title: long_click
    - timing:
      - ON for at least 2.2s
      then:
        - logger.log: "Click and Hold"
        - homeassistant.event:
            event: esphome.puls_32_01_25
            data:
              title: hold
    - timing:
      - ON for at most 1s
      - OFF for at least 0.5s
      then:
        - logger.log: "Single Short Clicked"
        - homeassistant.event:
            event: esphome.puls_32_01_25
            data:
              title: single_click

And here is a sample automation triggered from this custom event:

alias: 'Tastiera Sala TV p1'
trigger:
  - platform: event
    event_type: esphome.puls_32_01_25
    event_data:
      title: dbl_click
action:
  service: script.turn_on
  entity_id: script.hue_scena1

7 Likes

Hi, I have created a cover and I would like to add a double press to the push-button so that when I press the push-button twice it automatically closes the relay for the time set in the cover.

Copy to clipboard

- platform: gpio
  pin:
    number: GPIO16
    mode: INPUT_PULLUP
    inverted: True
  id: ph_button1
  on_press:
  - cover.open: my_cover
  on_release:
  - cover.stop: my_cover
  on_double_click:  
    min_length: 50ms
    max_length: 350ms
    then:
      - cover.open: my_cover

I discovered however that on press is not compatible with dual click. There will however be a lambda way of creating this with Lambda actionsā€¦
ā€¦delays in on_press/on_release and checks before actionā€¦

but I canā€™t use lambda. Can someone help me?

Not sure if you got the solution to this but when I was experimenting with my buttons, I realized that I cant use on_press and on_double_click together. If I do then most (or all) of the times on_press used to get called. on_double_click used to get called only when I commented out on_press.