From 6455f1388ae48d0adfe33edd96b569f112a21f4d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen <paulus@paulusschoutsen.nl> Date: Sun, 29 Mar 2015 23:57:52 -0700 Subject: [PATCH] Have logbook only report each sensor every 15 minutes --- homeassistant/components/logbook.py | 111 ++++++++++++++++++---------- 1 file changed, 72 insertions(+), 39 deletions(-) diff --git a/homeassistant/components/logbook.py b/homeassistant/components/logbook.py index b5739638a43..8cf750fb932 100644 --- a/homeassistant/components/logbook.py +++ b/homeassistant/components/logbook.py @@ -5,6 +5,7 @@ homeassistant.components.logbook Parses events and generates a human log """ from datetime import datetime +from itertools import groupby from homeassistant import State, DOMAIN as HA_DOMAIN from homeassistant.const import ( @@ -25,6 +26,8 @@ QUERY_EVENTS_BETWEEN = """ ORDER BY time_fired """ +GROUP_BY_MINUTES = 15 + def setup(hass, config): """ Listens for download events to download files. """ @@ -72,56 +75,86 @@ class Entry(object): def humanify(events): - """ Generator that converts a list of events into Entry objects. """ + """ + Generator that converts a list of events into Entry objects. + + Will try to group events if possible: + - if 2+ sensor updates in GROUP_BY_MINUTES, show last + """ # pylint: disable=too-many-branches - for event in events: - if event.event_type == EVENT_STATE_CHANGED: - # Do not report on new entities - if 'old_state' not in event.data: - continue + # Group events in batches of GROUP_BY_MINUTES + for _, g_events in groupby( + events, + lambda event: event.time_fired.minute // GROUP_BY_MINUTES): - to_state = State.from_dict(event.data.get('new_state')) + events_batch = list(g_events) - if not to_state: - continue + # Keep track of last sensor states + last_sensor_event = {} - domain = to_state.domain + # Process events + for event in events_batch: + if event.event_type == EVENT_STATE_CHANGED: + entity_id = event.data['entity_id'] - entry = Entry( - event.time_fired, domain=domain, - name=to_state.name, entity_id=to_state.entity_id) + if entity_id.startswith('sensor.'): + last_sensor_event[entity_id] = event - if domain == 'device_tracker': - entry.message = '{} home'.format( - 'arrived' if to_state.state == STATE_HOME else 'left') + # Yield entries + for event in events_batch: + if event.event_type == EVENT_STATE_CHANGED: - elif domain == 'sun': - if to_state.state == sun.STATE_ABOVE_HORIZON: - entry.message = 'has risen' - else: - entry.message = 'has set' + # Do not report on new entities + if 'old_state' not in event.data: + continue + + to_state = State.from_dict(event.data.get('new_state')) + + if not to_state: + continue + + domain = to_state.domain - elif to_state.state == STATE_ON: - # Future: combine groups and its entity entries ? - entry.message = "turned on" + # Skip all but the last sensor state + if domain == 'sensor' and \ + event != last_sensor_event[to_state.entity_id]: + continue - elif to_state.state == STATE_OFF: - entry.message = "turned off" + entry = Entry( + event.time_fired, domain=domain, + name=to_state.name, entity_id=to_state.entity_id) - else: - entry.message = "changed to {}".format(to_state.state) + if domain == 'device_tracker': + entry.message = '{} home'.format( + 'arrived' if to_state.state == STATE_HOME else 'left') + + elif domain == 'sun': + if to_state.state == sun.STATE_ABOVE_HORIZON: + entry.message = 'has risen' + else: + entry.message = 'has set' + + elif to_state.state == STATE_ON: + # Future: combine groups and its entity entries ? + entry.message = "turned on" + + elif to_state.state == STATE_OFF: + entry.message = "turned off" + + else: + entry.message = "changed to {}".format(to_state.state) - if entry.is_valid: - yield entry + if entry.is_valid: + yield entry - elif event.event_type == EVENT_HOMEASSISTANT_START: - # Future: look for sequence stop/start and rewrite as restarted - yield Entry( - event.time_fired, "Home Assistant", "started", - domain=HA_DOMAIN) + elif event.event_type == EVENT_HOMEASSISTANT_START: + # Future: look for sequence stop/start and rewrite as restarted + yield Entry( + event.time_fired, "Home Assistant", "started", + domain=HA_DOMAIN) - elif event.event_type == EVENT_HOMEASSISTANT_STOP: - yield Entry( - event.time_fired, "Home Assistant", "stopped", - domain=HA_DOMAIN) + elif event.event_type == EVENT_HOMEASSISTANT_STOP: + yield Entry( + event.time_fired, "Home Assistant", "stopped", + domain=HA_DOMAIN) -- GitLab