diff --git a/homeassistant/components/logbook.py b/homeassistant/components/logbook.py index 9100c098413..557c59a33ec 100644 --- a/homeassistant/components/logbook.py +++ b/homeassistant/components/logbook.py @@ -29,15 +29,22 @@ DEPENDENCIES = ['recorder', 'frontend'] _LOGGER = logging.getLogger(__name__) CONF_EXCLUDE = 'exclude' +CONF_INCLUDE = 'include' CONF_ENTITIES = 'entities' CONF_DOMAINS = 'domains' CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ CONF_EXCLUDE: vol.Schema({ - vol.Optional(CONF_ENTITIES, default=[]): cv.ensure_list, - vol.Optional(CONF_DOMAINS, default=[]): cv.ensure_list + vol.Optional(CONF_ENTITIES, default=[]): cv.entity_ids, + vol.Optional(CONF_DOMAINS, default=[]): vol.All(cv.ensure_list, + [cv.string]) }), + CONF_INCLUDE: vol.Schema({ + vol.Optional(CONF_ENTITIES, default=[]): cv.entity_ids, + vol.Optional(CONF_DOMAINS, default=[]): vol.All(cv.ensure_list, + [cv.string]) + }) }), }, extra=vol.ALLOW_EXTRA) @@ -267,12 +274,19 @@ def humanify(events): def _exclude_events(events, config): """Get lists of excluded entities and platforms.""" + # pylint: disable=too-many-branches excluded_entities = [] excluded_domains = [] + included_entities = [] + included_domains = [] exclude = config[DOMAIN].get(CONF_EXCLUDE) if exclude: excluded_entities = exclude[CONF_ENTITIES] excluded_domains = exclude[CONF_DOMAINS] + include = config[DOMAIN].get(CONF_INCLUDE) + if include: + included_entities = include[CONF_ENTITIES] + included_domains = include[CONF_DOMAINS] filtered_events = [] for event in events: @@ -288,11 +302,32 @@ def _exclude_events(events, config): continue domain = to_state.domain - # check if logbook entry is excluded for this domain - if domain in excluded_domains: + entity_id = to_state.entity_id + # filter if only excluded is configured for this domain + if excluded_domains and domain in excluded_domains and \ + not included_domains: + if (included_entities and entity_id not in included_entities) \ + or not included_entities: + continue + # filter if only included is configured for this domain + elif not excluded_domains and included_domains and \ + domain not in included_domains: + if (included_entities and entity_id not in included_entities) \ + or not included_entities: + continue + # filter if included and excluded is configured for this domain + elif excluded_domains and included_domains and \ + (domain not in included_domains or + domain in excluded_domains): + if (included_entities and entity_id not in included_entities) \ + or not included_entities or domain in excluded_domains: + continue + # filter if only included is configured for this entity + elif not excluded_domains and not included_domains and \ + included_entities and entity_id not in included_entities: continue # check if logbook entry is excluded for this entity - if to_state.entity_id in excluded_entities: + if entity_id in excluded_entities: continue filtered_events.append(event) return filtered_events diff --git a/tests/components/test_logbook.py b/tests/components/test_logbook.py index 9e8ab09a5a6..a98273b6521 100644 --- a/tests/components/test_logbook.py +++ b/tests/components/test_logbook.py @@ -186,6 +186,91 @@ class TestComponentLogbook(unittest.TestCase): self.assert_entry(entries[1], pointB, 'blu', domain='sensor', entity_id=entity_id2) + def test_include_events_entity(self): + """Test if events are filtered if entity is included in config.""" + entity_id = 'sensor.bla' + entity_id2 = 'sensor.blu' + pointA = dt_util.utcnow() + pointB = pointA + timedelta(minutes=logbook.GROUP_BY_MINUTES) + + eventA = self.create_state_changed_event(pointA, entity_id, 10) + eventB = self.create_state_changed_event(pointB, entity_id2, 20) + + config = logbook.CONFIG_SCHEMA({ + ha.DOMAIN: {}, + logbook.DOMAIN: {logbook.CONF_INCLUDE: { + logbook.CONF_ENTITIES: [entity_id2, ]}}}) + events = logbook._exclude_events((ha.Event(EVENT_HOMEASSISTANT_STOP), + eventA, eventB), config) + entries = list(logbook.humanify(events)) + + self.assertEqual(2, len(entries)) + self.assert_entry( + entries[0], name='Home Assistant', message='stopped', + domain=ha.DOMAIN) + self.assert_entry( + entries[1], pointB, 'blu', domain='sensor', entity_id=entity_id2) + + def test_include_events_domain(self): + """Test if events are filtered if domain is included in config.""" + entity_id = 'switch.bla' + entity_id2 = 'sensor.blu' + pointA = dt_util.utcnow() + pointB = pointA + timedelta(minutes=logbook.GROUP_BY_MINUTES) + + eventA = self.create_state_changed_event(pointA, entity_id, 10) + eventB = self.create_state_changed_event(pointB, entity_id2, 20) + + config = logbook.CONFIG_SCHEMA({ + ha.DOMAIN: {}, + logbook.DOMAIN: {logbook.CONF_INCLUDE: { + logbook.CONF_DOMAINS: ['sensor', ]}}}) + events = logbook._exclude_events((ha.Event(EVENT_HOMEASSISTANT_START), + eventA, eventB), config) + entries = list(logbook.humanify(events)) + + self.assertEqual(2, len(entries)) + self.assert_entry(entries[0], name='Home Assistant', message='started', + domain=ha.DOMAIN) + self.assert_entry(entries[1], pointB, 'blu', domain='sensor', + entity_id=entity_id2) + + def test_include_exclude_events(self): + """Test if events are filtered if include and exclude is configured.""" + entity_id = 'switch.bla' + entity_id2 = 'sensor.blu' + entity_id3 = 'sensor.bli' + pointA = dt_util.utcnow() + pointB = pointA + timedelta(minutes=logbook.GROUP_BY_MINUTES) + + eventA1 = self.create_state_changed_event(pointA, entity_id, 10) + eventA2 = self.create_state_changed_event(pointA, entity_id2, 10) + eventA3 = self.create_state_changed_event(pointA, entity_id3, 10) + eventB1 = self.create_state_changed_event(pointB, entity_id, 20) + eventB2 = self.create_state_changed_event(pointB, entity_id2, 20) + + config = logbook.CONFIG_SCHEMA({ + ha.DOMAIN: {}, + logbook.DOMAIN: { + logbook.CONF_INCLUDE: { + logbook.CONF_DOMAINS: ['sensor', ], + logbook.CONF_ENTITIES: ['switch.bla', ]}, + logbook.CONF_EXCLUDE: { + logbook.CONF_DOMAINS: ['switch', ], + logbook.CONF_ENTITIES: ['sensor.bli', ]}}}) + events = logbook._exclude_events((ha.Event(EVENT_HOMEASSISTANT_START), + eventA1, eventA2, eventA3, + eventB1, eventB2), config) + entries = list(logbook.humanify(events)) + + self.assertEqual(3, len(entries)) + self.assert_entry(entries[0], name='Home Assistant', message='started', + domain=ha.DOMAIN) + self.assert_entry(entries[1], pointA, 'blu', domain='sensor', + entity_id=entity_id2) + self.assert_entry(entries[2], pointB, 'blu', domain='sensor', + entity_id=entity_id2) + def test_exclude_auto_groups(self): """Test if events of automatically generated groups are filtered.""" entity_id = 'switch.bla'