Merge pull request #17970 from home-assistant/rc

0.81.2
pull/18005/head 0.81.2
Paulus Schoutsen 2018-10-30 08:13:59 +01:00 committed by GitHub
commit 2aabdf29bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 94 additions and 147 deletions

View File

@ -163,7 +163,7 @@ async def async_setup(hass, config):
async def atv_discovered(service, info): async def atv_discovered(service, info):
"""Set up an Apple TV that was auto discovered.""" """Set up an Apple TV that was auto discovered."""
await _setup_atv(hass, { await _setup_atv(hass, config, {
CONF_NAME: info['name'], CONF_NAME: info['name'],
CONF_HOST: info['host'], CONF_HOST: info['host'],
CONF_LOGIN_ID: info['properties']['hG'], CONF_LOGIN_ID: info['properties']['hG'],
@ -172,7 +172,7 @@ async def async_setup(hass, config):
discovery.async_listen(hass, SERVICE_APPLE_TV, atv_discovered) 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: if tasks:
await asyncio.wait(tasks, loop=hass.loop) await asyncio.wait(tasks, loop=hass.loop)
@ -187,7 +187,7 @@ async def async_setup(hass, config):
return True return True
async def _setup_atv(hass, atv_config): async def _setup_atv(hass, hass_config, atv_config):
"""Set up an Apple TV.""" """Set up an Apple TV."""
import pyatv import pyatv
name = atv_config.get(CONF_NAME) name = atv_config.get(CONF_NAME)
@ -212,10 +212,10 @@ async def _setup_atv(hass, atv_config):
} }
hass.async_create_task(discovery.async_load_platform( 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.async_create_task(discovery.async_load_platform(
hass, 'remote', DOMAIN, atv_config)) hass, 'remote', DOMAIN, atv_config, hass_config))
class AppleTVPowerManager: class AppleTVPowerManager:

View File

@ -4,20 +4,16 @@ Component to integrate the Home Assistant cloud.
For more details about this component, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/cloud/ https://home-assistant.io/components/cloud/
""" """
import asyncio
from datetime import datetime, timedelta from datetime import datetime, timedelta
import json import json
import logging import logging
import os import os
import aiohttp
import async_timeout
import voluptuous as vol import voluptuous as vol
from homeassistant.const import ( from homeassistant.const import (
EVENT_HOMEASSISTANT_START, CONF_REGION, CONF_MODE, CONF_NAME) EVENT_HOMEASSISTANT_START, CONF_REGION, CONF_MODE, CONF_NAME)
from homeassistant.helpers import entityfilter, config_validation as cv 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.util import dt as dt_util
from homeassistant.components.alexa import smart_home as alexa_sh from homeassistant.components.alexa import smart_home as alexa_sh
from homeassistant.components.google_assistant import helpers as ga_h from homeassistant.components.google_assistant import helpers as ga_h
@ -129,7 +125,6 @@ class Cloud:
self._google_actions = google_actions self._google_actions = google_actions
self._gactions_config = None self._gactions_config = None
self._prefs = None self._prefs = None
self.jwt_keyset = None
self.id_token = None self.id_token = None
self.access_token = None self.access_token = None
self.refresh_token = None self.refresh_token = None
@ -262,13 +257,6 @@ class Cloud:
} }
self._prefs = prefs 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(): def load_config():
"""Load config.""" """Load config."""
# Ensure config dir exists # Ensure config dir exists
@ -288,14 +276,6 @@ class Cloud:
if info is None: if info is None:
return 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.id_token = info['id_token']
self.access_token = info['access_token'] self.access_token = info['access_token']
self.refresh_token = info['refresh_token'] self.refresh_token = info['refresh_token']
@ -311,49 +291,7 @@ class Cloud:
self._prefs[STORAGE_ENABLE_ALEXA] = alexa_enabled self._prefs[STORAGE_ENABLE_ALEXA] = alexa_enabled
await self._store.async_save(self._prefs) await self._store.async_save(self._prefs)
async def _fetch_jwt_keyset(self): def _decode_claims(self, token): # pylint: disable=no-self-use
"""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):
"""Decode the claims in a token.""" """Decode the claims in a token."""
from jose import jwt, exceptions as jose_exceptions from jose import jwt
try: return jwt.get_unverified_claims(token)
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

View File

@ -146,7 +146,8 @@ async def async_setup(hass: HomeAssistant, hass_config: ConfigType) -> bool:
hass.data[DOMAIN] = {'elk': elk, 'config': config, 'keypads': {}} hass.data[DOMAIN] = {'elk': elk, 'config': config, 'keypads': {}}
for component in SUPPORTED_DOMAINS: for component in SUPPORTED_DOMAINS:
hass.async_create_task( hass.async_create_task(
discovery.async_load_platform(hass, component, DOMAIN, {})) discovery.async_load_platform(hass, component, DOMAIN, {},
hass_config))
return True return True

View File

@ -140,6 +140,6 @@ def setup(hass, config):
_LOGGER.debug("setup(), location = %s", tmp_loc) _LOGGER.debug("setup(), location = %s", tmp_loc)
load_platform(hass, 'climate', DOMAIN) load_platform(hass, 'climate', DOMAIN, {}, config)
return True return True

View File

@ -88,7 +88,7 @@ DEVICE_SCHEMA = vol.Schema({
}, extra=vol.ALLOW_EXTRA) }, 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 actions and authenticate.
Notify user of user_code and verification_url then poll Notify user of user_code and verification_url then poll
@ -145,7 +145,7 @@ def do_authentication(hass, config):
storage = Storage(hass.config.path(TOKEN_FILE)) storage = Storage(hass.config.path(TOKEN_FILE))
storage.put(credentials) storage.put(credentials)
do_setup(hass, config) do_setup(hass, hass_config, config)
listener() listener()
hass.components.persistent_notification.create( hass.components.persistent_notification.create(
'We are all setup now. Check {} for calendars that have ' 'We are all setup now. Check {} for calendars that have '
@ -167,14 +167,15 @@ def setup(hass, config):
token_file = hass.config.path(TOKEN_FILE) token_file = hass.config.path(TOKEN_FILE)
if not os.path.isfile(token_file): if not os.path.isfile(token_file):
do_authentication(hass, conf) do_authentication(hass, config, conf)
else: else:
do_setup(hass, conf) do_setup(hass, config, conf)
return True 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.""" """Set up the service listeners."""
def _found_calendar(call): def _found_calendar(call):
"""Check if we know about a calendar and generate PLATFORM_DISCOVER.""" """Check if we know about a calendar and generate PLATFORM_DISCOVER."""
@ -190,7 +191,8 @@ def setup_services(hass, track_new_found_calendars, calendar_service):
) )
discovery.load_platform(hass, 'calendar', DOMAIN, 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( hass.services.register(
DOMAIN, SERVICE_FOUND_CALENDARS, _found_calendar) DOMAIN, SERVICE_FOUND_CALENDARS, _found_calendar)
@ -210,7 +212,7 @@ def setup_services(hass, track_new_found_calendars, calendar_service):
return True return True
def do_setup(hass, config): def do_setup(hass, hass_config, config):
"""Run the setup after we have everything configured.""" """Run the setup after we have everything configured."""
# Load calendars the user has configured # Load calendars the user has configured
hass.data[DATA_INDEX] = load_config(hass.config.path(YAML_DEVICES)) hass.data[DATA_INDEX] = load_config(hass.config.path(YAML_DEVICES))
@ -218,13 +220,15 @@ def do_setup(hass, config):
calendar_service = GoogleCalendarService(hass.config.path(TOKEN_FILE)) calendar_service = GoogleCalendarService(hass.config.path(TOKEN_FILE))
track_new_found_calendars = convert(config.get(CONF_TRACK_NEW), track_new_found_calendars = convert(config.get(CONF_TRACK_NEW),
bool, DEFAULT_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 # Ensure component is loaded
setup_component(hass, 'calendar', config) setup_component(hass, 'calendar', config)
for calendar in hass.data[DATA_INDEX].values(): 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 # Look for any new calendars
hass.services.call(DOMAIN, SERVICE_SCAN_CALENDARS, None) hass.services.call(DOMAIN, SERVICE_SCAN_CALENDARS, None)

View File

@ -73,8 +73,8 @@ def setup(hass, config):
if connection_failed >= len(gateways): if connection_failed >= len(gateways):
return False return False
load_platform(hass, 'climate', DOMAIN) load_platform(hass, 'climate', DOMAIN, {}, config)
load_platform(hass, 'binary_sensor', DOMAIN) load_platform(hass, 'binary_sensor', DOMAIN, {}, config)
return True return True

View File

@ -39,6 +39,6 @@ def setup(hass, config):
api = melissa.Melissa(username=username, password=password) api = melissa.Melissa(username=username, password=password)
hass.data[DATA_MELISSA] = api hass.data[DATA_MELISSA] = api
load_platform(hass, 'sensor', DOMAIN, {}) load_platform(hass, 'sensor', DOMAIN, {}, config)
load_platform(hass, 'climate', DOMAIN, {}) load_platform(hass, 'climate', DOMAIN, {}, config)
return True return True

View File

@ -111,7 +111,7 @@ async def async_setup(hass, config):
hass.data[MYSENSORS_GATEWAYS] = gateways hass.data[MYSENSORS_GATEWAYS] = gateways
hass.async_create_task(finish_setup(hass, gateways)) hass.async_create_task(finish_setup(hass, config, gateways))
return True return True

View File

@ -137,7 +137,7 @@ async def _get_gateway(hass, config, gateway_conf, persistence_file):
gateway.metric = hass.config.units.is_metric gateway.metric = hass.config.units.is_metric
gateway.optimistic = conf[CONF_OPTIMISTIC] gateway.optimistic = conf[CONF_OPTIMISTIC]
gateway.device = device 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] gateway.nodes_config = gateway_conf[CONF_NODES]
if persistence: if persistence:
await gateway.start_persistence() await gateway.start_persistence()
@ -145,12 +145,13 @@ async def _get_gateway(hass, config, gateway_conf, persistence_file):
return gateway 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.""" """Load any persistent devices and platforms and start gateway."""
discover_tasks = [] discover_tasks = []
start_tasks = [] start_tasks = []
for gateway in gateways.values(): 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)) start_tasks.append(_gw_start(hass, gateway))
if discover_tasks: if discover_tasks:
# Make sure all devices and platforms are loaded before gateway start. # Make sure all devices and platforms are loaded before gateway start.
@ -159,7 +160,7 @@ async def finish_setup(hass, gateways):
await asyncio.wait(start_tasks, loop=hass.loop) 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.""" """Discover platforms for devices loaded via persistence file."""
tasks = [] tasks = []
new_devices = defaultdict(list) new_devices = defaultdict(list)
@ -170,17 +171,18 @@ async def _discover_persistent_devices(hass, gateway):
for platform, dev_ids in validated.items(): for platform, dev_ids in validated.items():
new_devices[platform].extend(dev_ids) new_devices[platform].extend(dev_ids)
for platform, dev_ids in new_devices.items(): 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: if tasks:
await asyncio.wait(tasks, loop=hass.loop) await asyncio.wait(tasks, loop=hass.loop)
@callback @callback
def _discover_mysensors_platform(hass, platform, new_devices): def _discover_mysensors_platform(hass, hass_config, platform, new_devices):
"""Discover a MySensors platform.""" """Discover a MySensors platform."""
task = hass.async_create_task(discovery.async_load_platform( task = hass.async_create_task(discovery.async_load_platform(
hass, platform, DOMAIN, hass, platform, DOMAIN,
{ATTR_DEVICES: new_devices, CONF_NAME: DOMAIN})) {ATTR_DEVICES: new_devices, CONF_NAME: DOMAIN}, hass_config))
return task return task
@ -215,7 +217,7 @@ async def _gw_start(hass, gateway):
hass.data.pop(gateway_ready_key, None) 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.""" """Return a new callback for the gateway."""
@callback @callback
def mysensors_callback(msg): def mysensors_callback(msg):
@ -246,7 +248,8 @@ def _gw_callback_factory(hass):
else: else:
new_dev_ids.append(dev_id) new_dev_ids.append(dev_id)
if new_dev_ids: 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): for signal in set(signals):
# Only one signal per device is needed. # Only one signal per device is needed.
# A device can have multiple platforms, ie multiple schemas. # A device can have multiple platforms, ie multiple schemas.

View File

@ -114,11 +114,12 @@ def setup(hass, config):
sensors = printer[CONF_SENSORS][CONF_MONITORED_CONDITIONS] sensors = printer[CONF_SENSORS][CONF_MONITORED_CONDITIONS]
load_platform(hass, 'sensor', DOMAIN, {'name': name, load_platform(hass, 'sensor', DOMAIN, {'name': name,
'base_url': base_url, 'base_url': base_url,
'sensors': sensors}) 'sensors': sensors}, config)
b_sensors = printer[CONF_BINARY_SENSORS][CONF_MONITORED_CONDITIONS] b_sensors = printer[CONF_BINARY_SENSORS][CONF_MONITORED_CONDITIONS]
load_platform(hass, 'binary_sensor', DOMAIN, {'name': name, load_platform(hass, 'binary_sensor', DOMAIN, {'name': name,
'base_url': base_url, 'base_url': base_url,
'sensors': b_sensors}) 'sensors': b_sensors},
config)
success = True success = True
return success return success

View File

@ -64,9 +64,10 @@ async def async_setup(hass, config):
hass.async_create_task(connect_and_subscribe( hass.async_create_task(connect_and_subscribe(
hass, conf[CONF_DEVICE], gateway)) hass, conf[CONF_DEVICE], gateway))
hass.async_create_task(async_load_platform( 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: 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 return True
@ -82,7 +83,7 @@ async def connect_and_subscribe(hass, device_path, gateway):
gateway.subscribe(handle_report) 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.""" """Set up requested sensors."""
gw_vars = hass.data[DATA_OPENTHERM_GW][DATA_GW_VARS] gw_vars = hass.data[DATA_OPENTHERM_GW][DATA_GW_VARS]
sensor_type_map = { sensor_type_map = {
@ -200,6 +201,6 @@ async def setup_monitored_vars(hass, monitored_vars):
_LOGGER.error("Monitored variable not supported: %s", var) _LOGGER.error("Monitored variable not supported: %s", var)
if binary_sensors: if binary_sensors:
hass.async_create_task(async_load_platform( hass.async_create_task(async_load_platform(
hass, COMP_BINARY_SENSOR, DOMAIN, binary_sensors)) hass, COMP_BINARY_SENSOR, DOMAIN, binary_sensors, config))
if sensors: if sensors:
await async_load_platform(hass, COMP_SENSOR, DOMAIN, sensors) await async_load_platform(hass, COMP_SENSOR, DOMAIN, sensors, config)

View File

@ -66,8 +66,8 @@ def setup(hass, config):
return False return False
hass.data[DATA_SMAPPEE] = smappee hass.data[DATA_SMAPPEE] = smappee
load_platform(hass, 'switch', DOMAIN) load_platform(hass, 'switch', DOMAIN, {}, config)
load_platform(hass, 'sensor', DOMAIN) load_platform(hass, 'sensor', DOMAIN, {}, config)
return True return True

View File

@ -63,11 +63,11 @@ async def async_setup(hass, config):
# add sensor devices for each zone (typically motion/fire/door sensors) # add sensor devices for each zone (typically motion/fire/door sensors)
hass.async_create_task(discovery.async_load_platform( hass.async_create_task(discovery.async_load_platform(
hass, 'binary_sensor', DOMAIN, {})) hass, 'binary_sensor', DOMAIN, {}, config))
# create a separate alarm panel for each area # create a separate alarm panel for each area
hass.async_create_task(discovery.async_load_platform( hass.async_create_task(discovery.async_load_platform(
hass, 'alarm_control_panel', DOMAIN, {})) hass, 'alarm_control_panel', DOMAIN, {}, config))
# start listening for incoming events over websocket # start listening for incoming events over websocket
spc.start() spc.start()

View File

@ -56,7 +56,7 @@ def setup(hass, config):
} }
for component in SPIDER_COMPONENTS: for component in SPIDER_COMPONENTS:
load_platform(hass, component, DOMAIN, {}) load_platform(hass, component, DOMAIN, {}, config)
_LOGGER.debug("Connection with Spider API succeeded") _LOGGER.debug("Connection with Spider API succeeded")
return True return True

View File

@ -32,20 +32,21 @@ async def async_setup(hass, config):
async def async_setup_entry(hass, config_entry): async def async_setup_entry(hass, config_entry):
"""Set up the UniFi component.""" """Set up the UniFi component."""
controller = UniFiController(hass, config_entry)
if DOMAIN not in hass.data: if DOMAIN not in hass.data:
hass.data[DOMAIN] = {} hass.data[DOMAIN] = {}
controller = UniFiController(hass, config_entry)
controller_id = CONTROLLER_ID.format( controller_id = CONTROLLER_ID.format(
host=config_entry.data[CONF_CONTROLLER][CONF_HOST], host=config_entry.data[CONF_CONTROLLER][CONF_HOST],
site=config_entry.data[CONF_CONTROLLER][CONF_SITE_ID] site=config_entry.data[CONF_CONTROLLER][CONF_SITE_ID]
) )
hass.data[DOMAIN][controller_id] = controller
if not await controller.async_setup(): if not await controller.async_setup():
return False return False
hass.data[DOMAIN][controller_id] = controller
if controller.mac is None: if controller.mac is None:
return True return True

View File

@ -2,7 +2,7 @@
"""Constants used by Home Assistant components.""" """Constants used by Home Assistant components."""
MAJOR_VERSION = 0 MAJOR_VERSION = 0
MINOR_VERSION = 81 MINOR_VERSION = 81
PATCH_VERSION = '1' PATCH_VERSION = '2'
__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, 5, 3) REQUIRED_PYTHON_VER = (3, 5, 3)

View File

@ -114,8 +114,7 @@ def async_listen_platform(hass, component, callback):
@bind_hass @bind_hass
def load_platform(hass, component, platform, discovered=None, def load_platform(hass, component, platform, discovered, hass_config):
hass_config=None):
"""Load a component and platform dynamically. """Load a component and platform dynamically.
Target components will be loaded and an EVENT_PLATFORM_DISCOVERED will be Target components will be loaded and an EVENT_PLATFORM_DISCOVERED will be
@ -132,8 +131,8 @@ def load_platform(hass, component, platform, discovered=None,
@bind_hass @bind_hass
async def async_load_platform(hass, component, platform, discovered=None, async def async_load_platform(hass, component, platform, discovered,
hass_config=None): hass_config):
"""Load a component and platform dynamically. """Load a component and platform dynamically.
Target components will be loaded and an EVENT_PLATFORM_DISCOVERED will be Target components will be loaded and an EVENT_PLATFORM_DISCOVERED will be
@ -149,6 +148,8 @@ async def async_load_platform(hass, component, platform, discovered=None,
This method is a coroutine. This method is a coroutine.
""" """
assert hass_config, 'You need to pass in the real hass config'
if component in DEPENDENCY_BLACKLIST: if component in DEPENDENCY_BLACKLIST:
raise HomeAssistantError( raise HomeAssistantError(
'Cannot discover the {} component.'.format(component)) 'Cannot discover the {} component.'.format(component))

View File

@ -10,7 +10,7 @@ cryptography==2.3.1
pip>=8.0.3 pip>=8.0.3
pytz>=2018.04 pytz>=2018.04
pyyaml>=3.13,<4 pyyaml>=3.13,<4
requests==2.19.1 requests==2.20.0
voluptuous==0.11.5 voluptuous==0.11.5
voluptuous-serialize==2.0.0 voluptuous-serialize==2.0.0

View File

@ -11,7 +11,7 @@ cryptography==2.3.1
pip>=8.0.3 pip>=8.0.3
pytz>=2018.04 pytz>=2018.04
pyyaml>=3.13,<4 pyyaml>=3.13,<4
requests==2.19.1 requests==2.20.0
voluptuous==0.11.5 voluptuous==0.11.5
voluptuous-serialize==2.0.0 voluptuous-serialize==2.0.0

View File

@ -45,7 +45,7 @@ REQUIRES = [
'pip>=8.0.3', 'pip>=8.0.3',
'pytz>=2018.04', 'pytz>=2018.04',
'pyyaml>=3.13,<4', 'pyyaml>=3.13,<4',
'requests==2.19.1', 'requests==2.20.0',
'voluptuous==0.11.5', 'voluptuous==0.11.5',
'voluptuous-serialize==2.0.0', 'voluptuous-serialize==2.0.0',
] ]

View File

@ -32,8 +32,7 @@ def test_constructor_loads_info_from_constant():
'google_actions_sync_url': 'test-google_actions_sync_url', 'google_actions_sync_url': 'test-google_actions_sync_url',
'subscription_info_url': 'test-subscription-info-url' 'subscription_info_url': 'test-subscription-info-url'
} }
}), patch('homeassistant.components.cloud.Cloud._fetch_jwt_keyset', }):
return_value=mock_coro(True)):
result = yield from cloud.async_setup(hass, { result = yield from cloud.async_setup(hass, {
'cloud': {cloud.CONF_MODE: 'beer'} 'cloud': {cloud.CONF_MODE: 'beer'}
}) })
@ -54,17 +53,15 @@ def test_constructor_loads_info_from_config():
"""Test non-dev mode loads info from SERVERS constant.""" """Test non-dev mode loads info from SERVERS constant."""
hass = MagicMock(data={}) hass = MagicMock(data={})
with patch('homeassistant.components.cloud.Cloud._fetch_jwt_keyset', result = yield from cloud.async_setup(hass, {
return_value=mock_coro(True)): 'cloud': {
result = yield from cloud.async_setup(hass, { cloud.CONF_MODE: cloud.MODE_DEV,
'cloud': { 'cognito_client_id': 'test-cognito_client_id',
cloud.CONF_MODE: cloud.MODE_DEV, 'user_pool_id': 'test-user_pool_id',
'cognito_client_id': 'test-cognito_client_id', 'region': 'test-region',
'user_pool_id': 'test-user_pool_id', 'relayer': 'test-relayer',
'region': 'test-region', }
'relayer': 'test-relayer', })
}
})
assert result assert result
cl = hass.data['cloud'] cl = hass.data['cloud']
@ -89,8 +86,6 @@ async def test_initialize_loads_info(mock_os, hass):
cl.iot.connect.return_value = mock_coro() cl.iot.connect.return_value = mock_coro()
with patch('homeassistant.components.cloud.open', mopen, create=True), \ with patch('homeassistant.components.cloud.open', mopen, create=True), \
patch('homeassistant.components.cloud.Cloud._fetch_jwt_keyset',
return_value=mock_coro(True)), \
patch('homeassistant.components.cloud.Cloud._decode_claims'): patch('homeassistant.components.cloud.Cloud._decode_claims'):
await cl.async_start(None) await cl.async_start(None)

View File

@ -180,7 +180,7 @@ class TestComponentsDeviceTracker(unittest.TestCase):
assert device_tracker.DOMAIN not in self.hass.config.components assert device_tracker.DOMAIN not in self.hass.config.components
discovery.load_platform( discovery.load_platform(
self.hass, device_tracker.DOMAIN, 'demo', {'test_key': 'test_val'}, self.hass, device_tracker.DOMAIN, 'demo', {'test_key': 'test_val'},
{}) {'demo': {}})
self.hass.block_till_done() self.hass.block_till_done()
assert device_tracker.DOMAIN in self.hass.config.components assert device_tracker.DOMAIN in self.hass.config.components
assert mock_demo_setup_scanner.called assert mock_demo_setup_scanner.called

View File

@ -674,7 +674,7 @@ class TestLightMQTTJSON(unittest.TestCase):
async def test_discovery_removal(hass, mqtt_mock, caplog): async def test_discovery_removal(hass, mqtt_mock, caplog):
"""Test removal of discovered mqtt_json lights.""" """Test removal of discovered mqtt_json lights."""
await async_start(hass, 'homeassistant', {}) await async_start(hass, 'homeassistant', {'mqtt': {}})
data = ( data = (
'{ "name": "Beer",' '{ "name": "Beer",'
' "platform": "mqtt_json",' ' "platform": "mqtt_json",'

View File

@ -180,7 +180,7 @@ class TestLockMQTT(unittest.TestCase):
async def test_discovery_removal_lock(hass, mqtt_mock, caplog): async def test_discovery_removal_lock(hass, mqtt_mock, caplog):
"""Test removal of discovered lock.""" """Test removal of discovered lock."""
await async_start(hass, 'homeassistant', {}) await async_start(hass, 'homeassistant', {'mqtt': {}})
data = ( data = (
'{ "name": "Beer",' '{ "name": "Beer",'
' "command_topic": "test_topic" }' ' "command_topic": "test_topic" }'

View File

@ -66,7 +66,8 @@ class TestNotifyDemo(unittest.TestCase):
"""Test discovery of notify demo platform.""" """Test discovery of notify demo platform."""
assert notify.DOMAIN not in self.hass.config.components assert notify.DOMAIN not in self.hass.config.components
discovery.load_platform( discovery.load_platform(
self.hass, 'notify', 'demo', {'test_key': 'test_val'}, {}) self.hass, 'notify', 'demo', {'test_key': 'test_val'},
{'notify': {}})
self.hass.block_till_done() self.hass.block_till_done()
assert notify.DOMAIN in self.hass.config.components assert notify.DOMAIN in self.hass.config.components
assert mock_demo_get_service.called assert mock_demo_get_service.called

View File

@ -85,8 +85,8 @@ class TestGoogle(unittest.TestCase):
calendar_service = google.GoogleCalendarService( calendar_service = google.GoogleCalendarService(
self.hass.config.path(google.TOKEN_FILE)) self.hass.config.path(google.TOKEN_FILE))
self.assertTrue(google.setup_services(self.hass, True, assert google.setup_services(
calendar_service)) self.hass, {'google': {}}, True, calendar_service)
# self.hass.services.call('google', 'found_calendar', calendar, # self.hass.services.call('google', 'found_calendar', calendar,
# blocking=True) # blocking=True)

View File

@ -54,7 +54,7 @@ async def test_successful_config_entry(hass):
async def test_controller_fail_setup(hass): async def test_controller_fail_setup(hass):
"""Test that configured options for a host are loaded via config entry.""" """Test that a failed setup still stores controller."""
entry = MockConfigEntry(domain=unifi.DOMAIN, data={ entry = MockConfigEntry(domain=unifi.DOMAIN, data={
'controller': { 'controller': {
'host': '0.0.0.0', 'host': '0.0.0.0',
@ -75,7 +75,7 @@ async def test_controller_fail_setup(hass):
controller_id = unifi.CONTROLLER_ID.format( controller_id = unifi.CONTROLLER_ID.format(
host='0.0.0.0', site='default' host='0.0.0.0', site='default'
) )
assert controller_id not in hass.data[unifi.DOMAIN] assert controller_id in hass.data[unifi.DOMAIN]
async def test_controller_no_mac(hass): async def test_controller_no_mac(hass):

View File

@ -79,15 +79,15 @@ class TestHelpersDiscovery:
platform_callback) platform_callback)
discovery.load_platform(self.hass, 'test_component', 'test_platform', discovery.load_platform(self.hass, 'test_component', 'test_platform',
'discovery info') 'discovery info', {'test_component': {}})
self.hass.block_till_done() self.hass.block_till_done()
assert mock_setup_component.called assert mock_setup_component.called
assert mock_setup_component.call_args[0] == \ assert mock_setup_component.call_args[0] == \
(self.hass, 'test_component', None) (self.hass, 'test_component', {'test_component': {}})
self.hass.block_till_done() self.hass.block_till_done()
discovery.load_platform(self.hass, 'test_component_2', 'test_platform', discovery.load_platform(self.hass, 'test_component_2', 'test_platform',
'discovery info') 'discovery info', {'test_component': {}})
self.hass.block_till_done() self.hass.block_till_done()
assert len(calls) == 1 assert len(calls) == 1
@ -202,7 +202,8 @@ class TestHelpersDiscovery:
async def test_load_platform_forbids_config(): async def test_load_platform_forbids_config():
"""Test you cannot setup config component with load_platform.""" """Test you cannot setup config component with load_platform."""
with pytest.raises(HomeAssistantError): with pytest.raises(HomeAssistantError):
await discovery.async_load_platform(None, 'config', 'zwave') await discovery.async_load_platform(None, 'config', 'zwave', {},
{'config': {}})
async def test_discover_forbids_config(): async def test_discover_forbids_config():

View File

@ -131,7 +131,7 @@ class TestHelpersEntityComponent(unittest.TestCase):
component.setup({}) component.setup({})
discovery.load_platform(self.hass, DOMAIN, 'platform_test', discovery.load_platform(self.hass, DOMAIN, 'platform_test',
{'msg': 'discovery_info'}) {'msg': 'discovery_info'}, {DOMAIN: {}})
self.hass.block_till_done() self.hass.block_till_done()