Merge pull request #4988 from home-assistant/release-0-35-1

0.35.1
This commit is contained in:
Paulus Schoutsen 2016-12-18 14:11:10 -08:00 committed by GitHub
commit 75dd391118
8 changed files with 126 additions and 38 deletions

View File

@ -166,6 +166,8 @@ def async_setup(hass, config):
for entity in component.async_extract_from_service(service_call): for entity in component.async_extract_from_service(service_call):
tasks.append(entity.async_trigger( tasks.append(entity.async_trigger(
service_call.data.get(ATTR_VARIABLES), True)) service_call.data.get(ATTR_VARIABLES), True))
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop) yield from asyncio.wait(tasks, loop=hass.loop)
@asyncio.coroutine @asyncio.coroutine
@ -175,6 +177,8 @@ def async_setup(hass, config):
method = 'async_{}'.format(service_call.service) method = 'async_{}'.format(service_call.service)
for entity in component.async_extract_from_service(service_call): for entity in component.async_extract_from_service(service_call):
tasks.append(getattr(entity, method)()) tasks.append(getattr(entity, method)())
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop) yield from asyncio.wait(tasks, loop=hass.loop)
@asyncio.coroutine @asyncio.coroutine
@ -186,6 +190,8 @@ def async_setup(hass, config):
tasks.append(entity.async_turn_off()) tasks.append(entity.async_turn_off())
else: else:
tasks.append(entity.async_turn_on()) tasks.append(entity.async_turn_on())
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop) yield from asyncio.wait(tasks, loop=hass.loop)
@asyncio.coroutine @asyncio.coroutine

View File

@ -18,7 +18,7 @@ from aiohttp.web_exceptions import HTTPUnauthorized, HTTPMovedPermanently
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
import homeassistant.remote as rem import homeassistant.remote as rem
from homeassistant.util import get_local_ip import homeassistant.util as hass_util
from homeassistant.components import persistent_notification from homeassistant.components import persistent_notification
from homeassistant.const import ( from homeassistant.const import (
SERVER_PORT, CONTENT_TYPE_JSON, ALLOWED_CORS_HEADERS, SERVER_PORT, CONTENT_TYPE_JSON, ALLOWED_CORS_HEADERS,
@ -41,6 +41,7 @@ REQUIREMENTS = ('aiohttp_cors==0.5.0',)
CONF_API_PASSWORD = 'api_password' CONF_API_PASSWORD = 'api_password'
CONF_SERVER_HOST = 'server_host' CONF_SERVER_HOST = 'server_host'
CONF_SERVER_PORT = 'server_port' CONF_SERVER_PORT = 'server_port'
CONF_BASE_URL = 'base_url'
CONF_DEVELOPMENT = 'development' CONF_DEVELOPMENT = 'development'
CONF_SSL_CERTIFICATE = 'ssl_certificate' CONF_SSL_CERTIFICATE = 'ssl_certificate'
CONF_SSL_KEY = 'ssl_key' CONF_SSL_KEY = 'ssl_key'
@ -84,6 +85,7 @@ HTTP_SCHEMA = vol.Schema({
vol.Optional(CONF_SERVER_HOST, default=DEFAULT_SERVER_HOST): cv.string, vol.Optional(CONF_SERVER_HOST, default=DEFAULT_SERVER_HOST): cv.string,
vol.Optional(CONF_SERVER_PORT, default=SERVER_PORT): vol.Optional(CONF_SERVER_PORT, default=SERVER_PORT):
vol.All(vol.Coerce(int), vol.Range(min=1, max=65535)), vol.All(vol.Coerce(int), vol.Range(min=1, max=65535)),
vol.Optional(CONF_BASE_URL): cv.string,
vol.Optional(CONF_DEVELOPMENT, default=DEFAULT_DEVELOPMENT): cv.string, vol.Optional(CONF_DEVELOPMENT, default=DEFAULT_DEVELOPMENT): cv.string,
vol.Optional(CONF_SSL_CERTIFICATE, default=None): cv.isfile, vol.Optional(CONF_SSL_CERTIFICATE, default=None): cv.isfile,
vol.Optional(CONF_SSL_KEY, default=None): cv.isfile, vol.Optional(CONF_SSL_KEY, default=None): cv.isfile,
@ -155,9 +157,17 @@ def async_setup(hass, config):
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, start_server) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, start_server)
hass.http = server hass.http = server
hass.config.api = rem.API(server_host if server_host != '0.0.0.0'
else get_local_ip(), host = conf.get(CONF_BASE_URL)
api_password, server_port,
if host:
pass
elif server_host != DEFAULT_SERVER_HOST:
host = server_host
else:
host = hass_util.get_local_ip()
hass.config.api = rem.API(host, api_password, server_port,
ssl_certificate is not None) ssl_certificate is not None)
return True return True

View File

@ -157,7 +157,8 @@ def async_setup(hass, config):
hass.services.async_register( hass.services.async_register(
DOMAIN, SERVICE_CLEAR_CACHE, async_clear_cache_handle, DOMAIN, SERVICE_CLEAR_CACHE, async_clear_cache_handle,
descriptions.get(SERVICE_CLEAR_CACHE), schema=SERVICE_CLEAR_CACHE) descriptions.get(SERVICE_CLEAR_CACHE),
schema=SCHEMA_SERVICE_CLEAR_CACHE)
return True return True
@ -170,9 +171,9 @@ class SpeechManager(object):
self.hass = hass self.hass = hass
self.providers = {} self.providers = {}
self.use_cache = True self.use_cache = DEFAULT_CACHE
self.cache_dir = None self.cache_dir = DEFAULT_CACHE_DIR
self.time_memory = None self.time_memory = DEFAULT_TIME_MEMORY
self.file_cache = {} self.file_cache = {}
self.mem_cache = {} self.mem_cache = {}
@ -229,7 +230,7 @@ class SpeechManager(object):
"""Remove files from filesystem.""" """Remove files from filesystem."""
for _, filename in self.file_cache.items(): for _, filename in self.file_cache.items():
try: try:
os.remove(os.path.join(self.cache_dir), filename) os.remove(os.path.join(self.cache_dir, filename))
except OSError: except OSError:
pass pass

View File

@ -2,7 +2,7 @@
"""Constants used by Home Assistant components.""" """Constants used by Home Assistant components."""
MAJOR_VERSION = 0 MAJOR_VERSION = 0
MINOR_VERSION = 35 MINOR_VERSION = 35
PATCH_VERSION = '0' PATCH_VERSION = '1'
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
REQUIRED_PYTHON_VER = (3, 4, 2) REQUIRED_PYTHON_VER = (3, 4, 2)

View File

@ -298,9 +298,8 @@ class HomeAssistant(object):
# cleanup async layer from python logging # cleanup async layer from python logging
if self.data.get(DATA_ASYNCHANDLER): if self.data.get(DATA_ASYNCHANDLER):
handler = self.data.pop(DATA_ASYNCHANDLER) handler = self.data.pop(DATA_ASYNCHANDLER)
logger = logging.getLogger('') logging.getLogger('').removeHandler(handler)
handler.close() yield from handler.async_close(blocking=True)
logger.removeHandler(handler)
self.loop.stop() self.loop.stop()

View File

@ -49,6 +49,23 @@ class AsyncHandler(object):
"""Wrap close to handler.""" """Wrap close to handler."""
self.emit(None) self.emit(None)
@asyncio.coroutine
def async_close(self, blocking=False):
"""Close the handler.
When blocking=True, will wait till closed.
"""
self.close()
if blocking:
# Python 3.4.4+
# pylint: disable=no-member
if hasattr(self._queue, 'join'):
yield from self._queue.join()
else:
while not self._queue.empty():
yield from asyncio.sleep(0, loop=self.loop)
def emit(self, record): def emit(self, record):
"""Process a record.""" """Process a record."""
ident = self.loop.__dict__.get("_thread_ident") ident = self.loop.__dict__.get("_thread_ident")
@ -66,15 +83,23 @@ class AsyncHandler(object):
def _process(self): def _process(self):
"""Process log in a thread.""" """Process log in a thread."""
support_join = hasattr(self._queue, 'task_done')
while True: while True:
record = run_coroutine_threadsafe( record = run_coroutine_threadsafe(
self._queue.get(), self.loop).result() self._queue.get(), self.loop).result()
# pylint: disable=no-member
if record is None: if record is None:
self.handler.close() self.handler.close()
if support_join:
self.loop.call_soon_threadsafe(self._queue.task_done)
return return
self.handler.emit(record) self.handler.emit(record)
if support_join:
self.loop.call_soon_threadsafe(self._queue.task_done)
def createLock(self): def createLock(self):
"""Ignore lock stuff.""" """Ignore lock stuff."""

View File

@ -1,6 +1,7 @@
"""The tests for the Home Assistant HTTP component.""" """The tests for the Home Assistant HTTP component."""
import asyncio import asyncio
import requests import requests
from unittest.mock import MagicMock
from homeassistant import bootstrap, const from homeassistant import bootstrap, const
import homeassistant.components.http as http import homeassistant.components.http as http
@ -154,3 +155,49 @@ def test_registering_view_while_running(hass, test_client):
text = yield from resp.text() text = yield from resp.text()
assert text == 'hello' assert text == 'hello'
def test_api_base_url(loop):
"""Test setting api url."""
hass = MagicMock()
hass.loop = loop
assert loop.run_until_complete(
bootstrap.async_setup_component(hass, 'http', {
'http': {
'base_url': 'example.com'
}
})
)
assert hass.config.api.base_url == 'http://example.com:8123'
assert loop.run_until_complete(
bootstrap.async_setup_component(hass, 'http', {
'http': {
'server_host': '1.1.1.1'
}
})
)
assert hass.config.api.base_url == 'http://1.1.1.1:8123'
assert loop.run_until_complete(
bootstrap.async_setup_component(hass, 'http', {
'http': {
'server_host': '1.1.1.1'
}
})
)
assert hass.config.api.base_url == 'http://1.1.1.1:8123'
assert loop.run_until_complete(
bootstrap.async_setup_component(hass, 'http', {
'http': {
}
})
)
assert hass.config.api.base_url == 'http://127.0.0.1:8123'