Skip to content

Commit

Permalink
Merge pull request home-assistant#4988 from home-assistant/release-0-…
Browse files Browse the repository at this point in the history
…35-1

0.35.1
  • Loading branch information
balloob authored Dec 18, 2016
2 parents 9bc1615 + 76a9eba commit 75dd391
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 39 deletions.
12 changes: 9 additions & 3 deletions homeassistant/components/automation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,9 @@ def trigger_service_handler(service_call):
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):
Expand All @@ -175,7 +177,9 @@ def turn_onoff_service_handler(service_call):
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):
Expand All @@ -186,7 +190,9 @@ def toggle_service_handler(service_call):
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):
Expand Down
18 changes: 14 additions & 4 deletions homeassistant/components/http/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

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,
Expand All @@ -41,6 +41,7 @@
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'
Expand Down Expand Up @@ -84,6 +85,7 @@
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,
Expand Down Expand Up @@ -155,9 +157,17 @@ def start_server(event):
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
Expand Down
11 changes: 6 additions & 5 deletions homeassistant/components/tts/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ def async_clear_cache_handle(service):

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

Expand All @@ -170,9 +171,9 @@ def __init__(self, hass):
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 = {}

Expand Down Expand Up @@ -229,7 +230,7 @@ def remove_files():
"""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

Expand Down
2 changes: 1 addition & 1 deletion homeassistant/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 2 additions & 3 deletions homeassistant/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,8 @@ def async_stop(self) -> None:
# 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()

Expand Down
25 changes: 25 additions & 0 deletions homeassistant/util/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,23 @@ def close(self):
"""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")
Expand All @@ -66,15 +83,23 @@ def __repr__(self):

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."""
Expand Down
47 changes: 47 additions & 0 deletions tests/components/http/test_init.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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'
46 changes: 23 additions & 23 deletions tests/components/tts/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,35 +88,35 @@ def test_setup_component_and_test_service(self):
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)

config = {
tts.DOMAIN: {
'platform': 'demo',
}
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',
}
}

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."""
Expand Down

0 comments on commit 75dd391

Please sign in to comment.