esphome / feature-requests

ESPHome Feature Request Tracker
https://esphome.io/
404 stars 26 forks source link

"Device Trigger" entity #2614

Open Nick2253 opened 4 months ago

Nick2253 commented 4 months ago

Describe the problem you have/What new integration you would like

The MQTT integration defines a "Device Trigger" sensor. This is really useful for buttons, controls, etc.

ESPHome does not support this kind of sensor. Instead, in ESPHome, the documentation seems to suggest that a binary_sensor is the "correct" way to do this, but it's not always convenient, depending on the exact hardware.

In my case, I have a TOPGREENER TGWFSC8 Scene Controller, which has a Tuya MCU which manages the button presses. The Tuya MCU only reports a datapoint when a button is pressed, but does not change the reported value. Since it doesn't report the value, I can't easily use the Tuya Binary Sensor component to capture this press.

As it exists today, the only way to convert these datapoints into sensors is to use binary sensors coupled with the on_datapoint_update parameter, which turns into a mountain of configuration. (See at the end for an example of this config code.) I have to initialize the binary sensors, set on_boot triggers that switch each binary sensor to off, and then create on_datapoint_update actions that, for each datapoint, set the corresponding binary sensor to true, delay 0.2s, and then set it to false.

Please describe your use case for this integration and alternatives you've tried:

If there was some kind of "Device Trigger" sensor, then I could easily use this to capture these datapoints (button presses) and forward them on to Home Assistant.

For any hardware where pressing a physical button is a primary use, then a "device trigger" would make it much easier and more consistent.

Right now, the use of binary_sensor isn't always appropriate for capturing a button press. Within Home Assistant, among the dozens of device classes for binary sensors, not a single one is directly comparable to a button. Per the documentation, binary sensors are for capturing "states and conditions", while buttons are really more about sending an "event" or "trigger".

Additional context

My Example ESPHome Config showing how I used binary sensors to capture the data points.

esphome:
  name: projector-scene-controller
  platform: ESP8266
  board: esp01_1m

  #Initialize Template Sensors
  # Initialize sensors on boot
  on_boot:
    then:
      - binary_sensor.template.publish:
          id: psc_button_1
          state: OFF
      - binary_sensor.template.publish:
          id: psc_button_1_x2
          state: OFF
      - binary_sensor.template.publish:
          id: psc_button_2
          state: OFF
      - binary_sensor.template.publish:
          id: psc_button_2_x2
          state: OFF
      - binary_sensor.template.publish:
          id: psc_button_3
          state: OFF
      - binary_sensor.template.publish:
          id: psc_button_3_x2
          state: OFF
      - binary_sensor.template.publish:
          id: psc_button_4
          state: OFF
      - binary_sensor.template.publish:
          id: psc_button_4_x2
          state: OFF
      - binary_sensor.template.publish:
          id: psc_button_5
          state: OFF
      - binary_sensor.template.publish:
          id: psc_button_5_x2
          state: OFF
      - binary_sensor.template.publish:
          id: psc_button_6
          state: OFF
      - binary_sensor.template.publish:
          id: psc_button_6_x2
          state: OFF
      - binary_sensor.template.publish:
          id: psc_button_7
          state: OFF
      - binary_sensor.template.publish:
          id: psc_button_7_x2
          state: OFF

# Enable logging
# Make sure logging is not using the serial port
logger:
  baud_rate: 0

# Enable Home Assistant API
api:
  encryption:
    key: xxx

ota:
  password: !secret esphome_ota_pass

wifi:
  ssid: !secret iot_ssid
  password: !secret iot_pass

  # Set Static IP Address
  manual_ip:
    static_ip:  x
    gateway: x
    subnet: x

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Projector-Scene-Controller"
    password: xxx

captive_portal:

# Basic Sensors
text_sensor:
  - platform: wifi_info
    ip_address:
      name: Scene Controller ESP IP Address

binary_sensor:
  - platform: status
    name: Projector Scene Controller ESP Status

## Tuya Sensors
  - platform: template
    name: "Projector Scene Controller Button 1"
    id: psc_button_1
  - platform: template
    name: "Projector Scene Controller Button 1 Double"
    id: psc_button_1_x2
  - platform: template
    name: "Projector Scene Controller Button 2"
    id: psc_button_2
  - platform: template
    name: "Projector Scene Controller Button 2 Double"
    id: psc_button_2_x2
  - platform: template
    name: "Projector Scene Controller Button 3"
    id: psc_button_3
  - platform: template
    name: "Projector Scene Controller Button 3 Double"
    id: psc_button_3_x2
  - platform: template
    name: "Projector Scene Controller Button 4"
    id: psc_button_4
  - platform: template
    name: "Projector Scene Controller Button 4 Double"
    id: psc_button_4_x2
  - platform: template
    name: "Projector Scene Controller Button 5"
    id: psc_button_5
  - platform: template
    name: "Projector Scene Controller Button 5 Double"
    id: psc_button_5_x2
  - platform: template
    name: "Projector Scene Controller Button 6"
    id: psc_button_6
  - platform: template
    name: "Projector Scene Controller Button 6 Double"
    id: psc_button_6_x2
  - platform: template
    name: "Projector Scene Controller Button 7"
    id: psc_button_7
  - platform: template
    name: "Projector Scene Controller Button 7 Double"
    id: psc_button_7_x2

switch:
  - platform: tuya
    name: "Projector Scene Controller Relay"
    switch_datapoint: 1

# TuYa Setup

# UART Config
uart:
  rx_pin: GPIO3
  tx_pin: GPIO1
  baud_rate: 9600

# Register the Tuya MCU connection
tuya:
  on_datapoint_update:
    - sensor_datapoint: 101
      datapoint_type: any
      then:
        - binary_sensor.template.publish:
            id: psc_button_1
            state: ON
        - delay: 0.2s
        - binary_sensor.template.publish:
            id: psc_button_1
            state: OFF
    - sensor_datapoint: 108
      datapoint_type: any
      then:
        - binary_sensor.template.publish:
            id: psc_button_1_x2
            state: ON
        - delay: 0.2s
        - binary_sensor.template.publish:
            id: psc_button_1_x2
            state: OFF
    - sensor_datapoint: 102
      datapoint_type: any
      then:
        - binary_sensor.template.publish:
            id: psc_button_2
            state: ON
        - delay: 0.2s
        - binary_sensor.template.publish:
            id: psc_button_2
            state: OFF
    - sensor_datapoint: 109
      datapoint_type: any
      then:
        - binary_sensor.template.publish:
            id: psc_button_2_x2
            state: ON
        - delay: 0.2s
        - binary_sensor.template.publish:
            id: psc_button_2_x2
            state: OFF
    - sensor_datapoint: 103
      datapoint_type: any
      then:
        - binary_sensor.template.publish:
            id: psc_button_3
            state: ON
        - delay: 0.2s
        - binary_sensor.template.publish:
            id: psc_button_3
            state: OFF
    - sensor_datapoint: 110
      datapoint_type: any
      then:
        - binary_sensor.template.publish:
            id: psc_button_3_x2
            state: ON
        - delay: 0.2s
        - binary_sensor.template.publish:
            id: psc_button_3_x2
            state: OFF
    - sensor_datapoint: 104
      datapoint_type: any
      then:
        - binary_sensor.template.publish:
            id: psc_button_4
            state: ON
        - delay: 0.2s
        - binary_sensor.template.publish:
            id: psc_button_4
            state: OFF
    - sensor_datapoint: 111
      datapoint_type: any
      then:
        - binary_sensor.template.publish:
            id: psc_button_4_x2
            state: ON
        - delay: 0.2s
        - binary_sensor.template.publish:
            id: psc_button_4_x2
            state: OFF
    - sensor_datapoint: 105
      datapoint_type: any
      then:
        - binary_sensor.template.publish:
            id: psc_button_5
            state: ON
        - delay: 0.2s
        - binary_sensor.template.publish:
            id: psc_button_5
            state: OFF
    - sensor_datapoint: 112
      datapoint_type: any
      then:
        - binary_sensor.template.publish:
            id: psc_button_5_x2
            state: ON
        - delay: 0.2s
        - binary_sensor.template.publish:
            id: psc_button_5_x2
            state: OFF
    - sensor_datapoint: 106
      datapoint_type: any
      then:
        - binary_sensor.template.publish:
            id: psc_button_6
            state: ON
        - delay: 0.2s
        - binary_sensor.template.publish:
            id: psc_button_6
            state: OFF
    - sensor_datapoint: 113
      datapoint_type: any
      then:
        - binary_sensor.template.publish:
            id: psc_button_6_x2
            state: ON
        - delay: 0.2s
        - binary_sensor.template.publish:
            id: psc_button_6_x2
            state: OFF
    - sensor_datapoint: 107
      datapoint_type: any
      then:
        - binary_sensor.template.publish:
            id: psc_button_7
            state: ON
        - delay: 0.2s
        - binary_sensor.template.publish:
            id: psc_button_7
            state: OFF
    - sensor_datapoint: 114
      datapoint_type: any
      then:
        - binary_sensor.template.publish:
            id: psc_button_7_x2
            state: ON
        - delay: 0.2s
        - binary_sensor.template.publish:
            id: psc_button_7_x2
            state: OFF
ssieb commented 4 months ago

If your goal is for HA to receive events, then why not just use the api event action to send them directly instead of creating lots of extra unnecessary components?

Nick2253 commented 4 months ago

There are a couple reason why events are not desirable.

First off, Home Assistant doesn't really have a "registry" for events in the same way it does for devices or entities. What this means is that, if I want to do anything with devices or entities, it's really easy. Home Assistant allows me to browse through these, search for them, and see historical data. As well, when I add automations, scenes, or scripts with a device or entity, they are collected in the corresponding device page, which makes it really easy to manage.

On the other hand, with events, there's significantly less structure. This makes events very powerful, for sure, but you lose many of the benefits of the structure that comes from devices and entities. Furthermore, without knowing the exact event type, you can't really "find" the event in Home Assistant. As an example, many times, while I'm in the process of working on an automation, I can't remember the exact name of a device or entity. However, it's easy to search within the UI's of Home Assistant and find those. It's significantly more difficult with events.

The second major reason is for parity with the MQTT integration. "Device Triggers" work so well for my Zigbee buttons that it feels like a hack to use anything else. Considering that ESPHome should be more powerful than the MQTT system, it seems like an oversight that something as simple as a Device Trigger doesn't exist.

And lastly (and I'll definitely grant that this is my subjective feelings here), it just Feels Right™. The buttons are clearly physical things, so they should interface as devices/entity ids, like every other piece of physical hardware does.

ssieb commented 4 months ago

I don't understand what you're asking for. You're comparing to an integration in HA. What are you expecting esphome to do?

Nick2253 commented 4 months ago

I don't understand what you're asking for.

Then you'll have to forgive me, since I'm not sure how to be more clear. Let me try to answer these questions, and hopefully that context will help.

You're comparing to an integration in HA.

First off, isn't ESPHome also an integration in Home Assistant? I mean, the very first link in "Getting Started" on the ESPHome front page is to Getting Started with ESPHome and Home Assistant.

I understand from a technical perspective the difference between the ESPHome code that runs on an ESP device, the ESPHome Addon which powers that, and the ESPHome integration that connects the data to Home Assistant. However, making a change to one of those in isolation doesn't really make sense. And since Home Assistant appears to be the primary integration project for ESPHome, it seems appropriate to ask for features for that pipeline that improve the Home Assistant experience.

If I'm off-base on that, then point me to the right place to get my features implemented, and I'll go bug whoever you point me to. But my understanding is that, until changes are made to ESPHome, then it doesn't matter what changes I can request (or make myself) to the ESPHome HA integration.

What are you expecting esphome to do?

Maybe a specific example will help:

Right now, if you were to use have a Tuya button on an ESP device, your config code might look like:

binary_sensor:
  - platform: 'tuya'
    sensor_datapoint: 1
    name: "My Button"

This config will create an entity in Home Assistant binary_sensor.my_button. (However, such an entity would be set to whatever the "sensor_datapoint" payload's value is, and many tuya MCUs don't provide value data, making this kind of sensor worthless.)

I want to be able to have this in my configuration:

device_trigger:
  - platform: 'tuya'
    sensor_datapoint: 1
    name: "My Button"

This config should create an entity in Home Assistant like sensor.my_button with the properties of a device trigger, just how it is done via the MQTT integration. And in my example, this would trigger any time the sensor_datapoint comes through, no matter what its payload's value is.

ssieb commented 4 months ago

Ok, this is a feature request, but it's unlikely to be implemented. This is what events are for.

luca-iodice commented 4 months ago

I agree that this feature should be implemented. I think the best way could be to implement Home assistant's event entities. There are already two feature requests about this issue, because as you said, events are not tracked by home assistant

Nick2253 commented 4 months ago

Yes, event entities would definitely be a good way to solve this.

Related: #2433