Button entity is not consistent with switch entity for example

Using ESPHome I created the following interaction between entities:

  1. Pressing a physical button (binary_sensor) will trigger a button entity to be pressed
on_click:
   button.press:...
  1. When the button entity is pressed (by the binary_sensor OR by Home Assistant button entity) a switch will toggle
on_press:
   switch.toggle:...

So in the end you have 3 methods to toggle the switch:

  1. Via the physical button connected to a GPIO that controls the binary_sensor
  2. Via the button entity in the Home Assistant dashboard
  3. Via Home Assistant dashboard directly.

Why is it though that pressing the physical button does not register a press event of the button entity in Home Assistant?

To put it as an example:
If I implemented a switch on ESPHome that changed state with every physical button press, I would only need one entity to trigger automations.

Instead if I want to use buttons i.e. momentary/stateless entities I need two entities to trigger automations.

  • one that comes from the binary_sensor of the physical “button” and
  • one from the button entity which will be the virtual “button”

Here is the code if my point is not clear:

binary_sensor:
  # Physical button 
  - platform: gpio
    internal: true
    pin:
      number: D2
      mode: INPUT_PULLUP
      inverted: true
    name: "GPIO Button"
    icon: mdi:gesture-tap
    on_click:
        - button.press: button_1

button:
  # Button to control switch  
  - platform: template
    internal: false
    name: "Button Press"
    id: button_1
    icon: mdi:gesture-tap-button
    on_press:
      - switch.toggle: switch_1

switch:
  - platform: template
    name: "Switch_SP"
    internal: false
    id: switch_1
    optimistic: true
    entity_category: ''
    icon: mdi:toggle-switch
    restore_state: true

You can remove the button config and change button.press: button_1 to switch.toggle in the binary sensor. In Ha a button card can now call a service, so set the card to toggle the light. Same functionality, one less entity.

I actually want to keep the buttons only and remove the switches.
The idea is that I want to be able to use e.g. short and long press to trigger different actions.

If I publish the below binary sensor, I will be able to see when the physical button has been pressed and then released and probably determine if this was a short or long press inside HA.
This is silly since ESPHome already does it.

binary_sensor:
  # Physical button 
  - platform: gpio
    internal: true
    pin:
      number: D2
      mode: INPUT_PULLUP
      inverted: true
    name: "GPIO Button"
    icon: mdi:gesture-tap
    on_click:
      # Define short press behaviour
    - min_length: 100ms
      max_length: 350ms
      then:
        - button.press: button_1
      # Define long press behaviour
    - min_length: 500ms
      max_length: 10000ms
      then:
        - button.press: button_2
    on_double_click:
      # Define double press behaviour
        - button.press: button_3

Now toggling switches is not ideal for two reasons.

  • The state means nothing so I don’t want to see it.
  • I only want to see the occasional “pressed” state from the button as if use a switch when the switch becomes unavailable then the state of the switch will switch to unavailable and then to on or off when it recovers which will still trigger an automation.
    That is because, since I don’t care about the state, my automation triggers at every change of the state. I can filter out potentially unwanted transitions but
  • I am not sure how to do it in Node-RED where I have all my automations
  • it will require a bunch of filters which I could do without if the button entity worked in a similar way to the switch.

So the point of my post is not to find a workaround but to raise the inconsistency and hope that maybe the developers take notice. Should it there be no technical limitation maybe they can update the behaviour.

The binary sensor switch will output what you tell it to. There are two other triggers available on_press and on_release. They would each send a unique event to HA.

Having the binary sensor turn on/off a template switch should give the attribute time since last changed i.e. short/long press.

However if your trying to catch a 200ms interval, you’re better off doing that on the esp.

In node red the bottom of the event state node, there is 1/2 dozen check boxes that will cover unavailable, unknown etc.
image

Buttons are designed to be one-way interaction from Home Assistant to an integration (ESPHome in this case), to have something happen on a device based on an action in Home Assistant, not the other way around. If you trigger the button press from ESPHome itself, that doesn’t get communicated back to Home Assistant. This is a fundamental property of the button entity type in Home Assistant, ESPHome can’t do anything about this.

If you want to do something in Home Assistant based on an action in ESPHome, you shouldn’t be using a button. Instead, trigger a Home Assistant event using the homeassistant.event action, and make your automations start based on that event.

1 Like

I see. So good news is that it is not as if I am doing something wrong but rather it is not meant to do that.

Thanks for the hint. I looked for it and found this complete example: ESPHome buttons - #10 by CiBi69