From 4342d7aa17d4cbcda47114cd9007126a1c7713cb Mon Sep 17 00:00:00 2001 From: Adam Mills Date: Sat, 7 Oct 2017 16:13:32 -0400 Subject: [PATCH] Event trigger nested conditions (#9732) * Test to supported nested event triggers * Update event trigger to allow nested data tests --- homeassistant/components/automation/event.py | 26 +++++++++++------- tests/components/automation/test_event.py | 28 ++++++++++++++++++++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/automation/event.py b/homeassistant/components/automation/event.py index 32d2d245bef..90baeaded14 100644 --- a/homeassistant/components/automation/event.py +++ b/homeassistant/components/automation/event.py @@ -21,7 +21,7 @@ _LOGGER = logging.getLogger(__name__) TRIGGER_SCHEMA = vol.Schema({ vol.Required(CONF_PLATFORM): 'event', vol.Required(CONF_EVENT_TYPE): cv.string, - vol.Optional(CONF_EVENT_DATA): dict, + vol.Optional(CONF_EVENT_DATA, default={}): dict, }) @@ -29,18 +29,24 @@ TRIGGER_SCHEMA = vol.Schema({ def async_trigger(hass, config, action): """Listen for events based on configuration.""" event_type = config.get(CONF_EVENT_TYPE) - event_data = config.get(CONF_EVENT_DATA) + event_data_schema = vol.Schema( + config.get(CONF_EVENT_DATA), + extra=vol.ALLOW_EXTRA) @callback def handle_event(event): """Listen for events and calls the action when data matches.""" - if not event_data or all(val == event.data.get(key) for key, val - in event_data.items()): - hass.async_run_job(action, { - 'trigger': { - 'platform': 'event', - 'event': event, - }, - }) + try: + event_data_schema(event.data) + except vol.Invalid: + # If event data doesn't match requested schema, skip event + return + + hass.async_run_job(action, { + 'trigger': { + 'platform': 'event', + 'event': event, + }, + }) return hass.bus.async_listen(event_type, handle_event) diff --git a/tests/components/automation/test_event.py b/tests/components/automation/test_event.py index b4686650057..bde34f7fb9f 100644 --- a/tests/components/automation/test_event.py +++ b/tests/components/automation/test_event.py @@ -74,6 +74,34 @@ class TestAutomationEvent(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) + def test_if_fires_on_event_with_nested_data(self): + """Test the firing of events with nested data.""" + assert setup_component(self.hass, automation.DOMAIN, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + 'event_data': { + 'parent_attr': { + 'some_attr': 'some_value' + } + } + }, + 'action': { + 'service': 'test.automation', + } + } + }) + + self.hass.bus.fire('test_event', { + 'parent_attr': { + 'some_attr': 'some_value', + 'another': 'value' + } + }) + self.hass.block_till_done() + self.assertEqual(1, len(self.calls)) + def test_if_not_fires_if_event_data_not_matches(self): """Test firing of event if no match.""" assert setup_component(self.hass, automation.DOMAIN, {