mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 03:37:07 +00:00
commit
75dd391118
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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."""
|
||||||
|
@ -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'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user