Merge pull request #6227 from home-assistant/release-0-39

Release 0 39
This commit is contained in:
Paulus Schoutsen 2017-02-25 15:04:54 -08:00 committed by GitHub
commit 58f9455604
9 changed files with 31 additions and 22 deletions

View File

@ -3,7 +3,7 @@
FINGERPRINTS = {
"compatibility.js": "83d9c77748dafa9db49ae77d7f3d8fb0",
"core.js": "1f7f88d8f5dada08bce1d935cfa5f33e",
"frontend.html": "be258a53166b82f4ebd5232037e1cbd5",
"frontend.html": "ca9efa7e4506aa6b1a668703c8d0f800",
"mdi.html": "c1dde43ccf5667f687c418fc8daf9668",
"micromarkdown-js.html": "93b5ec4016f0bba585521cf4d18dec1a",
"panels/ha-panel-config.html": "412b3e24515ffa1ee8074ce974cf4057",

File diff suppressed because one or more lines are too long

@ -1 +1 @@
Subproject commit 5d223c8da4b4380bf79d8f0285ce7824063e89ef
Subproject commit e509ed07a08d35152b9eea6e263411dfc027867b

File diff suppressed because one or more lines are too long

View File

@ -7,6 +7,7 @@ to query this database.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/recorder/
"""
import asyncio
import logging
import queue
import threading
@ -20,7 +21,7 @@ import voluptuous as vol
from homeassistant.core import HomeAssistant, callback, split_entity_id
from homeassistant.const import (
ATTR_ENTITY_ID, CONF_ENTITIES, CONF_EXCLUDE, CONF_DOMAINS,
CONF_INCLUDE, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP,
CONF_INCLUDE, EVENT_HOMEASSISTANT_STOP,
EVENT_STATE_CHANGED, EVENT_TIME_CHANGED, MATCH_ALL)
from homeassistant.exceptions import HomeAssistantError
import homeassistant.helpers.config_validation as cv
@ -83,7 +84,18 @@ def session_scope():
session.close()
def get_instance() -> None:
@asyncio.coroutine
def async_get_instance():
"""Throw error if recorder not initialized."""
if _INSTANCE is None:
raise RuntimeError("Recorder not initialized.")
yield from _INSTANCE.async_db_ready.wait()
return _INSTANCE
def get_instance():
"""Throw error if recorder not initialized."""
if _INSTANCE is None:
raise RuntimeError("Recorder not initialized.")
@ -200,7 +212,7 @@ class Recorder(threading.Thread):
self.recording_start = dt_util.utcnow()
self.db_url = uri
self.db_ready = threading.Event()
self.start_recording = threading.Event()
self.async_db_ready = asyncio.Event(loop=hass.loop)
self.engine = None # type: Any
self._run = None # type: Any
@ -209,11 +221,6 @@ class Recorder(threading.Thread):
self.exclude = exclude.get(CONF_ENTITIES, []) + \
exclude.get(CONF_DOMAINS, [])
def start_recording(event):
"""Start recording."""
self.start_recording.set()
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_recording)
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, self.shutdown)
hass.bus.listen(MATCH_ALL, self.event_listener)
@ -229,6 +236,7 @@ class Recorder(threading.Thread):
self._setup_connection()
self._setup_run()
self.db_ready.set()
self.async_db_ready.set()
break
except SQLAlchemyError as err:
_LOGGER.error("Error during connection setup: %s (retrying "
@ -239,8 +247,6 @@ class Recorder(threading.Thread):
async_track_time_interval(
self.hass, self._purge_old_data, timedelta(days=2))
_wait(self.start_recording, "Waiting to start recording")
while True:
event = self.queue.get()
@ -297,9 +303,6 @@ class Recorder(threading.Thread):
"""Tell the recorder to shut down."""
global _INSTANCE # pylint: disable=global-statement
self.queue.put(None)
if not self.start_recording.is_set():
_LOGGER.warning("Recorder never started correctly")
self.start_recording.set()
self.join()
_INSTANCE = None
@ -505,7 +508,7 @@ def _wait(event, message):
event.wait(10)
if event.is_set():
return
msg = message + " ({} seconds)".format(retry)
msg = "{} ({} seconds)".format(message, retry)
_LOGGER.warning(msg)
if not event.is_set():
raise HomeAssistantError(msg)

View File

@ -6,7 +6,8 @@ from datetime import timedelta
from homeassistant.core import HomeAssistant, CoreState, callback
from homeassistant.const import EVENT_HOMEASSISTANT_START
from homeassistant.components.history import get_states, last_recorder_run
from homeassistant.components.recorder import DOMAIN as _RECORDER
from homeassistant.components.recorder import (
async_get_instance, DOMAIN as _RECORDER)
import homeassistant.util.dt as dt_util
_LOGGER = logging.getLogger(__name__)
@ -57,6 +58,8 @@ def async_get_last_state(hass, entity_id: str):
hass.state)
return None
yield from async_get_instance() # Ensure recorder ready
if _LOCK not in hass.data:
hass.data[_LOCK] = asyncio.Lock(loop=hass.loop)

View File

@ -11,7 +11,8 @@ from homeassistant.components import input_boolean, recorder
from homeassistant.helpers.restore_state import (
async_get_last_state, DATA_RESTORE_CACHE)
from tests.common import get_test_home_assistant, init_recorder_component
from tests.common import (
get_test_home_assistant, mock_coro, init_recorder_component)
@asyncio.coroutine
@ -29,7 +30,9 @@ def test_caching_data(hass):
with patch('homeassistant.helpers.restore_state.last_recorder_run',
return_value=MagicMock(end=dt_util.utcnow())), \
patch('homeassistant.helpers.restore_state.get_states',
return_value=states):
return_value=states), \
patch('homeassistant.helpers.restore_state.async_get_instance',
return_value=mock_coro()):
state = yield from async_get_last_state(hass, 'input_boolean.b1')
assert DATA_RESTORE_CACHE in hass.data