Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 32 additions & 36 deletions homeassistant/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,15 @@ def from_config_dict(config: Dict[str, Any],
return hass


@asyncio.coroutine
def async_from_config_dict(config: Dict[str, Any],
hass: core.HomeAssistant,
config_dir: Optional[str] = None,
enable_log: bool = True,
verbose: bool = False,
skip_pip: bool = False,
log_rotate_days: Any = None,
log_file: Any = None,
log_no_color: bool = False) \
async def async_from_config_dict(config: Dict[str, Any],
hass: core.HomeAssistant,
config_dir: Optional[str] = None,
enable_log: bool = True,
verbose: bool = False,
skip_pip: bool = False,
log_rotate_days: Any = None,
log_file: Any = None,
log_no_color: bool = False) \
-> Optional[core.HomeAssistant]:
"""Try to configure Home Assistant from a configuration dictionary.

Expand All @@ -92,20 +91,20 @@ def async_from_config_dict(config: Dict[str, Any],
core_config = config.get(core.DOMAIN, {})

try:
yield from conf_util.async_process_ha_core_config(hass, core_config)
await conf_util.async_process_ha_core_config(hass, core_config)
except vol.Invalid as ex:
conf_util.async_log_exception(ex, 'homeassistant', core_config, hass)
return None

yield from hass.async_add_job(conf_util.process_ha_config_upgrade, hass)
await hass.async_add_job(conf_util.process_ha_config_upgrade, hass)

hass.config.skip_pip = skip_pip
if skip_pip:
_LOGGER.warning("Skipping pip installation of required modules. "
"This may cause issues")

if not loader.PREPARED:
yield from hass.async_add_job(loader.prepare, hass)
await hass.async_add_job(loader.prepare, hass)

# Make a copy because we are mutating it.
config = OrderedDict(config)
Expand All @@ -120,7 +119,7 @@ def async_from_config_dict(config: Dict[str, Any],
config[key] = {}

hass.config_entries = config_entries.ConfigEntries(hass, config)
yield from hass.config_entries.async_load()
await hass.config_entries.async_load()

# Filter out the repeating and common config section [homeassistant]
components = set(key.split(' ')[0] for key in config.keys()
Expand All @@ -129,13 +128,13 @@ def async_from_config_dict(config: Dict[str, Any],

# setup components
# pylint: disable=not-an-iterable
res = yield from core_components.async_setup(hass, config)
res = await core_components.async_setup(hass, config)
if not res:
_LOGGER.error("Home Assistant core failed to initialize. "
"further initialization aborted")
return hass

yield from persistent_notification.async_setup(hass, config)
await persistent_notification.async_setup(hass, config)

_LOGGER.info("Home Assistant core initialized")

Expand All @@ -145,15 +144,15 @@ def async_from_config_dict(config: Dict[str, Any],
continue
hass.async_add_job(async_setup_component(hass, component, config))

yield from hass.async_block_till_done()
await hass.async_block_till_done()

# stage 2
for component in components:
if component in FIRST_INIT_COMPONENT:
continue
hass.async_add_job(async_setup_component(hass, component, config))

yield from hass.async_block_till_done()
await hass.async_block_till_done()

stop = time()
_LOGGER.info("Home Assistant initialized in %.2fs", stop-start)
Expand Down Expand Up @@ -187,14 +186,13 @@ def from_config_file(config_path: str,
return hass


@asyncio.coroutine
def async_from_config_file(config_path: str,
hass: core.HomeAssistant,
verbose: bool = False,
skip_pip: bool = True,
log_rotate_days: Any = None,
log_file: Any = None,
log_no_color: bool = False):
async def async_from_config_file(config_path: str,
hass: core.HomeAssistant,
verbose: bool = False,
skip_pip: bool = True,
log_rotate_days: Any = None,
log_file: Any = None,
log_no_color: bool = False):
"""Read the configuration file and try to start all the functionality.

Will add functionality to 'hass' parameter.
Expand All @@ -203,21 +201,21 @@ def async_from_config_file(config_path: str,
# Set config dir to directory holding config file
config_dir = os.path.abspath(os.path.dirname(config_path))
hass.config.config_dir = config_dir
yield from async_mount_local_lib_path(config_dir, hass.loop)
await async_mount_local_lib_path(config_dir, hass.loop)

async_enable_logging(hass, verbose, log_rotate_days, log_file,
log_no_color)

try:
config_dict = yield from hass.async_add_job(
config_dict = await hass.async_add_job(
conf_util.load_yaml_config_file, config_path)
except HomeAssistantError as err:
_LOGGER.error("Error loading %s: %s", config_path, err)
return None
finally:
clear_secret_cache()

hass = yield from async_from_config_dict(
hass = await async_from_config_dict(
config_dict, hass, enable_log=False, skip_pip=skip_pip)
return hass

Expand Down Expand Up @@ -294,11 +292,10 @@ def async_enable_logging(hass: core.HomeAssistant,

async_handler = AsyncHandler(hass.loop, err_handler)

@asyncio.coroutine
def async_stop_async_handler(event):
async def async_stop_async_handler(event):
"""Cleanup async handler."""
logging.getLogger('').removeHandler(async_handler)
yield from async_handler.async_close(blocking=True)
await async_handler.async_close(blocking=True)

hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_CLOSE, async_stop_async_handler)
Expand All @@ -323,15 +320,14 @@ def mount_local_lib_path(config_dir: str) -> str:
return deps_dir


@asyncio.coroutine
def async_mount_local_lib_path(config_dir: str,
loop: asyncio.AbstractEventLoop) -> str:
async def async_mount_local_lib_path(config_dir: str,
loop: asyncio.AbstractEventLoop) -> str:
"""Add local library to Python Path.

This function is a coroutine.
"""
deps_dir = os.path.join(config_dir, 'deps')
lib_dir = yield from async_get_user_site(deps_dir, loop=loop)
lib_dir = await async_get_user_site(deps_dir, loop=loop)
if lib_dir not in sys.path:
sys.path.insert(0, lib_dir)
return deps_dir
50 changes: 21 additions & 29 deletions homeassistant/components/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ class APIEventStream(HomeAssistantView):
url = URL_API_STREAM
name = "api:stream"

@asyncio.coroutine
def get(self, request):
async def get(self, request):
"""Provide a streaming interface for the event bus."""
# pylint: disable=no-self-use
hass = request.app['hass']
Expand All @@ -88,8 +87,7 @@ def get(self, request):
if restrict:
restrict = restrict.split(',') + [EVENT_HOMEASSISTANT_STOP]

@asyncio.coroutine
def forward_events(event):
async def forward_events(event):
"""Forward events to the open request."""
if event.event_type == EVENT_TIME_CHANGED:
return
Expand All @@ -104,35 +102,35 @@ def forward_events(event):
else:
data = json.dumps(event, cls=rem.JSONEncoder)

yield from to_write.put(data)
await to_write.put(data)

response = web.StreamResponse()
response.content_type = 'text/event-stream'
yield from response.prepare(request)
await response.prepare(request)

unsub_stream = hass.bus.async_listen(MATCH_ALL, forward_events)

try:
_LOGGER.debug('STREAM %s ATTACHED', id(stop_obj))

# Fire off one message so browsers fire open event right away
yield from to_write.put(STREAM_PING_PAYLOAD)
await to_write.put(STREAM_PING_PAYLOAD)

while True:
try:
with async_timeout.timeout(STREAM_PING_INTERVAL,
loop=hass.loop):
payload = yield from to_write.get()
payload = await to_write.get()

if payload is stop_obj:
break

msg = "data: {}\n\n".format(payload)
_LOGGER.debug('STREAM %s WRITING %s', id(stop_obj),
msg.strip())
yield from response.write(msg.encode("UTF-8"))
await response.write(msg.encode("UTF-8"))
except asyncio.TimeoutError:
yield from to_write.put(STREAM_PING_PAYLOAD)
await to_write.put(STREAM_PING_PAYLOAD)

except asyncio.CancelledError:
_LOGGER.debug('STREAM %s ABORT', id(stop_obj))
Expand Down Expand Up @@ -200,12 +198,11 @@ def get(self, request, entity_id):
return self.json(state)
return self.json_message('Entity not found', HTTP_NOT_FOUND)

@asyncio.coroutine
def post(self, request, entity_id):
async def post(self, request, entity_id):
"""Update state of entity."""
hass = request.app['hass']
try:
data = yield from request.json()
data = await request.json()
except ValueError:
return self.json_message('Invalid JSON specified',
HTTP_BAD_REQUEST)
Expand Down Expand Up @@ -257,10 +254,9 @@ class APIEventView(HomeAssistantView):
url = '/api/events/{event_type}'
name = "api:event"

@asyncio.coroutine
def post(self, request, event_type):
async def post(self, request, event_type):
"""Fire events."""
body = yield from request.text()
body = await request.text()
try:
event_data = json.loads(body) if body else None
except ValueError:
Expand Down Expand Up @@ -292,10 +288,9 @@ class APIServicesView(HomeAssistantView):
url = URL_API_SERVICES
name = "api:services"

@asyncio.coroutine
def get(self, request):
async def get(self, request):
"""Get registered services."""
services = yield from async_services_json(request.app['hass'])
services = await async_services_json(request.app['hass'])
return self.json(services)


Expand All @@ -305,22 +300,21 @@ class APIDomainServicesView(HomeAssistantView):
url = "/api/services/{domain}/{service}"
name = "api:domain-services"

@asyncio.coroutine
def post(self, request, domain, service):
async def post(self, request, domain, service):
"""Call a service.

Returns a list of changed states.
"""
hass = request.app['hass']
body = yield from request.text()
body = await request.text()
try:
data = json.loads(body) if body else None
except ValueError:
return self.json_message('Data should be valid JSON',
HTTP_BAD_REQUEST)

with AsyncTrackStates(hass) as changed_states:
yield from hass.services.async_call(domain, service, data, True)
await hass.services.async_call(domain, service, data, True)

return self.json(changed_states)

Expand All @@ -343,11 +337,10 @@ class APITemplateView(HomeAssistantView):
url = URL_API_TEMPLATE
name = "api:template"

@asyncio.coroutine
def post(self, request):
async def post(self, request):
"""Render a template."""
try:
data = yield from request.json()
data = await request.json()
tpl = template.Template(data['template'], request.app['hass'])
return tpl.async_render(data.get('variables'))
except (ValueError, TemplateError) as ex:
Expand All @@ -366,10 +359,9 @@ async def get(self, request):
return await self.file(request, request.app['hass'].data[DATA_LOGGING])


@asyncio.coroutine
def async_services_json(hass):
async def async_services_json(hass):
"""Generate services data to JSONify."""
descriptions = yield from async_get_all_descriptions(hass)
descriptions = await async_get_all_descriptions(hass)
return [{"domain": key, "services": value}
for key, value in descriptions.items()]

Expand Down
9 changes: 4 additions & 5 deletions homeassistant/components/device_tracker/gpslogger.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.gpslogger/
"""
import asyncio
import logging
from hmac import compare_digest

Expand All @@ -22,6 +21,7 @@
from homeassistant.components.device_tracker import ( # NOQA
DOMAIN, PLATFORM_SCHEMA
)
from homeassistant.helpers.typing import HomeAssistantType, ConfigType

_LOGGER = logging.getLogger(__name__)

Expand All @@ -32,8 +32,8 @@
})


@asyncio.coroutine
def async_setup_scanner(hass, config, async_see, discovery_info=None):
async def async_setup_scanner(hass: HomeAssistantType, config: ConfigType,
async_see, discovery_info=None):
"""Set up an endpoint for the GPSLogger application."""
hass.http.register_view(GPSLoggerView(async_see, config))

Expand All @@ -54,8 +54,7 @@ def __init__(self, async_see, config):
# password is set
self.requires_auth = self._password is None

@asyncio.coroutine
def get(self, request: Request):
async def get(self, request: Request):
"""Handle for GPSLogger message received as GET."""
hass = request.app['hass']
data = request.query
Expand Down
Loading