From 434b4dfa583037c755cbf86f53465941329f6fc9 Mon Sep 17 00:00:00 2001 From: Robert Svensson Date: Fri, 5 Feb 2021 23:07:12 +0100 Subject: [PATCH] Improve deCONZ logbook to be more robust in different situations (#46063) --- homeassistant/components/deconz/logbook.py | 38 ++++++++++--- tests/components/deconz/test_logbook.py | 62 ++++++++++++++++++++++ 2 files changed, 93 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/deconz/logbook.py b/homeassistant/components/deconz/logbook.py index 73c157ac8f6..85982244364 100644 --- a/homeassistant/components/deconz/logbook.py +++ b/homeassistant/components/deconz/logbook.py @@ -6,7 +6,7 @@ from homeassistant.const import ATTR_DEVICE_ID, CONF_EVENT from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.event import Event -from .const import DOMAIN as DECONZ_DOMAIN +from .const import CONF_GESTURE, DOMAIN as DECONZ_DOMAIN from .deconz_event import CONF_DECONZ_EVENT, DeconzEvent from .device_trigger import ( CONF_BOTH_BUTTONS, @@ -107,8 +107,12 @@ def _get_device_event_description(modelid: str, event: str) -> tuple: device_event_descriptions: dict = REMOTES[modelid] for event_type_tuple, event_dict in device_event_descriptions.items(): - if event == event_dict[CONF_EVENT]: + if event == event_dict.get(CONF_EVENT): return event_type_tuple + if event == event_dict.get(CONF_GESTURE): + return event_type_tuple + + return (None, None) @callback @@ -125,15 +129,35 @@ def async_describe_events( hass, event.data[ATTR_DEVICE_ID] ) - if deconz_event.device.modelid not in REMOTES: + action = None + interface = None + data = event.data.get(CONF_EVENT) or event.data.get(CONF_GESTURE, "") + + if data and deconz_event.device.modelid in REMOTES: + action, interface = _get_device_event_description( + deconz_event.device.modelid, data + ) + + # Unknown event + if not data: return { "name": f"{deconz_event.device.name}", - "message": f"fired event '{event.data[CONF_EVENT]}'.", + "message": "fired an unknown event.", } - action, interface = _get_device_event_description( - deconz_event.device.modelid, event.data[CONF_EVENT] - ) + # No device event match + if not action: + return { + "name": f"{deconz_event.device.name}", + "message": f"fired event '{data}'.", + } + + # Gesture event + if not interface: + return { + "name": f"{deconz_event.device.name}", + "message": f"fired event '{ACTIONS[action]}'.", + } return { "name": f"{deconz_event.device.name}", diff --git a/tests/components/deconz/test_logbook.py b/tests/components/deconz/test_logbook.py index 7315a766d5c..500ca03b7ed 100644 --- a/tests/components/deconz/test_logbook.py +++ b/tests/components/deconz/test_logbook.py @@ -3,6 +3,7 @@ from copy import deepcopy from homeassistant.components import logbook +from homeassistant.components.deconz.const import CONF_GESTURE from homeassistant.components.deconz.deconz_event import CONF_DECONZ_EVENT from homeassistant.components.deconz.gateway import get_gateway_from_config_entry from homeassistant.const import CONF_DEVICE_ID, CONF_EVENT, CONF_ID, CONF_UNIQUE_ID @@ -34,6 +35,23 @@ async def test_humanifying_deconz_event(hass): "config": {}, "uniqueid": "00:00:00:00:00:00:00:02-00", }, + "2": { + "id": "Xiaomi cube id", + "name": "Xiaomi cube", + "type": "ZHASwitch", + "modelid": "lumi.sensor_cube", + "state": {"buttonevent": 1000, "gesture": 1}, + "config": {}, + "uniqueid": "00:00:00:00:00:00:00:03-00", + }, + "3": { + "id": "faulty", + "name": "Faulty event", + "type": "ZHASwitch", + "state": {}, + "config": {}, + "uniqueid": "00:00:00:00:00:00:00:04-00", + }, } config_entry = await setup_deconz_integration(hass, get_state_response=data) gateway = get_gateway_from_config_entry(hass, config_entry) @@ -46,6 +64,7 @@ async def test_humanifying_deconz_event(hass): logbook.humanify( hass, [ + # Event without matching device trigger MockLazyEventPartialState( CONF_DECONZ_EVENT, { @@ -55,6 +74,7 @@ async def test_humanifying_deconz_event(hass): CONF_UNIQUE_ID: gateway.events[0].serial, }, ), + # Event with matching device trigger MockLazyEventPartialState( CONF_DECONZ_EVENT, { @@ -64,6 +84,36 @@ async def test_humanifying_deconz_event(hass): CONF_UNIQUE_ID: gateway.events[1].serial, }, ), + # Gesture with matching device trigger + MockLazyEventPartialState( + CONF_DECONZ_EVENT, + { + CONF_DEVICE_ID: gateway.events[2].device_id, + CONF_GESTURE: 1, + CONF_ID: gateway.events[2].event_id, + CONF_UNIQUE_ID: gateway.events[2].serial, + }, + ), + # Unsupported device trigger + MockLazyEventPartialState( + CONF_DECONZ_EVENT, + { + CONF_DEVICE_ID: gateway.events[2].device_id, + CONF_GESTURE: "unsupported_gesture", + CONF_ID: gateway.events[2].event_id, + CONF_UNIQUE_ID: gateway.events[2].serial, + }, + ), + # Unknown event + MockLazyEventPartialState( + CONF_DECONZ_EVENT, + { + CONF_DEVICE_ID: gateway.events[3].device_id, + "unknown_event": None, + CONF_ID: gateway.events[3].event_id, + CONF_UNIQUE_ID: gateway.events[3].serial, + }, + ), ], entity_attr_cache, {}, @@ -77,3 +127,15 @@ async def test_humanifying_deconz_event(hass): assert events[1]["name"] == "Hue remote" assert events[1]["domain"] == "deconz" assert events[1]["message"] == "'Long press' event for 'Dim up' was fired." + + assert events[2]["name"] == "Xiaomi cube" + assert events[2]["domain"] == "deconz" + assert events[2]["message"] == "fired event 'Shake'." + + assert events[3]["name"] == "Xiaomi cube" + assert events[3]["domain"] == "deconz" + assert events[3]["message"] == "fired event 'unsupported_gesture'." + + assert events[4]["name"] == "Faulty event" + assert events[4]["domain"] == "deconz" + assert events[4]["message"] == "fired an unknown event."