Pass hass_config to load_platform (#17952)

* Pass hass_config to load_platform

* Fix tests

* Lint
This commit is contained in:
Paulus Schoutsen 2018-10-29 19:21:21 +01:00 committed by GitHub
parent b03e6050c5
commit 6ae345b01c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 70 additions and 56 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

@ -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

@ -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

@ -181,7 +181,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

@ -524,7 +524,7 @@ async def test_custom_availability_payload(hass, mqtt_mock):
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

@ -136,7 +136,7 @@ async def test_custom_availability_payload(hass, mqtt_mock):
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

@ -65,7 +65,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,7 +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))
assert google.setup_services(self.hass, True, calendar_service) assert google.setup_services(
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

@ -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()