home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
71.75k stars 30k forks source link

SmartThings integration does not differentiate which button was pressed for multi-tap or multi-button devices #22337

Closed clboles closed 5 years ago

clboles commented 5 years ago

Home Assistant release with the issue:

Home Assistant 0.90.1

Last working Home Assistant release (if known):

Operating environment (Hass.io/Docker/Windows/etc.):

Ubuntu 18.04, Docker

Component/platform:

https://www.home-assistant.io/components/smartthings/

Description of problem: Multi-button devices (ex: Homeseer HS-WD200+, HS-FC200+, Hank Four Button Z-Wave Controller, etc) that support sending different button number (id) based on the number of presses are showing up in the new SmartThings integration as the same button press. The additional data that denotes which button was pressed is missing. This prevents event handling from determining which button was tapped (ex: differentiating between double tap up, triple tap down, etc).

The debug output shows:

2019-03-23 22:31:09 DEBUG (MainThread) [homeassistant.components.smartthings] Fired button event: {'component_id': 'main', 'device_id': '****----****', 'location_id': '****----****', 'value': 'pushed', 'name': 'Master Ceiling Light', 'data': None}

I was able to pass the button number when using the MQTT Bridge approach by altering the smart app inputHandler to include data.buttonNumber in the event. Hopefully you can do something similar to support pulling in the correct button number for these devices.

        // If we're dealing with a button (even a single button device),
        // it's pretty likely that the data contains a buttonNumber specifying which button
        def name = null
        if (evt.name == "button") {
            def data = parseJson(evt.data)
            name = "${evt.name}/${data.buttonNumber}"
        }
        else {
            name = evt.name
        }

Problem-relevant configuration.yaml entries and (fill out even if it seems unimportant): N/A

Traceback (if applicable): N/A

Additional information:

andrewsayre commented 5 years ago

Unfortunately, this is not a bug, but how the API works. The button capability does not define data for the button attribute and anything populated by device type handlers gets removed when it passes through the webhooks (events) or REST API by design.

I have an open ticket with SmartThings asking that they either removing the filter for data or add the common elements (like buttonNumber) to the capability definition, like lock.

The workaround is to modify the device type handler to create a child device for each button, then raise the events from those devices, which then changes the component_id to the name of the child device, allowing button presses to be differentiated.

clboles commented 5 years ago

Thank you for the additional info. It looks like the button value enum is set up to support devices like the Homeseer HS-WD200+. Although the device handler always sends "pushed" right now, perhaps I'll be able to tweak it to properly send "up_2x", "down_3x", etc.

For devices with separate buttons like the Hank four button controller, I'll look into the child device workaround.

Thanks for the SmartThings integration. While the MQTT bridge has been working well for me, this integration has allowed things like my washer and dryer to start working in HA as well.

andrewsayre commented 5 years ago

Yeah that's another approach if it fits into the enum values. Just note that it you have to send one of those enum values exactly or it too will get filtered out. :)

clboles commented 5 years ago

To close the loop for future readers, tweaking the HS-WD200+ device handler to send up/down values from the button value enum works properly. This is a good fit for the HomeSeer devices since it maps cleanly to their operation (up to 5-tap up/down). It's not as good of a match for true multi-button scene controllers (ex: Hank four button), so I probably won't use this approach for those.

Here's how it looks in HA:

2019-03-24 10:07:33 DEBUG (MainThread) [homeassistant.components.smartthings] Fired button event: {'component_id': 'main', 'device_id': '********-****-****-****-************', 'location_id': '********-****-****-****-************', 'value': 'up_2x', 'name': 'Breakfast Cans', 'data': None}

And here's the button event in Node-RED, showing the value making it through for automation.

{
    "event_type":"smartthings.button",
    "topic":"smartthings.button",
    "payload":
    {
        "event_type":"smartthings.button",
        "event":
        {
            "component_id":"main",
            "device_id":"********-****-****-****-************",
            "location_id":"********-****-****-****-************",
            "value":"up_2x",
            "name":"Breakfast Cans",
            "data":null
        }
    },
    "_msgid":"********.*****"
}
rpatterson commented 5 years ago

This also affects the Sylvania/OSRAM Lightify Dimmer Switch which has two buttons. Can you post the link to the SmartThings ticket you opened, @andrewsayre? I'd love to weigh in there, this would be much easier if the ST button event data were just passed through.

I rely heavily on these switches/buttons in my rented apartment in an old building with no access to the breaker. I've not found any other smart switch which covers the existing physical switch and works nearly as well as these. So I may tackle hacking the ST device handler to treat each button as a child device. Any references for that?