Skip to content

Commit

Permalink
Merge aa32efc into b8a94c3
Browse files Browse the repository at this point in the history
  • Loading branch information
amelchio committed Mar 1, 2019
2 parents b8a94c3 + aa32efc commit 63f243f
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 103 deletions.
111 changes: 55 additions & 56 deletions homeassistant/components/logbook/__init__.py
Expand Up @@ -146,8 +146,8 @@ async def get(self, request, datetime=None):

def json_events():
"""Fetch events and generate JSON."""
return self.json(list(
_get_events(hass, self.config, start_day, end_day, entity_id)))
return self.json(
_get_events(hass, self.config, start_day, end_day, entity_id))

return await hass.async_add_job(json_events)

Expand Down Expand Up @@ -393,11 +393,17 @@ def _generate_filter_from_config(config):
def _get_events(hass, config, start_day, end_day, entity_id=None):
"""Get events for a period of time."""
from homeassistant.components.recorder.models import Events, States
from homeassistant.components.recorder.util import (
execute, session_scope)
from homeassistant.components.recorder.util import session_scope

entities_filter = _generate_filter_from_config(config)

def yield_events(query):
"""Yield Events that are not filtered away."""
for row in query.yield_per(500):
event = row.to_native()
if _keep_event(event, entities_filter):
yield event

with session_scope(hass=hass) as session:
if entity_id is not None:
entity_ids = [entity_id.lower()]
Expand All @@ -413,77 +419,70 @@ def _get_events(hass, config, start_day, end_day, entity_id=None):
States.entity_id.in_(entity_ids))
| (States.state_id.is_(None)))

events = execute(query)

return humanify(hass, _exclude_events(events, entities_filter))

return list(humanify(hass, yield_events(query)))

def _exclude_events(events, entities_filter):
filtered_events = []
for event in events:
domain, entity_id = None, None

if event.event_type == EVENT_STATE_CHANGED:
entity_id = event.data.get('entity_id')
def _keep_event(event, entities_filter):
domain, entity_id = None, None

if entity_id is None:
continue
if event.event_type == EVENT_STATE_CHANGED:
entity_id = event.data.get('entity_id')

# Do not report on new entities
if event.data.get('old_state') is None:
continue
if entity_id is None:
return False

new_state = event.data.get('new_state')
# Do not report on new entities
if event.data.get('old_state') is None:
return False

# Do not report on entity removal
if not new_state:
continue
new_state = event.data.get('new_state')

attributes = new_state.get('attributes', {})
# Do not report on entity removal
if not new_state:
return False

# If last_changed != last_updated only attributes have changed
# we do not report on that yet.
last_changed = new_state.get('last_changed')
last_updated = new_state.get('last_updated')
if last_changed != last_updated:
continue
attributes = new_state.get('attributes', {})

domain = split_entity_id(entity_id)[0]
# If last_changed != last_updated only attributes have changed
# we do not report on that yet.
last_changed = new_state.get('last_changed')
last_updated = new_state.get('last_updated')
if last_changed != last_updated:
return False

# Also filter auto groups.
if domain == 'group' and attributes.get('auto', False):
continue
domain = split_entity_id(entity_id)[0]

# exclude entities which are customized hidden
hidden = attributes.get(ATTR_HIDDEN, False)
if hidden:
continue
# Also filter auto groups.
if domain == 'group' and attributes.get('auto', False):
return False

elif event.event_type == EVENT_LOGBOOK_ENTRY:
domain = event.data.get(ATTR_DOMAIN)
entity_id = event.data.get(ATTR_ENTITY_ID)
# exclude entities which are customized hidden
hidden = attributes.get(ATTR_HIDDEN, False)
if hidden:
return False

elif event.event_type == EVENT_AUTOMATION_TRIGGERED:
domain = 'automation'
entity_id = event.data.get(ATTR_ENTITY_ID)
elif event.event_type == EVENT_LOGBOOK_ENTRY:
domain = event.data.get(ATTR_DOMAIN)
entity_id = event.data.get(ATTR_ENTITY_ID)

elif event.event_type == EVENT_SCRIPT_STARTED:
domain = 'script'
entity_id = event.data.get(ATTR_ENTITY_ID)
elif event.event_type == EVENT_AUTOMATION_TRIGGERED:
domain = 'automation'
entity_id = event.data.get(ATTR_ENTITY_ID)

elif event.event_type == EVENT_ALEXA_SMART_HOME:
domain = 'alexa'
elif event.event_type == EVENT_SCRIPT_STARTED:
domain = 'script'
entity_id = event.data.get(ATTR_ENTITY_ID)

elif event.event_type == EVENT_HOMEKIT_CHANGED:
domain = DOMAIN_HOMEKIT
elif event.event_type == EVENT_ALEXA_SMART_HOME:
domain = 'alexa'

if not entity_id and domain:
entity_id = "%s." % (domain, )
elif event.event_type == EVENT_HOMEKIT_CHANGED:
domain = DOMAIN_HOMEKIT

if not entity_id or entities_filter(entity_id):
filtered_events.append(event)
if not entity_id and domain:
entity_id = "%s." % (domain, )

return filtered_events
return not entity_id or entities_filter(entity_id)


def _entry_message_from_state(domain, state):
Expand Down
11 changes: 7 additions & 4 deletions homeassistant/scripts/benchmark/__init__.py
Expand Up @@ -180,12 +180,15 @@ def _logbook_filtering(hass, last_changed, last_updated):
'new_state': new_state
})

events = [event] * 10**5
def yield_events(event):
# pylint: disable=protected-access
entities_filter = logbook._generate_filter_from_config({})
for _ in range(10**5):
if logbook._keep_event(event, entities_filter):
yield event

start = timer()

# pylint: disable=protected-access
events = logbook._exclude_events(events, {})
list(logbook.humanify(None, events))
list(logbook.humanify(None, yield_events(event)))

return timer() - start
106 changes: 63 additions & 43 deletions tests/components/logbook/test_init.py
Expand Up @@ -148,10 +148,11 @@ def test_exclude_new_entities(self):
eventB = self.create_state_changed_event(pointB, entity_id2, 20)
eventA.data['old_state'] = None

events = logbook._exclude_events(
(ha.Event(EVENT_HOMEASSISTANT_STOP),
eventA, eventB),
logbook._generate_filter_from_config({}))
entities_filter = logbook._generate_filter_from_config({})
events = [e for e in
(ha.Event(EVENT_HOMEASSISTANT_STOP),
eventA, eventB)
if logbook._keep_event(e, entities_filter)]
entries = list(logbook.humanify(self.hass, events))

assert 2 == len(entries)
Expand All @@ -172,10 +173,11 @@ def test_exclude_removed_entities(self):
eventB = self.create_state_changed_event(pointB, entity_id2, 20)
eventA.data['new_state'] = None

events = logbook._exclude_events(
(ha.Event(EVENT_HOMEASSISTANT_STOP),
eventA, eventB),
logbook._generate_filter_from_config({}))
entities_filter = logbook._generate_filter_from_config({})
events = [e for e in
(ha.Event(EVENT_HOMEASSISTANT_STOP),
eventA, eventB)
if logbook._keep_event(e, entities_filter)]
entries = list(logbook.humanify(self.hass, events))

assert 2 == len(entries)
Expand All @@ -196,10 +198,11 @@ def test_exclude_events_hidden(self):
{ATTR_HIDDEN: 'true'})
eventB = self.create_state_changed_event(pointB, entity_id2, 20)

events = logbook._exclude_events(
(ha.Event(EVENT_HOMEASSISTANT_STOP),
eventA, eventB),
logbook._generate_filter_from_config({}))
entities_filter = logbook._generate_filter_from_config({})
events = [e for e in
(ha.Event(EVENT_HOMEASSISTANT_STOP),
eventA, eventB)
if logbook._keep_event(e, entities_filter)]
entries = list(logbook.humanify(self.hass, events))

assert 2 == len(entries)
Expand All @@ -223,9 +226,11 @@ def test_exclude_events_entity(self):
ha.DOMAIN: {},
logbook.DOMAIN: {logbook.CONF_EXCLUDE: {
logbook.CONF_ENTITIES: [entity_id, ]}}})
events = logbook._exclude_events(
(ha.Event(EVENT_HOMEASSISTANT_STOP), eventA, eventB),
logbook._generate_filter_from_config(config[logbook.DOMAIN]))
entities_filter = logbook._generate_filter_from_config(
config[logbook.DOMAIN])
events = [e for e in
(ha.Event(EVENT_HOMEASSISTANT_STOP), eventA, eventB)
if logbook._keep_event(e, entities_filter)]
entries = list(logbook.humanify(self.hass, events))

assert 2 == len(entries)
Expand All @@ -249,11 +254,13 @@ def test_exclude_events_domain(self):
ha.DOMAIN: {},
logbook.DOMAIN: {logbook.CONF_EXCLUDE: {
logbook.CONF_DOMAINS: ['switch', 'alexa', DOMAIN_HOMEKIT]}}})
events = logbook._exclude_events(
(ha.Event(EVENT_HOMEASSISTANT_START),
ha.Event(EVENT_ALEXA_SMART_HOME),
ha.Event(EVENT_HOMEKIT_CHANGED), eventA, eventB),
logbook._generate_filter_from_config(config[logbook.DOMAIN]))
entities_filter = logbook._generate_filter_from_config(
config[logbook.DOMAIN])
events = [e for e in
(ha.Event(EVENT_HOMEASSISTANT_START),
ha.Event(EVENT_ALEXA_SMART_HOME),
ha.Event(EVENT_HOMEKIT_CHANGED), eventA, eventB)
if logbook._keep_event(e, entities_filter)]
entries = list(logbook.humanify(self.hass, events))

assert 2 == len(entries)
Expand Down Expand Up @@ -283,9 +290,11 @@ def test_exclude_automation_events(self):
ha.DOMAIN: {},
logbook.DOMAIN: {logbook.CONF_EXCLUDE: {
logbook.CONF_ENTITIES: [entity_id, ]}}})
events = logbook._exclude_events(
(ha.Event(EVENT_HOMEASSISTANT_STOP), eventA, eventB),
logbook._generate_filter_from_config(config[logbook.DOMAIN]))
entities_filter = logbook._generate_filter_from_config(
config[logbook.DOMAIN])
events = [e for e in
(ha.Event(EVENT_HOMEASSISTANT_STOP), eventA, eventB)
if logbook._keep_event(e, entities_filter)]
entries = list(logbook.humanify(self.hass, events))

assert 2 == len(entries)
Expand Down Expand Up @@ -316,9 +325,11 @@ def test_exclude_script_events(self):
ha.DOMAIN: {},
logbook.DOMAIN: {logbook.CONF_EXCLUDE: {
logbook.CONF_ENTITIES: [entity_id, ]}}})
events = logbook._exclude_events(
(ha.Event(EVENT_HOMEASSISTANT_STOP), eventA, eventB),
logbook._generate_filter_from_config(config[logbook.DOMAIN]))
entities_filter = logbook._generate_filter_from_config(
config[logbook.DOMAIN])
events = [e for e in
(ha.Event(EVENT_HOMEASSISTANT_STOP), eventA, eventB)
if logbook._keep_event(e, entities_filter)]
entries = list(logbook.humanify(self.hass, events))

assert 2 == len(entries)
Expand All @@ -342,9 +353,11 @@ def test_include_events_entity(self):
ha.DOMAIN: {},
logbook.DOMAIN: {logbook.CONF_INCLUDE: {
logbook.CONF_ENTITIES: [entity_id2, ]}}})
events = logbook._exclude_events(
(ha.Event(EVENT_HOMEASSISTANT_STOP), eventA, eventB),
logbook._generate_filter_from_config(config[logbook.DOMAIN]))
entities_filter = logbook._generate_filter_from_config(
config[logbook.DOMAIN])
events = [e for e in
(ha.Event(EVENT_HOMEASSISTANT_STOP), eventA, eventB)
if logbook._keep_event(e, entities_filter)]
entries = list(logbook.humanify(self.hass, events))

assert 2 == len(entries)
Expand Down Expand Up @@ -378,10 +391,12 @@ def test_include_events_domain(self):
ha.DOMAIN: {},
logbook.DOMAIN: {logbook.CONF_INCLUDE: {
logbook.CONF_DOMAINS: ['sensor', 'alexa', DOMAIN_HOMEKIT]}}})
events = logbook._exclude_events(
(ha.Event(EVENT_HOMEASSISTANT_START),
event_alexa, event_homekit, eventA, eventB),
logbook._generate_filter_from_config(config[logbook.DOMAIN]))
entities_filter = logbook._generate_filter_from_config(
config[logbook.DOMAIN])
events = [e for e in
(ha.Event(EVENT_HOMEASSISTANT_START),
event_alexa, event_homekit, eventA, eventB)
if logbook._keep_event(e, entities_filter)]
entries = list(logbook.humanify(self.hass, events))

assert 4 == len(entries)
Expand Down Expand Up @@ -415,10 +430,13 @@ def test_include_exclude_events(self):
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),
logbook._generate_filter_from_config(config[logbook.DOMAIN]))
entities_filter = logbook._generate_filter_from_config(
config[logbook.DOMAIN])
events = [e for e in
(ha.Event(EVENT_HOMEASSISTANT_START),
eventA1, eventA2, eventA3,
eventB1, eventB2)
if logbook._keep_event(e, entities_filter)]
entries = list(logbook.humanify(self.hass, events))

assert 5 == len(entries)
Expand All @@ -443,9 +461,10 @@ def test_exclude_auto_groups(self):
eventB = self.create_state_changed_event(pointA, entity_id2, 20,
{'auto': True})

events = logbook._exclude_events(
(eventA, eventB),
logbook._generate_filter_from_config({}))
entities_filter = logbook._generate_filter_from_config({})
events = [e for e in
(eventA, eventB)
if logbook._keep_event(e, entities_filter)]
entries = list(logbook.humanify(self.hass, events))

assert 1 == len(entries)
Expand All @@ -463,9 +482,10 @@ def test_exclude_attribute_changes(self):
eventB = self.create_state_changed_event(
pointA, entity_id2, 20, last_changed=pointA, last_updated=pointB)

events = logbook._exclude_events(
(eventA, eventB),
logbook._generate_filter_from_config({}))
entities_filter = logbook._generate_filter_from_config({})
events = [e for e in
(eventA, eventB)
if logbook._keep_event(e, entities_filter)]
entries = list(logbook.humanify(self.hass, events))

assert 1 == len(entries)
Expand Down

0 comments on commit 63f243f

Please sign in to comment.