Logbook: filter by entity and period (#17095)

* Filter logbook by entity_id

* Filter logbook by period

* Simple test

* houndci-bot review

* Tests

* Test fix

* Test Fix
pull/17328/head
Nikolay Vasilchuk 2018-10-11 15:15:04 +03:00 committed by Paulus Schoutsen
parent ed45dff6e8
commit 44477f3d32
2 changed files with 103 additions and 5 deletions

View File

@ -133,14 +133,21 @@ class LogbookView(HomeAssistantView):
else:
datetime = dt_util.start_of_local_day()
start_day = dt_util.as_utc(datetime)
end_day = start_day + timedelta(days=1)
period = request.query.get('period')
if period is None:
period = 1
else:
period = int(period)
entity_id = request.query.get('entity')
start_day = dt_util.as_utc(datetime) - timedelta(days=period - 1)
end_day = start_day + timedelta(days=period)
hass = request.app['hass']
def json_events():
"""Fetch events and generate JSON."""
return self.json(list(
_get_events(hass, self.config, start_day, end_day)))
_get_events(hass, self.config, start_day, end_day, entity_id)))
return await hass.async_add_job(json_events)
@ -288,7 +295,7 @@ def humanify(hass, events):
}
def _get_events(hass, config, start_day, end_day):
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 (
@ -302,6 +309,10 @@ def _get_events(hass, config, start_day, end_day):
& (Events.time_fired < end_day)) \
.filter((States.last_updated == States.last_changed)
| (States.state_id.is_(None)))
if entity_id is not None:
query = query.filter(States.entity_id == entity_id.lower())
events = execute(query)
return humanify(hass, _exclude_events(events, config))

View File

@ -1,7 +1,7 @@
"""The tests for the logbook component."""
# pylint: disable=protected-access,invalid-name
import logging
from datetime import timedelta
from datetime import (timedelta, datetime)
import unittest
from homeassistant.components import sun
@ -558,6 +558,93 @@ async def test_logbook_view(hass, aiohttp_client):
assert response.status == 200
async def test_logbook_view_period_entity(hass, aiohttp_client):
"""Test the logbook view with period and entity."""
await hass.async_add_job(init_recorder_component, hass)
await async_setup_component(hass, 'logbook', {})
await hass.components.recorder.wait_connection_ready()
await hass.async_add_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
entity_id_test = 'switch.test'
hass.states.async_set(entity_id_test, STATE_OFF)
hass.states.async_set(entity_id_test, STATE_ON)
entity_id_second = 'switch.second'
hass.states.async_set(entity_id_second, STATE_OFF)
hass.states.async_set(entity_id_second, STATE_ON)
await hass.async_block_till_done()
await hass.async_add_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
client = await aiohttp_client(hass.http.app)
# Today time 00:00:00
start = dt_util.utcnow().date()
start_date = datetime(start.year, start.month, start.day)
# Test today entries without filters
response = await client.get(
'/api/logbook/{}'.format(start_date.isoformat()))
assert response.status == 200
json = await response.json()
assert len(json) == 2
assert json[0]['entity_id'] == entity_id_test
assert json[1]['entity_id'] == entity_id_second
# Test today entries with filter by period
response = await client.get(
'/api/logbook/{}?period=1'.format(start_date.isoformat()))
assert response.status == 200
json = await response.json()
assert len(json) == 2
assert json[0]['entity_id'] == entity_id_test
assert json[1]['entity_id'] == entity_id_second
# Test today entries with filter by entity_id
response = await client.get(
'/api/logbook/{}?entity=switch.test'.format(
start_date.isoformat()))
assert response.status == 200
json = await response.json()
assert len(json) == 1
assert json[0]['entity_id'] == entity_id_test
# Test entries for 3 days with filter by entity_id
response = await client.get(
'/api/logbook/{}?period=3&entity=switch.test'.format(
start_date.isoformat()))
assert response.status == 200
json = await response.json()
assert len(json) == 1
assert json[0]['entity_id'] == entity_id_test
# Tomorrow time 00:00:00
start = (dt_util.utcnow() + timedelta(days=1)).date()
start_date = datetime(start.year, start.month, start.day)
# Test tomorrow entries without filters
response = await client.get(
'/api/logbook/{}'.format(start_date.isoformat()))
assert response.status == 200
json = await response.json()
assert len(json) == 0
# Test tomorrow entries with filter by entity_id
response = await client.get(
'/api/logbook/{}?entity=switch.test'.format(
start_date.isoformat()))
assert response.status == 200
json = await response.json()
assert len(json) == 0
# Test entries from tomorrow to 3 days ago with filter by entity_id
response = await client.get(
'/api/logbook/{}?period=3&entity=switch.test'.format(
start_date.isoformat()))
assert response.status == 200
json = await response.json()
assert len(json) == 1
assert json[0]['entity_id'] == entity_id_test
async def test_humanify_alexa_event(hass):
"""Test humanifying Alexa event."""
hass.states.async_set('light.kitchen', 'on', {