mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
commit
75dd391118
@ -166,7 +166,9 @@ def async_setup(hass, config):
|
||||
for entity in component.async_extract_from_service(service_call):
|
||||
tasks.append(entity.async_trigger(
|
||||
service_call.data.get(ATTR_VARIABLES), True))
|
||||
yield from asyncio.wait(tasks, loop=hass.loop)
|
||||
|
||||
if tasks:
|
||||
yield from asyncio.wait(tasks, loop=hass.loop)
|
||||
|
||||
@asyncio.coroutine
|
||||
def turn_onoff_service_handler(service_call):
|
||||
@ -175,7 +177,9 @@ def async_setup(hass, config):
|
||||
method = 'async_{}'.format(service_call.service)
|
||||
for entity in component.async_extract_from_service(service_call):
|
||||
tasks.append(getattr(entity, method)())
|
||||
yield from asyncio.wait(tasks, loop=hass.loop)
|
||||
|
||||
if tasks:
|
||||
yield from asyncio.wait(tasks, loop=hass.loop)
|
||||
|
||||
@asyncio.coroutine
|
||||
def toggle_service_handler(service_call):
|
||||
@ -186,7 +190,9 @@ def async_setup(hass, config):
|
||||
tasks.append(entity.async_turn_off())
|
||||
else:
|
||||
tasks.append(entity.async_turn_on())
|
||||
yield from asyncio.wait(tasks, loop=hass.loop)
|
||||
|
||||
if tasks:
|
||||
yield from asyncio.wait(tasks, loop=hass.loop)
|
||||
|
||||
@asyncio.coroutine
|
||||
def reload_service_handler(service_call):
|
||||
|
@ -18,7 +18,7 @@ from aiohttp.web_exceptions import HTTPUnauthorized, HTTPMovedPermanently
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
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.const import (
|
||||
SERVER_PORT, CONTENT_TYPE_JSON, ALLOWED_CORS_HEADERS,
|
||||
@ -41,6 +41,7 @@ REQUIREMENTS = ('aiohttp_cors==0.5.0',)
|
||||
CONF_API_PASSWORD = 'api_password'
|
||||
CONF_SERVER_HOST = 'server_host'
|
||||
CONF_SERVER_PORT = 'server_port'
|
||||
CONF_BASE_URL = 'base_url'
|
||||
CONF_DEVELOPMENT = 'development'
|
||||
CONF_SSL_CERTIFICATE = 'ssl_certificate'
|
||||
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_PORT, default=SERVER_PORT):
|
||||
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_SSL_CERTIFICATE, 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.http = server
|
||||
hass.config.api = rem.API(server_host if server_host != '0.0.0.0'
|
||||
else get_local_ip(),
|
||||
api_password, server_port,
|
||||
|
||||
host = conf.get(CONF_BASE_URL)
|
||||
|
||||
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)
|
||||
|
||||
return True
|
||||
|
@ -157,7 +157,8 @@ def async_setup(hass, config):
|
||||
|
||||
hass.services.async_register(
|
||||
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
|
||||
|
||||
@ -170,9 +171,9 @@ class SpeechManager(object):
|
||||
self.hass = hass
|
||||
self.providers = {}
|
||||
|
||||
self.use_cache = True
|
||||
self.cache_dir = None
|
||||
self.time_memory = None
|
||||
self.use_cache = DEFAULT_CACHE
|
||||
self.cache_dir = DEFAULT_CACHE_DIR
|
||||
self.time_memory = DEFAULT_TIME_MEMORY
|
||||
self.file_cache = {}
|
||||
self.mem_cache = {}
|
||||
|
||||
@ -229,7 +230,7 @@ class SpeechManager(object):
|
||||
"""Remove files from filesystem."""
|
||||
for _, filename in self.file_cache.items():
|
||||
try:
|
||||
os.remove(os.path.join(self.cache_dir), filename)
|
||||
os.remove(os.path.join(self.cache_dir, filename))
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
"""Constants used by Home Assistant components."""
|
||||
MAJOR_VERSION = 0
|
||||
MINOR_VERSION = 35
|
||||
PATCH_VERSION = '0'
|
||||
PATCH_VERSION = '1'
|
||||
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
|
||||
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
|
||||
REQUIRED_PYTHON_VER = (3, 4, 2)
|
||||
|
@ -298,9 +298,8 @@ class HomeAssistant(object):
|
||||
# cleanup async layer from python logging
|
||||
if self.data.get(DATA_ASYNCHANDLER):
|
||||
handler = self.data.pop(DATA_ASYNCHANDLER)
|
||||
logger = logging.getLogger('')
|
||||
handler.close()
|
||||
logger.removeHandler(handler)
|
||||
logging.getLogger('').removeHandler(handler)
|
||||
yield from handler.async_close(blocking=True)
|
||||
|
||||
self.loop.stop()
|
||||
|
||||
|
@ -49,6 +49,23 @@ class AsyncHandler(object):
|
||||
"""Wrap close to handler."""
|
||||
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):
|
||||
"""Process a record."""
|
||||
ident = self.loop.__dict__.get("_thread_ident")
|
||||
@ -66,15 +83,23 @@ class AsyncHandler(object):
|
||||
|
||||
def _process(self):
|
||||
"""Process log in a thread."""
|
||||
support_join = hasattr(self._queue, 'task_done')
|
||||
|
||||
while True:
|
||||
record = run_coroutine_threadsafe(
|
||||
self._queue.get(), self.loop).result()
|
||||
|
||||
# pylint: disable=no-member
|
||||
|
||||
if record is None:
|
||||
self.handler.close()
|
||||
if support_join:
|
||||
self.loop.call_soon_threadsafe(self._queue.task_done)
|
||||
return
|
||||
|
||||
self.handler.emit(record)
|
||||
if support_join:
|
||||
self.loop.call_soon_threadsafe(self._queue.task_done)
|
||||
|
||||
def createLock(self):
|
||||
"""Ignore lock stuff."""
|
||||
|
@ -1,6 +1,7 @@
|
||||
"""The tests for the Home Assistant HTTP component."""
|
||||
import asyncio
|
||||
import requests
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from homeassistant import bootstrap, const
|
||||
import homeassistant.components.http as http
|
||||
@ -154,3 +155,49 @@ def test_registering_view_while_running(hass, test_client):
|
||||
|
||||
text = yield from resp.text()
|
||||
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'
|
||||
|
@ -88,35 +88,35 @@ class TestTTS(object):
|
||||
self.default_tts_cache,
|
||||
"265944c108cbb00b2a621be5930513e03a0bb2cd_demo.mp3"))
|
||||
|
||||
def test_setup_component_and_test_service_clear_cache(self):
|
||||
"""Setup the demo platform and call service clear cache."""
|
||||
calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
def test_setup_component_and_test_service_clear_cache(self):
|
||||
"""Setup the demo platform and call service clear cache."""
|
||||
calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {
|
||||
tts.DOMAIN: {
|
||||
'platform': 'demo',
|
||||
}
|
||||
config = {
|
||||
tts.DOMAIN: {
|
||||
'platform': 'demo',
|
||||
}
|
||||
}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
setup_component(self.hass, tts.DOMAIN, config)
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
setup_component(self.hass, tts.DOMAIN, config)
|
||||
|
||||
self.hass.services.call(tts.DOMAIN, 'demo_say', {
|
||||
tts.ATTR_MESSAGE: "I person is on front of your door.",
|
||||
})
|
||||
self.hass.block_till_done()
|
||||
self.hass.services.call(tts.DOMAIN, 'demo_say', {
|
||||
tts.ATTR_MESSAGE: "I person is on front of your door.",
|
||||
})
|
||||
self.hass.block_till_done()
|
||||
|
||||
assert len(calls) == 1
|
||||
assert os.path.isfile(os.path.join(
|
||||
self.default_tts_cache,
|
||||
"265944c108cbb00b2a621be5930513e03a0bb2cd_demo.mp3"))
|
||||
assert len(calls) == 1
|
||||
assert os.path.isfile(os.path.join(
|
||||
self.default_tts_cache,
|
||||
"265944c108cbb00b2a621be5930513e03a0bb2cd_demo.mp3"))
|
||||
|
||||
self.hass.services.call(tts.DOMAIN, tts.SERVICE_CLEAR_CACHE, {})
|
||||
self.hass.block_till_done()
|
||||
self.hass.services.call(tts.DOMAIN, tts.SERVICE_CLEAR_CACHE, {})
|
||||
self.hass.block_till_done()
|
||||
|
||||
assert not os.path.isfile(os.path.join(
|
||||
self.default_tts_cache,
|
||||
"265944c108cbb00b2a621be5930513e03a0bb2cd_demo.mp3"))
|
||||
assert not os.path.isfile(os.path.join(
|
||||
self.default_tts_cache,
|
||||
"265944c108cbb00b2a621be5930513e03a0bb2cd_demo.mp3"))
|
||||
|
||||
def test_setup_component_and_test_service_with_receive_voice(self):
|
||||
"""Setup the demo platform and call service and receive voice."""
|
||||
|
Loading…
x
Reference in New Issue
Block a user