Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 13 additions & 40 deletions homeassistant/components/history.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

from homeassistant.const import (
HTTP_BAD_REQUEST, CONF_DOMAINS, CONF_ENTITIES, CONF_EXCLUDE, CONF_INCLUDE)
import homeassistant.helpers.config_validation as cv
import homeassistant.util.dt as dt_util
from homeassistant.components import recorder, script
from homeassistant.components.frontend import register_built_in_panel
Expand All @@ -28,34 +27,22 @@
DEPENDENCIES = ['recorder', 'http']

CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
CONF_EXCLUDE: vol.Schema({
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])
})
}),
DOMAIN: recorder.FILTER_SCHEMA,
}, extra=vol.ALLOW_EXTRA)

SIGNIFICANT_DOMAINS = ('thermostat', 'climate')
IGNORE_DOMAINS = ('zone', 'scene',)


def last_5_states(entity_id):
"""Return the last 5 states for entity_id."""
entity_id = entity_id.lower()

states = recorder.get_model('States')
return recorder.execute(
recorder.query('States').filter(
(states.entity_id == entity_id) &
(states.last_changed == states.last_updated)
).order_by(states.state_id.desc()).limit(5))
def last_recorder_run():
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use hybrid properties instead and add this to the RecorderRun model: http://stackoverflow.com/a/14616299/646416

We then no longer need a helper method. (and yes, we should probably remove more of these helper methods in favor of that)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Postponed for future PR

"""Retireve the last closed recorder run from the DB."""
rec_runs = recorder.get_model('RecorderRuns')
with recorder.session_scope() as session:
res = recorder.query(rec_runs).order_by(rec_runs.end.desc()).first()
if res is None:
return None
session.expunge(res)
return res


def get_significant_states(start_time, end_time=None, entity_id=None,
Expand Down Expand Up @@ -91,7 +78,7 @@ def get_significant_states(start_time, end_time=None, entity_id=None,
def state_changes_during_period(start_time, end_time=None, entity_id=None):
"""Return states changes during UTC period start_time - end_time."""
states = recorder.get_model('States')
query = recorder.query('States').filter(
query = recorder.query(states).filter(
(states.last_changed == states.last_updated) &
(states.last_changed > start_time))

Expand Down Expand Up @@ -132,7 +119,7 @@ def get_states(utc_point_in_time, entity_ids=None, run=None, filters=None):
most_recent_state_ids = most_recent_state_ids.group_by(
states.entity_id).subquery()

query = recorder.query('States').join(most_recent_state_ids, and_(
query = recorder.query(states).join(most_recent_state_ids, and_(
states.state_id == most_recent_state_ids.c.max_state_id))

for state in recorder.execute(query):
Expand Down Expand Up @@ -185,27 +172,13 @@ def setup(hass, config):
filters.included_entities = include[CONF_ENTITIES]
filters.included_domains = include[CONF_DOMAINS]

hass.http.register_view(Last5StatesView)
recorder.get_instance()
hass.http.register_view(HistoryPeriodView(filters))
register_built_in_panel(hass, 'history', 'History', 'mdi:poll-box')

return True


class Last5StatesView(HomeAssistantView):
"""Handle last 5 state view requests."""

url = '/api/history/entity/{entity_id}/recent_states'
name = 'api:history:entity-recent-states'

@asyncio.coroutine
def get(self, request, entity_id):
"""Retrieve last 5 states of entity."""
result = yield from request.app['hass'].loop.run_in_executor(
None, last_5_states, entity_id)
return self.json(result)


class HistoryPeriodView(HomeAssistantView):
"""Handle history period requests."""

Expand Down
9 changes: 9 additions & 0 deletions homeassistant/components/input_boolean.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import ToggleEntity
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.restore_state import async_get_last_state

DOMAIN = 'input_boolean'

Expand Down Expand Up @@ -139,6 +140,14 @@ def is_on(self):
"""Return true if entity is on."""
return self._state

@asyncio.coroutine
def async_added_to_hass(self):
"""Called when entity about to be added to hass."""
state = yield from async_get_last_state(self.hass, self.entity_id)
if not state:
return
self._state = state.state == 'on'

@asyncio.coroutine
def async_turn_on(self, **kwargs):
"""Turn the entity on."""
Expand Down
15 changes: 15 additions & 0 deletions homeassistant/components/light/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.restore_state import async_restore_state
import homeassistant.util.color as color_util
from homeassistant.util.async import run_callback_threadsafe

Expand Down Expand Up @@ -126,6 +127,14 @@
_LOGGER = logging.getLogger(__name__)


def extract_info(state):
"""Extract light parameters from a state object."""
params = {key: state.attributes[key] for key in PROP_TO_ATTR
if key in state.attributes}
params['is_on'] = state.state == STATE_ON
return params


def is_on(hass, entity_id=None):
"""Return if the lights are on based on the statemachine."""
entity_id = entity_id or ENTITY_ID_ALL_LIGHTS
Expand Down Expand Up @@ -369,3 +378,9 @@ def state_attributes(self):
def supported_features(self):
"""Flag supported features."""
return 0

@asyncio.coroutine
def async_added_to_hass(self):
"""Component added, restore_state using platforms."""
if hasattr(self, 'async_restore_state'):
yield from async_restore_state(self, extract_info)
24 changes: 24 additions & 0 deletions homeassistant/components/light/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
For more details about this platform, please refer to the documentation
https://home-assistant.io/components/demo/
"""
import asyncio
import random

from homeassistant.components.light import (
Expand Down Expand Up @@ -149,3 +150,26 @@ def turn_off(self, **kwargs) -> None:
# As we have disabled polling, we need to inform
# Home Assistant about updates in our state ourselves.
self.schedule_update_ha_state()

@asyncio.coroutine
def async_restore_state(self, is_on, **kwargs):
"""Restore the demo state."""
self._state = is_on

if 'brightness' in kwargs:
self._brightness = kwargs['brightness']

if 'color_temp' in kwargs:
self._ct = kwargs['color_temp']

if 'rgb_color' in kwargs:
self._rgb = kwargs['rgb_color']

if 'xy_color' in kwargs:
self._xy_color = kwargs['xy_color']

if 'white_value' in kwargs:
self._white = kwargs['white_value']

if 'effect' in kwargs:
self._effect = kwargs['effect']
Loading