From eb37668036519365715b49c2cedace5f2d722b10 Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Thu, 23 Dec 2021 14:24:37 +0100 Subject: [PATCH] Fix Hue button events (#62669) --- homeassistant/components/hue/v2/hue_event.py | 24 +++++++++++++++++-- .../components/hue/test_device_trigger_v2.py | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/hue/v2/hue_event.py b/homeassistant/components/hue/v2/hue_event.py index 86dabc26660..496507aff4d 100644 --- a/homeassistant/components/hue/v2/hue_event.py +++ b/homeassistant/components/hue/v2/hue_event.py @@ -4,7 +4,7 @@ from typing import TYPE_CHECKING from aiohue.v2 import HueBridgeV2 from aiohue.v2.controllers.events import EventType -from aiohue.v2.models.button import Button +from aiohue.v2.models.button import Button, ButtonEvent from homeassistant.const import CONF_DEVICE_ID, CONF_ID, CONF_TYPE, CONF_UNIQUE_ID from homeassistant.core import callback @@ -27,6 +27,11 @@ async def async_setup_hue_events(bridge: "HueBridge"): api: HueBridgeV2 = bridge.api # to satisfy typing conf_entry = bridge.config_entry dev_reg = device_registry.async_get(hass) + last_state = { + x.id: x.button.last_event + for x in api.sensors.button.items + if x.button is not None + } # at this time the `button` resource is the only source of hue events btn_controller = api.sensors.button @@ -35,6 +40,21 @@ async def async_setup_hue_events(bridge: "HueBridge"): def handle_button_event(evt_type: EventType, hue_resource: Button) -> None: """Handle event from Hue devices controller.""" LOGGER.debug("Received button event: %s", hue_resource) + + # guard for missing button object on the resource + if hue_resource.button is None: + return + + cur_event = hue_resource.button.last_event + last_event = last_state.get(hue_resource.id) + # ignore the event if the last_event value is exactly the same + # this may happen if some other metadata of the button resource is adjusted + if cur_event == last_event: + return + if cur_event != ButtonEvent.REPEAT: + # do not store repeat event + last_state[hue_resource.id] = cur_event + hue_device = btn_controller.get_device(hue_resource.id) device = dev_reg.async_get_device({(DOMAIN, hue_device.id)}) @@ -44,7 +64,7 @@ async def async_setup_hue_events(bridge: "HueBridge"): CONF_ID: slugify(f"{hue_device.metadata.name}: Button"), CONF_DEVICE_ID: device.id, # type: ignore CONF_UNIQUE_ID: hue_resource.id, - CONF_TYPE: hue_resource.button.last_event.value, + CONF_TYPE: cur_event.value, CONF_SUBTYPE: hue_resource.metadata.control_id, } hass.bus.async_fire(ATTR_HUE_EVENT, data) diff --git a/tests/components/hue/test_device_trigger_v2.py b/tests/components/hue/test_device_trigger_v2.py index e6de70d12cb..a5e60b965fd 100644 --- a/tests/components/hue/test_device_trigger_v2.py +++ b/tests/components/hue/test_device_trigger_v2.py @@ -26,7 +26,7 @@ async def test_hue_event(hass, mock_bridge_v2, v2_resources_test_data): # Emit button update event btn_event = { - "button": {"last_event": "short_release"}, + "button": {"last_event": "initial_press"}, "id": "c658d3d8-a013-4b81-8ac6-78b248537e70", "metadata": {"control_id": 1}, "type": "button",