Skip to content

Commit

Permalink
Merge pull request #17970 from home-assistant/rc
Browse files Browse the repository at this point in the history
0.81.2
  • Loading branch information
balloob committed Oct 30, 2018
2 parents b6a7994 + 1e03f94 commit 2aabdf2
Show file tree
Hide file tree
Showing 29 changed files with 94 additions and 147 deletions.
10 changes: 5 additions & 5 deletions homeassistant/components/apple_tv.py
Expand Up @@ -163,7 +163,7 @@ async def async_service_handler(service):

async def atv_discovered(service, info):
"""Set up an Apple TV that was auto discovered."""
await _setup_atv(hass, {
await _setup_atv(hass, config, {
CONF_NAME: info['name'],
CONF_HOST: info['host'],
CONF_LOGIN_ID: info['properties']['hG'],
Expand All @@ -172,7 +172,7 @@ async def atv_discovered(service, info):

discovery.async_listen(hass, SERVICE_APPLE_TV, atv_discovered)

tasks = [_setup_atv(hass, conf) for conf in config.get(DOMAIN, [])]
tasks = [_setup_atv(hass, config, conf) for conf in config.get(DOMAIN, [])]
if tasks:
await asyncio.wait(tasks, loop=hass.loop)

Expand All @@ -187,7 +187,7 @@ async def atv_discovered(service, info):
return True


async def _setup_atv(hass, atv_config):
async def _setup_atv(hass, hass_config, atv_config):
"""Set up an Apple TV."""
import pyatv
name = atv_config.get(CONF_NAME)
Expand All @@ -212,10 +212,10 @@ async def _setup_atv(hass, atv_config):
}

hass.async_create_task(discovery.async_load_platform(
hass, 'media_player', DOMAIN, atv_config))
hass, 'media_player', DOMAIN, atv_config, hass_config))

hass.async_create_task(discovery.async_load_platform(
hass, 'remote', DOMAIN, atv_config))
hass, 'remote', DOMAIN, atv_config, hass_config))


class AppleTVPowerManager:
Expand Down
68 changes: 3 additions & 65 deletions homeassistant/components/cloud/__init__.py
Expand Up @@ -4,20 +4,16 @@
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/cloud/
"""
import asyncio
from datetime import datetime, timedelta
import json
import logging
import os

import aiohttp
import async_timeout
import voluptuous as vol

from homeassistant.const import (
EVENT_HOMEASSISTANT_START, CONF_REGION, CONF_MODE, CONF_NAME)
from homeassistant.helpers import entityfilter, config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.util import dt as dt_util
from homeassistant.components.alexa import smart_home as alexa_sh
from homeassistant.components.google_assistant import helpers as ga_h
Expand Down Expand Up @@ -129,7 +125,6 @@ def __init__(self, hass, mode, alexa, google_actions,
self._google_actions = google_actions
self._gactions_config = None
self._prefs = None
self.jwt_keyset = None
self.id_token = None
self.access_token = None
self.refresh_token = None
Expand Down Expand Up @@ -262,13 +257,6 @@ async def async_start(self, _):
}
self._prefs = prefs

success = await self._fetch_jwt_keyset()

# Fetching keyset can fail if internet is not up yet.
if not success:
self.hass.helpers.event.async_call_later(5, self.async_start)
return

def load_config():
"""Load config."""
# Ensure config dir exists
Expand All @@ -288,14 +276,6 @@ def load_config():
if info is None:
return

# Validate tokens
try:
for token in 'id_token', 'access_token':
self._decode_claims(info[token])
except ValueError as err: # Raised when token is invalid
_LOGGER.warning("Found invalid token %s: %s", token, err)
return

self.id_token = info['id_token']
self.access_token = info['access_token']
self.refresh_token = info['refresh_token']
Expand All @@ -311,49 +291,7 @@ async def update_preferences(self, *, google_enabled=_UNDEF,
self._prefs[STORAGE_ENABLE_ALEXA] = alexa_enabled
await self._store.async_save(self._prefs)

async def _fetch_jwt_keyset(self):
"""Fetch the JWT keyset for the Cognito instance."""
session = async_get_clientsession(self.hass)
url = ("https://cognito-idp.us-east-1.amazonaws.com/"
"{}/.well-known/jwks.json".format(self.user_pool_id))

try:
with async_timeout.timeout(10, loop=self.hass.loop):
req = await session.get(url)
self.jwt_keyset = await req.json()

return True

except (asyncio.TimeoutError, aiohttp.ClientError) as err:
_LOGGER.error("Error fetching Cognito keyset: %s", err)
return False

def _decode_claims(self, token):
def _decode_claims(self, token): # pylint: disable=no-self-use
"""Decode the claims in a token."""
from jose import jwt, exceptions as jose_exceptions
try:
header = jwt.get_unverified_header(token)
except jose_exceptions.JWTError as err:
raise ValueError(str(err)) from None
kid = header.get('kid')

if kid is None:
raise ValueError("No kid in header")

# Locate the key for this kid
key = None
for key_dict in self.jwt_keyset['keys']:
if key_dict['kid'] == kid:
key = key_dict
break
if not key:
raise ValueError(
"Unable to locate kid ({}) in keyset".format(kid))

try:
return jwt.decode(
token, key, audience=self.cognito_client_id, options={
'verify_exp': False,
})
except jose_exceptions.JWTError as err:
raise ValueError(str(err)) from None
from jose import jwt
return jwt.get_unverified_claims(token)
3 changes: 2 additions & 1 deletion homeassistant/components/elkm1/__init__.py
Expand Up @@ -146,7 +146,8 @@ def _included(ranges, set_to, values):
hass.data[DOMAIN] = {'elk': elk, 'config': config, 'keypads': {}}
for component in SUPPORTED_DOMAINS:
hass.async_create_task(
discovery.async_load_platform(hass, component, DOMAIN, {}))
discovery.async_load_platform(hass, component, DOMAIN, {},
hass_config))

return True

Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/evohome.py
Expand Up @@ -140,6 +140,6 @@ def setup(hass, config):

_LOGGER.debug("setup(), location = %s", tmp_loc)

load_platform(hass, 'climate', DOMAIN)
load_platform(hass, 'climate', DOMAIN, {}, config)

return True
22 changes: 13 additions & 9 deletions homeassistant/components/google.py
Expand Up @@ -88,7 +88,7 @@
}, extra=vol.ALLOW_EXTRA)


def do_authentication(hass, config):
def do_authentication(hass, hass_config, config):
"""Notify user of actions and authenticate.
Notify user of user_code and verification_url then poll
Expand Down Expand Up @@ -145,7 +145,7 @@ def step2_exchange(now):

storage = Storage(hass.config.path(TOKEN_FILE))
storage.put(credentials)
do_setup(hass, config)
do_setup(hass, hass_config, config)
listener()
hass.components.persistent_notification.create(
'We are all setup now. Check {} for calendars that have '
Expand All @@ -167,14 +167,15 @@ def setup(hass, config):

token_file = hass.config.path(TOKEN_FILE)
if not os.path.isfile(token_file):
do_authentication(hass, conf)
do_authentication(hass, config, conf)
else:
do_setup(hass, conf)
do_setup(hass, config, conf)

return True


def setup_services(hass, track_new_found_calendars, calendar_service):
def setup_services(hass, hass_config, track_new_found_calendars,
calendar_service):
"""Set up the service listeners."""
def _found_calendar(call):
"""Check if we know about a calendar and generate PLATFORM_DISCOVER."""
Expand All @@ -190,7 +191,8 @@ def _found_calendar(call):
)

discovery.load_platform(hass, 'calendar', DOMAIN,
hass.data[DATA_INDEX][calendar[CONF_CAL_ID]])
hass.data[DATA_INDEX][calendar[CONF_CAL_ID]],
hass_config)

hass.services.register(
DOMAIN, SERVICE_FOUND_CALENDARS, _found_calendar)
Expand All @@ -210,21 +212,23 @@ def _scan_for_calendars(service):
return True


def do_setup(hass, config):
def do_setup(hass, hass_config, config):
"""Run the setup after we have everything configured."""
# Load calendars the user has configured
hass.data[DATA_INDEX] = load_config(hass.config.path(YAML_DEVICES))

calendar_service = GoogleCalendarService(hass.config.path(TOKEN_FILE))
track_new_found_calendars = convert(config.get(CONF_TRACK_NEW),
bool, DEFAULT_CONF_TRACK_NEW)
setup_services(hass, track_new_found_calendars, calendar_service)
setup_services(hass, hass_config, track_new_found_calendars,
calendar_service)

# Ensure component is loaded
setup_component(hass, 'calendar', config)

for calendar in hass.data[DATA_INDEX].values():
discovery.load_platform(hass, 'calendar', DOMAIN, calendar)
discovery.load_platform(hass, 'calendar', DOMAIN, calendar,
hass_config)

# Look for any new calendars
hass.services.call(DOMAIN, SERVICE_SCAN_CALENDARS, None)
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/maxcube.py
Expand Up @@ -73,8 +73,8 @@ def setup(hass, config):
if connection_failed >= len(gateways):
return False

load_platform(hass, 'climate', DOMAIN)
load_platform(hass, 'binary_sensor', DOMAIN)
load_platform(hass, 'climate', DOMAIN, {}, config)
load_platform(hass, 'binary_sensor', DOMAIN, {}, config)

return True

Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/melissa.py
Expand Up @@ -39,6 +39,6 @@ def setup(hass, config):
api = melissa.Melissa(username=username, password=password)
hass.data[DATA_MELISSA] = api

load_platform(hass, 'sensor', DOMAIN, {})
load_platform(hass, 'climate', DOMAIN, {})
load_platform(hass, 'sensor', DOMAIN, {}, config)
load_platform(hass, 'climate', DOMAIN, {}, config)
return True
2 changes: 1 addition & 1 deletion homeassistant/components/mysensors/__init__.py
Expand Up @@ -111,7 +111,7 @@ async def async_setup(hass, config):

hass.data[MYSENSORS_GATEWAYS] = gateways

hass.async_create_task(finish_setup(hass, gateways))
hass.async_create_task(finish_setup(hass, config, gateways))

return True

Expand Down
21 changes: 12 additions & 9 deletions homeassistant/components/mysensors/gateway.py
Expand Up @@ -137,20 +137,21 @@ def internal_callback(*args):
gateway.metric = hass.config.units.is_metric
gateway.optimistic = conf[CONF_OPTIMISTIC]
gateway.device = device
gateway.event_callback = _gw_callback_factory(hass)
gateway.event_callback = _gw_callback_factory(hass, config)
gateway.nodes_config = gateway_conf[CONF_NODES]
if persistence:
await gateway.start_persistence()

return gateway


async def finish_setup(hass, gateways):
async def finish_setup(hass, hass_config, gateways):
"""Load any persistent devices and platforms and start gateway."""
discover_tasks = []
start_tasks = []
for gateway in gateways.values():
discover_tasks.append(_discover_persistent_devices(hass, gateway))
discover_tasks.append(_discover_persistent_devices(
hass, hass_config, gateway))
start_tasks.append(_gw_start(hass, gateway))
if discover_tasks:
# Make sure all devices and platforms are loaded before gateway start.
Expand All @@ -159,7 +160,7 @@ async def finish_setup(hass, gateways):
await asyncio.wait(start_tasks, loop=hass.loop)


async def _discover_persistent_devices(hass, gateway):
async def _discover_persistent_devices(hass, hass_config, gateway):
"""Discover platforms for devices loaded via persistence file."""
tasks = []
new_devices = defaultdict(list)
Expand All @@ -170,17 +171,18 @@ async def _discover_persistent_devices(hass, gateway):
for platform, dev_ids in validated.items():
new_devices[platform].extend(dev_ids)
for platform, dev_ids in new_devices.items():
tasks.append(_discover_mysensors_platform(hass, platform, dev_ids))
tasks.append(_discover_mysensors_platform(
hass, hass_config, platform, dev_ids))
if tasks:
await asyncio.wait(tasks, loop=hass.loop)


@callback
def _discover_mysensors_platform(hass, platform, new_devices):
def _discover_mysensors_platform(hass, hass_config, platform, new_devices):
"""Discover a MySensors platform."""
task = hass.async_create_task(discovery.async_load_platform(
hass, platform, DOMAIN,
{ATTR_DEVICES: new_devices, CONF_NAME: DOMAIN}))
{ATTR_DEVICES: new_devices, CONF_NAME: DOMAIN}, hass_config))
return task


Expand Down Expand Up @@ -215,7 +217,7 @@ def gw_stop(event):
hass.data.pop(gateway_ready_key, None)


def _gw_callback_factory(hass):
def _gw_callback_factory(hass, hass_config):
"""Return a new callback for the gateway."""
@callback
def mysensors_callback(msg):
Expand Down Expand Up @@ -246,7 +248,8 @@ def mysensors_callback(msg):
else:
new_dev_ids.append(dev_id)
if new_dev_ids:
_discover_mysensors_platform(hass, platform, new_dev_ids)
_discover_mysensors_platform(
hass, hass_config, platform, new_dev_ids)
for signal in set(signals):
# Only one signal per device is needed.
# A device can have multiple platforms, ie multiple schemas.
Expand Down
5 changes: 3 additions & 2 deletions homeassistant/components/octoprint.py
Expand Up @@ -114,11 +114,12 @@ def device_discovered(service, info):
sensors = printer[CONF_SENSORS][CONF_MONITORED_CONDITIONS]
load_platform(hass, 'sensor', DOMAIN, {'name': name,
'base_url': base_url,
'sensors': sensors})
'sensors': sensors}, config)
b_sensors = printer[CONF_BINARY_SENSORS][CONF_MONITORED_CONDITIONS]
load_platform(hass, 'binary_sensor', DOMAIN, {'name': name,
'base_url': base_url,
'sensors': b_sensors})
'sensors': b_sensors},
config)
success = True

return success
Expand Down
11 changes: 6 additions & 5 deletions homeassistant/components/opentherm_gw.py
Expand Up @@ -64,9 +64,10 @@ async def async_setup(hass, config):
hass.async_create_task(connect_and_subscribe(
hass, conf[CONF_DEVICE], gateway))
hass.async_create_task(async_load_platform(
hass, 'climate', DOMAIN, conf.get(CONF_CLIMATE)))
hass, 'climate', DOMAIN, conf.get(CONF_CLIMATE), config))
if monitored_vars:
hass.async_create_task(setup_monitored_vars(hass, monitored_vars))
hass.async_create_task(setup_monitored_vars(
hass, config, monitored_vars))
return True


Expand All @@ -82,7 +83,7 @@ async def handle_report(status):
gateway.subscribe(handle_report)


async def setup_monitored_vars(hass, monitored_vars):
async def setup_monitored_vars(hass, config, monitored_vars):
"""Set up requested sensors."""
gw_vars = hass.data[DATA_OPENTHERM_GW][DATA_GW_VARS]
sensor_type_map = {
Expand Down Expand Up @@ -200,6 +201,6 @@ async def setup_monitored_vars(hass, monitored_vars):
_LOGGER.error("Monitored variable not supported: %s", var)
if binary_sensors:
hass.async_create_task(async_load_platform(
hass, COMP_BINARY_SENSOR, DOMAIN, binary_sensors))
hass, COMP_BINARY_SENSOR, DOMAIN, binary_sensors, config))
if sensors:
await async_load_platform(hass, COMP_SENSOR, DOMAIN, sensors)
await async_load_platform(hass, COMP_SENSOR, DOMAIN, sensors, config)

0 comments on commit 2aabdf2

Please sign in to comment.