mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 17:27:52 +00:00
Custom component loading cleanup (#14211)
* Clean up custom component loading * Fix some tests * Fix some stuff * Make imports work again * Fix tests * Remove debug print * Lint
This commit is contained in:
parent
5d96751168
commit
83d300fd11
@ -12,8 +12,7 @@ from typing import Any, Optional, Dict
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import (
|
||||
core, config as conf_util, config_entries, loader,
|
||||
components as core_components)
|
||||
core, config as conf_util, config_entries, components as core_components)
|
||||
from homeassistant.components import persistent_notification
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_CLOSE
|
||||
from homeassistant.setup import async_setup_component
|
||||
@ -103,15 +102,12 @@ async def async_from_config_dict(config: Dict[str, Any],
|
||||
_LOGGER.warning("Skipping pip installation of required modules. "
|
||||
"This may cause issues")
|
||||
|
||||
if not loader.PREPARED:
|
||||
await hass.async_add_job(loader.prepare, hass)
|
||||
|
||||
# Make a copy because we are mutating it.
|
||||
config = OrderedDict(config)
|
||||
|
||||
# Merge packages
|
||||
conf_util.merge_packages_config(
|
||||
config, core_config.get(conf_util.CONF_PACKAGES, {}))
|
||||
hass, config, core_config.get(conf_util.CONF_PACKAGES, {}))
|
||||
|
||||
# Ensure we have no None values after merge
|
||||
for key, value in config.items():
|
||||
|
@ -6,6 +6,7 @@ https://home-assistant.io/components/automation/
|
||||
"""
|
||||
import asyncio
|
||||
from functools import partial
|
||||
import importlib
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
@ -22,7 +23,6 @@ from homeassistant.helpers import extract_domain_configs, script, condition
|
||||
from homeassistant.helpers.entity import ToggleEntity
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
from homeassistant.helpers.restore_state import async_get_last_state
|
||||
from homeassistant.loader import get_platform
|
||||
from homeassistant.util.dt import utcnow
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
@ -58,12 +58,14 @@ _LOGGER = logging.getLogger(__name__)
|
||||
|
||||
def _platform_validator(config):
|
||||
"""Validate it is a valid platform."""
|
||||
platform = get_platform(DOMAIN, config[CONF_PLATFORM])
|
||||
try:
|
||||
platform = importlib.import_module(
|
||||
'homeassistant.components.automation.{}'.format(
|
||||
config[CONF_PLATFORM]))
|
||||
except ImportError:
|
||||
raise vol.Invalid('Invalid platform specified') from None
|
||||
|
||||
if not hasattr(platform, 'TRIGGER_SCHEMA'):
|
||||
return config
|
||||
|
||||
return getattr(platform, 'TRIGGER_SCHEMA')(config)
|
||||
return platform.TRIGGER_SCHEMA(config)
|
||||
|
||||
|
||||
_TRIGGER_SCHEMA = vol.All(
|
||||
@ -71,7 +73,7 @@ _TRIGGER_SCHEMA = vol.All(
|
||||
[
|
||||
vol.All(
|
||||
vol.Schema({
|
||||
vol.Required(CONF_PLATFORM): cv.platform_validator(DOMAIN)
|
||||
vol.Required(CONF_PLATFORM): str
|
||||
}, extra=vol.ALLOW_EXTRA),
|
||||
_platform_validator
|
||||
),
|
||||
|
@ -11,7 +11,6 @@ import voluptuous as vol
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDevice, PLATFORM_SCHEMA)
|
||||
from homeassistant.const import CONF_MONITORED_CONDITIONS
|
||||
from homeassistant.loader import get_component
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@ -31,7 +30,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up the available BloomSky weather binary sensors."""
|
||||
bloomsky = get_component('bloomsky')
|
||||
bloomsky = hass.components.bloomsky
|
||||
# Default needed in case of discovery
|
||||
sensors = config.get(CONF_MONITORED_CONDITIONS, SENSOR_TYPES)
|
||||
|
||||
|
@ -13,7 +13,6 @@ import voluptuous as vol
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDevice, PLATFORM_SCHEMA)
|
||||
from homeassistant.components.netatmo import CameraData
|
||||
from homeassistant.loader import get_component
|
||||
from homeassistant.const import CONF_TIMEOUT
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
|
||||
@ -61,7 +60,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up the access to Netatmo binary sensor."""
|
||||
netatmo = get_component('netatmo')
|
||||
netatmo = hass.components.netatmo
|
||||
home = config.get(CONF_HOME)
|
||||
timeout = config.get(CONF_TIMEOUT)
|
||||
if timeout is None:
|
||||
|
@ -7,7 +7,6 @@ https://home-assistant.io/components/binary_sensor.wemo/
|
||||
import logging
|
||||
|
||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
from homeassistant.loader import get_component
|
||||
|
||||
DEPENDENCIES = ['wemo']
|
||||
|
||||
@ -25,18 +24,18 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
||||
device = discovery.device_from_description(location, mac)
|
||||
|
||||
if device:
|
||||
add_devices_callback([WemoBinarySensor(device)])
|
||||
add_devices_callback([WemoBinarySensor(hass, device)])
|
||||
|
||||
|
||||
class WemoBinarySensor(BinarySensorDevice):
|
||||
"""Representation a WeMo binary sensor."""
|
||||
|
||||
def __init__(self, device):
|
||||
def __init__(self, hass, device):
|
||||
"""Initialize the WeMo sensor."""
|
||||
self.wemo = device
|
||||
self._state = None
|
||||
|
||||
wemo = get_component('wemo')
|
||||
wemo = hass.components.wemo
|
||||
wemo.SUBSCRIPTION_REGISTRY.register(self.wemo)
|
||||
wemo.SUBSCRIPTION_REGISTRY.on(self.wemo, None, self._update_callback)
|
||||
|
||||
|
@ -9,7 +9,6 @@ import logging
|
||||
import requests
|
||||
|
||||
from homeassistant.components.camera import Camera
|
||||
from homeassistant.loader import get_component
|
||||
|
||||
DEPENDENCIES = ['bloomsky']
|
||||
|
||||
@ -17,7 +16,7 @@ DEPENDENCIES = ['bloomsky']
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up access to BloomSky cameras."""
|
||||
bloomsky = get_component('bloomsky')
|
||||
bloomsky = hass.components.bloomsky
|
||||
for device in bloomsky.BLOOMSKY.devices.values():
|
||||
add_devices([BloomSkyCamera(bloomsky.BLOOMSKY, device)])
|
||||
|
||||
|
@ -12,7 +12,6 @@ import voluptuous as vol
|
||||
from homeassistant.const import CONF_VERIFY_SSL
|
||||
from homeassistant.components.netatmo import CameraData
|
||||
from homeassistant.components.camera import (Camera, PLATFORM_SCHEMA)
|
||||
from homeassistant.loader import get_component
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
|
||||
DEPENDENCIES = ['netatmo']
|
||||
@ -33,7 +32,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up access to Netatmo cameras."""
|
||||
netatmo = get_component('netatmo')
|
||||
netatmo = hass.components.netatmo
|
||||
home = config.get(CONF_HOME)
|
||||
verify_ssl = config.get(CONF_VERIFY_SSL, True)
|
||||
import lnetatmo
|
||||
|
@ -13,7 +13,6 @@ from homeassistant.components.climate import (
|
||||
STATE_HEAT, STATE_IDLE, ClimateDevice, PLATFORM_SCHEMA,
|
||||
SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE, SUPPORT_AWAY_MODE)
|
||||
from homeassistant.util import Throttle
|
||||
from homeassistant.loader import get_component
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
DEPENDENCIES = ['netatmo']
|
||||
@ -42,7 +41,7 @@ SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE |
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up the NetAtmo Thermostat."""
|
||||
netatmo = get_component('netatmo')
|
||||
netatmo = hass.components.netatmo
|
||||
device = config.get(CONF_RELAY)
|
||||
|
||||
import lnetatmo
|
||||
|
@ -16,7 +16,6 @@ from homeassistant.const import STATE_HOME, STATE_NOT_HOME
|
||||
from homeassistant.helpers.event import (
|
||||
async_track_point_in_utc_time, async_track_state_change)
|
||||
from homeassistant.helpers.sun import is_up, get_astral_event_next
|
||||
from homeassistant.loader import get_component
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
DOMAIN = 'device_sun_light_trigger'
|
||||
@ -48,9 +47,9 @@ CONFIG_SCHEMA = vol.Schema({
|
||||
def async_setup(hass, config):
|
||||
"""Set up the triggers to control lights based on device presence."""
|
||||
logger = logging.getLogger(__name__)
|
||||
device_tracker = get_component('device_tracker')
|
||||
group = get_component('group')
|
||||
light = get_component('light')
|
||||
device_tracker = hass.components.device_tracker
|
||||
group = hass.components.group
|
||||
light = hass.components.light
|
||||
conf = config[DOMAIN]
|
||||
disable_turn_off = conf.get(CONF_DISABLE_TURN_OFF)
|
||||
light_group = conf.get(CONF_LIGHT_GROUP, light.ENTITY_ID_ALL_LIGHTS)
|
||||
@ -58,14 +57,14 @@ def async_setup(hass, config):
|
||||
device_group = conf.get(
|
||||
CONF_DEVICE_GROUP, device_tracker.ENTITY_ID_ALL_DEVICES)
|
||||
device_entity_ids = group.get_entity_ids(
|
||||
hass, device_group, device_tracker.DOMAIN)
|
||||
device_group, device_tracker.DOMAIN)
|
||||
|
||||
if not device_entity_ids:
|
||||
logger.error("No devices found to track")
|
||||
return False
|
||||
|
||||
# Get the light IDs from the specified group
|
||||
light_ids = group.get_entity_ids(hass, light_group, light.DOMAIN)
|
||||
light_ids = group.get_entity_ids(light_group, light.DOMAIN)
|
||||
|
||||
if not light_ids:
|
||||
logger.error("No lights found to turn on")
|
||||
@ -85,9 +84,9 @@ def async_setup(hass, config):
|
||||
|
||||
def async_turn_on_before_sunset(light_id):
|
||||
"""Turn on lights."""
|
||||
if not device_tracker.is_on(hass) or light.is_on(hass, light_id):
|
||||
if not device_tracker.is_on() or light.is_on(light_id):
|
||||
return
|
||||
light.async_turn_on(hass, light_id,
|
||||
light.async_turn_on(light_id,
|
||||
transition=LIGHT_TRANSITION_TIME.seconds,
|
||||
profile=light_profile)
|
||||
|
||||
@ -129,7 +128,7 @@ def async_setup(hass, config):
|
||||
@callback
|
||||
def check_light_on_dev_state_change(entity, old_state, new_state):
|
||||
"""Handle tracked device state changes."""
|
||||
lights_are_on = group.is_on(hass, light_group)
|
||||
lights_are_on = group.is_on(light_group)
|
||||
light_needed = not (lights_are_on or is_up(hass))
|
||||
|
||||
# These variables are needed for the elif check
|
||||
@ -139,7 +138,7 @@ def async_setup(hass, config):
|
||||
# Do we need lights?
|
||||
if light_needed:
|
||||
logger.info("Home coming event for %s. Turning lights on", entity)
|
||||
light.async_turn_on(hass, light_ids, profile=light_profile)
|
||||
light.async_turn_on(light_ids, profile=light_profile)
|
||||
|
||||
# Are we in the time span were we would turn on the lights
|
||||
# if someone would be home?
|
||||
@ -152,7 +151,7 @@ def async_setup(hass, config):
|
||||
# when the fading in started and turn it on if so
|
||||
for index, light_id in enumerate(light_ids):
|
||||
if now > start_point + index * LIGHT_TRANSITION_TIME:
|
||||
light.async_turn_on(hass, light_id)
|
||||
light.async_turn_on(light_id)
|
||||
|
||||
else:
|
||||
# If this light didn't happen to be turned on yet so
|
||||
@ -169,12 +168,12 @@ def async_setup(hass, config):
|
||||
@callback
|
||||
def turn_off_lights_when_all_leave(entity, old_state, new_state):
|
||||
"""Handle device group state change."""
|
||||
if not group.is_on(hass, light_group):
|
||||
if not group.is_on(light_group):
|
||||
return
|
||||
|
||||
logger.info(
|
||||
"Everyone has left but there are lights on. Turning them off")
|
||||
light.async_turn_off(hass, light_ids)
|
||||
light.async_turn_off(light_ids)
|
||||
|
||||
async_track_state_change(
|
||||
hass, device_group, turn_off_lights_when_all_leave,
|
||||
|
@ -24,7 +24,6 @@ from homeassistant.helpers.event import async_track_time_interval
|
||||
from homeassistant.helpers.restore_state import async_get_last_state
|
||||
from homeassistant.helpers.typing import GPSType, ConfigType, HomeAssistantType
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.loader import get_component
|
||||
import homeassistant.util as util
|
||||
from homeassistant.util.async_ import run_coroutine_threadsafe
|
||||
import homeassistant.util.dt as dt_util
|
||||
@ -322,7 +321,7 @@ class DeviceTracker(object):
|
||||
# During init, we ignore the group
|
||||
if self.group and self.track_new:
|
||||
self.group.async_set_group(
|
||||
self.hass, util.slugify(GROUP_NAME_ALL_DEVICES), visible=False,
|
||||
util.slugify(GROUP_NAME_ALL_DEVICES), visible=False,
|
||||
name=GROUP_NAME_ALL_DEVICES, add=[device.entity_id])
|
||||
|
||||
self.hass.bus.async_fire(EVENT_NEW_DEVICE, {
|
||||
@ -357,9 +356,9 @@ class DeviceTracker(object):
|
||||
entity_ids = [dev.entity_id for dev in self.devices.values()
|
||||
if dev.track]
|
||||
|
||||
self.group = get_component('group')
|
||||
self.group = self.hass.components.group
|
||||
self.group.async_set_group(
|
||||
self.hass, util.slugify(GROUP_NAME_ALL_DEVICES), visible=False,
|
||||
util.slugify(GROUP_NAME_ALL_DEVICES), visible=False,
|
||||
name=GROUP_NAME_ALL_DEVICES, entity_ids=entity_ids)
|
||||
|
||||
@callback
|
||||
|
@ -17,7 +17,6 @@ from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.loader import bind_hass
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
from homeassistant.loader import get_component
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -121,12 +120,12 @@ class ImageProcessingEntity(Entity):
|
||||
|
||||
This method is a coroutine.
|
||||
"""
|
||||
camera = get_component('camera')
|
||||
camera = self.hass.components.camera
|
||||
image = None
|
||||
|
||||
try:
|
||||
image = yield from camera.async_get_image(
|
||||
self.hass, self.camera_entity, timeout=self.timeout)
|
||||
self.camera_entity, timeout=self.timeout)
|
||||
|
||||
except HomeAssistantError as err:
|
||||
_LOGGER.error("Error on receive image from entity: %s", err)
|
||||
|
@ -12,7 +12,6 @@ import homeassistant.util as util
|
||||
from homeassistant.components.light import (
|
||||
Light, ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_HS_COLOR, ATTR_TRANSITION,
|
||||
SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_COLOR, SUPPORT_TRANSITION)
|
||||
from homeassistant.loader import get_component
|
||||
import homeassistant.util.color as color_util
|
||||
|
||||
DEPENDENCIES = ['wemo']
|
||||
@ -151,7 +150,7 @@ class WemoDimmer(Light):
|
||||
@asyncio.coroutine
|
||||
def async_added_to_hass(self):
|
||||
"""Register update callback."""
|
||||
wemo = get_component('wemo')
|
||||
wemo = self.hass.components.wemo
|
||||
# The register method uses a threading condition, so call via executor.
|
||||
# and yield from to wait until the task is done.
|
||||
yield from self.hass.async_add_job(
|
||||
|
@ -18,7 +18,6 @@ from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.loader import get_component
|
||||
from homeassistant.util import slugify
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@ -231,7 +230,7 @@ def async_setup(hass, config):
|
||||
p_id = face.store[g_id].get(service.data[ATTR_PERSON])
|
||||
|
||||
camera_entity = service.data[ATTR_CAMERA_ENTITY]
|
||||
camera = get_component('camera')
|
||||
camera = hass.components.camera
|
||||
|
||||
try:
|
||||
image = yield from camera.async_get_image(hass, camera_entity)
|
||||
|
@ -10,7 +10,6 @@ import json
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.core import callback
|
||||
import homeassistant.loader as loader
|
||||
from homeassistant.components.mqtt import (
|
||||
valid_publish_topic, valid_subscribe_topic)
|
||||
from homeassistant.const import (
|
||||
@ -42,7 +41,7 @@ CONFIG_SCHEMA = vol.Schema({
|
||||
@asyncio.coroutine
|
||||
def async_setup(hass, config):
|
||||
"""Set up the MQTT eventstream component."""
|
||||
mqtt = loader.get_component('mqtt')
|
||||
mqtt = hass.components.mqtt
|
||||
conf = config.get(DOMAIN, {})
|
||||
pub_topic = conf.get(CONF_PUBLISH_TOPIC)
|
||||
sub_topic = conf.get(CONF_SUBSCRIBE_TOPIC)
|
||||
@ -82,7 +81,7 @@ def async_setup(hass, config):
|
||||
|
||||
event_info = {'event_type': event.event_type, 'event_data': event.data}
|
||||
msg = json.dumps(event_info, cls=JSONEncoder)
|
||||
mqtt.async_publish(hass, pub_topic, msg)
|
||||
mqtt.async_publish(pub_topic, msg)
|
||||
|
||||
# Only listen for local events if you are going to publish them.
|
||||
if pub_topic:
|
||||
@ -115,7 +114,7 @@ def async_setup(hass, config):
|
||||
|
||||
# Only subscribe if you specified a topic.
|
||||
if sub_topic:
|
||||
yield from mqtt.async_subscribe(hass, sub_topic, _event_receiver)
|
||||
yield from mqtt.async_subscribe(sub_topic, _event_receiver)
|
||||
|
||||
hass.states.async_set('{domain}.initialized'.format(domain=DOMAIN), True)
|
||||
return True
|
||||
|
@ -24,7 +24,6 @@ import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.dispatcher import (
|
||||
async_dispatcher_connect, dispatcher_send)
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.loader import get_component
|
||||
from homeassistant.setup import setup_component
|
||||
|
||||
REQUIREMENTS = ['pymysensors==0.11.1']
|
||||
@ -294,16 +293,16 @@ def setup(hass, config):
|
||||
if device == MQTT_COMPONENT:
|
||||
if not setup_component(hass, MQTT_COMPONENT, config):
|
||||
return
|
||||
mqtt = get_component(MQTT_COMPONENT)
|
||||
mqtt = hass.components.mqtt
|
||||
retain = config[DOMAIN].get(CONF_RETAIN)
|
||||
|
||||
def pub_callback(topic, payload, qos, retain):
|
||||
"""Call MQTT publish function."""
|
||||
mqtt.publish(hass, topic, payload, qos, retain)
|
||||
mqtt.publish(topic, payload, qos, retain)
|
||||
|
||||
def sub_callback(topic, sub_cb, qos):
|
||||
"""Call MQTT subscribe function."""
|
||||
mqtt.subscribe(hass, topic, sub_cb, qos)
|
||||
mqtt.subscribe(topic, sub_cb, qos)
|
||||
gateway = mysensors.MQTTGateway(
|
||||
pub_callback, sub_callback,
|
||||
event_callback=None, persistence=persistence,
|
||||
|
@ -5,6 +5,7 @@ For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/scene/
|
||||
"""
|
||||
import asyncio
|
||||
import importlib
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
@ -16,7 +17,6 @@ import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
from homeassistant.helpers.state import HASS_DOMAIN
|
||||
from homeassistant.loader import get_platform
|
||||
|
||||
DOMAIN = 'scene'
|
||||
STATE = 'scening'
|
||||
@ -34,20 +34,24 @@ def _hass_domain_validator(config):
|
||||
|
||||
def _platform_validator(config):
|
||||
"""Validate it is a valid platform."""
|
||||
p_name = config[CONF_PLATFORM]
|
||||
platform = get_platform(DOMAIN, p_name)
|
||||
try:
|
||||
platform = importlib.import_module(
|
||||
'homeassistant.components.scene.{}'.format(
|
||||
config[CONF_PLATFORM]))
|
||||
except ImportError:
|
||||
raise vol.Invalid('Invalid platform specified') from None
|
||||
|
||||
if not hasattr(platform, 'PLATFORM_SCHEMA'):
|
||||
return config
|
||||
|
||||
return getattr(platform, 'PLATFORM_SCHEMA')(config)
|
||||
return platform.PLATFORM_SCHEMA(config)
|
||||
|
||||
|
||||
PLATFORM_SCHEMA = vol.Schema(
|
||||
vol.All(
|
||||
_hass_domain_validator,
|
||||
vol.Schema({
|
||||
vol.Required(CONF_PLATFORM): cv.platform_validator(DOMAIN)
|
||||
vol.Required(CONF_PLATFORM): str
|
||||
}, extra=vol.ALLOW_EXTRA),
|
||||
_platform_validator
|
||||
), extra=vol.ALLOW_EXTRA)
|
||||
|
@ -11,7 +11,6 @@ import voluptuous as vol
|
||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||
from homeassistant.const import (TEMP_FAHRENHEIT, CONF_MONITORED_CONDITIONS)
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.loader import get_component
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@ -45,7 +44,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up the available BloomSky weather sensors."""
|
||||
bloomsky = get_component('bloomsky')
|
||||
bloomsky = hass.components.bloomsky
|
||||
# Default needed in case of discovery
|
||||
sensors = config.get(CONF_MONITORED_CONDITIONS, SENSOR_TYPES)
|
||||
|
||||
|
@ -13,7 +13,6 @@ from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||
from homeassistant.const import TEMP_CELSIUS, STATE_UNKNOWN
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.util import Throttle
|
||||
from homeassistant.loader import get_component
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@ -64,7 +63,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up the available Netatmo weather sensors."""
|
||||
netatmo = get_component('netatmo')
|
||||
netatmo = hass.components.netatmo
|
||||
data = NetAtmoData(netatmo.NETATMO_AUTH, config.get(CONF_STATION, None))
|
||||
|
||||
dev = []
|
||||
|
@ -788,7 +788,7 @@ class ZWaveDeviceEntityValues():
|
||||
if polling_intensity:
|
||||
self.primary.enable_poll(polling_intensity)
|
||||
|
||||
platform = get_platform(component, DOMAIN)
|
||||
platform = get_platform(self._hass, component, DOMAIN)
|
||||
device = platform.get_device(
|
||||
node=self._node, values=self,
|
||||
node_config=node_config, hass=self._hass)
|
||||
|
@ -548,7 +548,8 @@ def _identify_config_schema(module):
|
||||
return '', schema
|
||||
|
||||
|
||||
def merge_packages_config(config, packages, _log_pkg_error=_log_pkg_error):
|
||||
def merge_packages_config(hass, config, packages,
|
||||
_log_pkg_error=_log_pkg_error):
|
||||
"""Merge packages into the top-level configuration. Mutate config."""
|
||||
# pylint: disable=too-many-nested-blocks
|
||||
PACKAGES_CONFIG_SCHEMA(packages)
|
||||
@ -556,7 +557,7 @@ def merge_packages_config(config, packages, _log_pkg_error=_log_pkg_error):
|
||||
for comp_name, comp_conf in pack_conf.items():
|
||||
if comp_name == CONF_CORE:
|
||||
continue
|
||||
component = get_component(comp_name)
|
||||
component = get_component(hass, comp_name)
|
||||
|
||||
if component is None:
|
||||
_log_pkg_error(pack_name, comp_name, config, "does not exist")
|
||||
@ -625,7 +626,7 @@ def async_process_component_config(hass, config, domain):
|
||||
|
||||
This method must be run in the event loop.
|
||||
"""
|
||||
component = get_component(domain)
|
||||
component = get_component(hass, domain)
|
||||
|
||||
if hasattr(component, 'CONFIG_SCHEMA'):
|
||||
try:
|
||||
@ -651,7 +652,7 @@ def async_process_component_config(hass, config, domain):
|
||||
platforms.append(p_validated)
|
||||
continue
|
||||
|
||||
platform = get_platform(domain, p_name)
|
||||
platform = get_platform(hass, domain, p_name)
|
||||
|
||||
if platform is None:
|
||||
continue
|
||||
|
@ -12,7 +12,6 @@ from typing import Any, Union, TypeVar, Callable, Sequence, Dict
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.loader import get_platform
|
||||
from homeassistant.const import (
|
||||
CONF_PLATFORM, CONF_SCAN_INTERVAL, TEMP_CELSIUS, TEMP_FAHRENHEIT,
|
||||
CONF_ALIAS, CONF_ENTITY_ID, CONF_VALUE_TEMPLATE, WEEKDAYS,
|
||||
@ -283,19 +282,6 @@ def match_all(value):
|
||||
return value
|
||||
|
||||
|
||||
def platform_validator(domain):
|
||||
"""Validate if platform exists for given domain."""
|
||||
def validator(value):
|
||||
"""Test if platform exists."""
|
||||
if value is None:
|
||||
raise vol.Invalid('platform cannot be None')
|
||||
if get_platform(domain, str(value)):
|
||||
return value
|
||||
raise vol.Invalid(
|
||||
'platform {} does not exist for {}'.format(value, domain))
|
||||
return validator
|
||||
|
||||
|
||||
def positive_timedelta(value: timedelta) -> timedelta:
|
||||
"""Validate timedelta is positive."""
|
||||
if value < timedelta(0):
|
||||
|
@ -92,7 +92,7 @@ def extract_entity_ids(hass, service_call, expand_group=True):
|
||||
if not (service_call.data and ATTR_ENTITY_ID in service_call.data):
|
||||
return []
|
||||
|
||||
group = get_component('group')
|
||||
group = hass.components.group
|
||||
|
||||
# Entity ID attr can be a list or a string
|
||||
service_ent_id = service_call.data[ATTR_ENTITY_ID]
|
||||
@ -100,10 +100,10 @@ def extract_entity_ids(hass, service_call, expand_group=True):
|
||||
if expand_group:
|
||||
|
||||
if isinstance(service_ent_id, str):
|
||||
return group.expand_entity_ids(hass, [service_ent_id])
|
||||
return group.expand_entity_ids([service_ent_id])
|
||||
|
||||
return [ent_id for ent_id in
|
||||
group.expand_entity_ids(hass, service_ent_id)]
|
||||
group.expand_entity_ids(service_ent_id)]
|
||||
|
||||
else:
|
||||
|
||||
@ -128,7 +128,7 @@ async def async_get_all_descriptions(hass):
|
||||
import homeassistant.components as components
|
||||
component_path = path.dirname(components.__file__)
|
||||
else:
|
||||
component_path = path.dirname(get_component(domain).__file__)
|
||||
component_path = path.dirname(get_component(hass, domain).__file__)
|
||||
return path.join(component_path, 'services.yaml')
|
||||
|
||||
def load_services_files(yaml_files):
|
||||
|
@ -16,7 +16,7 @@ from homeassistant.const import (
|
||||
from homeassistant.core import State, valid_entity_id
|
||||
from homeassistant.exceptions import TemplateError
|
||||
from homeassistant.helpers import location as loc_helper
|
||||
from homeassistant.loader import bind_hass, get_component
|
||||
from homeassistant.loader import bind_hass
|
||||
from homeassistant.util import convert
|
||||
from homeassistant.util import dt as dt_util
|
||||
from homeassistant.util import location as loc_util
|
||||
@ -349,10 +349,10 @@ class TemplateMethods(object):
|
||||
else:
|
||||
gr_entity_id = str(entities)
|
||||
|
||||
group = get_component('group')
|
||||
group = self._hass.components.group
|
||||
|
||||
states = [self._hass.states.get(entity_id) for entity_id
|
||||
in group.expand_entity_ids(self._hass, [gr_entity_id])]
|
||||
in group.expand_entity_ids([gr_entity_id])]
|
||||
|
||||
return _wrap_state(loc_helper.closest(latitude, longitude, states))
|
||||
|
||||
|
@ -30,14 +30,14 @@ def flatten(data):
|
||||
return recursive_flatten('', data)
|
||||
|
||||
|
||||
def component_translation_file(component, language):
|
||||
def component_translation_file(hass, component, language):
|
||||
"""Return the translation json file location for a component."""
|
||||
if '.' in component:
|
||||
name = component.split('.', 1)[1]
|
||||
else:
|
||||
name = component
|
||||
|
||||
module = get_component(component)
|
||||
module = get_component(hass, component)
|
||||
component_path = path.dirname(module.__file__)
|
||||
|
||||
# If loading translations for the package root, (__init__.py), the
|
||||
@ -97,7 +97,7 @@ async def async_get_component_resources(hass, language):
|
||||
missing_files = {}
|
||||
for component in missing_components:
|
||||
missing_files[component] = component_translation_file(
|
||||
component, language)
|
||||
hass, component, language)
|
||||
|
||||
# Load missing files
|
||||
if missing_files:
|
||||
|
@ -6,15 +6,13 @@ documentation as possible to keep it understandable.
|
||||
|
||||
Components can be accessed via hass.components.switch from your code.
|
||||
If you want to retrieve a platform that is part of a component, you should
|
||||
call get_component('switch.your_platform'). In both cases the config directory
|
||||
is checked to see if it contains a user provided version. If not available it
|
||||
will check the built-in components and platforms.
|
||||
call get_component(hass, 'switch.your_platform'). In both cases the config
|
||||
directory is checked to see if it contains a user provided version. If not
|
||||
available it will check the built-in components and platforms.
|
||||
"""
|
||||
import functools as ft
|
||||
import importlib
|
||||
import logging
|
||||
import os
|
||||
import pkgutil
|
||||
import sys
|
||||
from types import ModuleType
|
||||
|
||||
@ -42,135 +40,94 @@ _COMPONENT_CACHE = {} # type: Dict[str, ModuleType]
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def prepare(hass: 'HomeAssistant'):
|
||||
"""Prepare the loading of components.
|
||||
|
||||
This method needs to run in an executor.
|
||||
"""
|
||||
global PREPARED # pylint: disable=global-statement
|
||||
|
||||
# Load the built-in components
|
||||
import homeassistant.components as components
|
||||
|
||||
AVAILABLE_COMPONENTS.clear()
|
||||
|
||||
AVAILABLE_COMPONENTS.extend(
|
||||
item[1] for item in
|
||||
pkgutil.iter_modules(components.__path__, 'homeassistant.components.'))
|
||||
|
||||
# Look for available custom components
|
||||
custom_path = hass.config.path("custom_components")
|
||||
|
||||
if os.path.isdir(custom_path):
|
||||
# Ensure we can load custom components using Pythons import
|
||||
sys.path.insert(0, hass.config.config_dir)
|
||||
|
||||
# We cannot use the same approach as for built-in components because
|
||||
# custom components might only contain a platform for a component.
|
||||
# ie custom_components/switch/some_platform.py. Using pkgutil would
|
||||
# not give us the switch component (and neither should it).
|
||||
|
||||
# Assumption: the custom_components dir only contains directories or
|
||||
# python components. If this assumption is not true, HA won't break,
|
||||
# just might output more errors.
|
||||
for fil in os.listdir(custom_path):
|
||||
if fil == '__pycache__':
|
||||
continue
|
||||
elif os.path.isdir(os.path.join(custom_path, fil)):
|
||||
AVAILABLE_COMPONENTS.append('custom_components.{}'.format(fil))
|
||||
else:
|
||||
# For files we will strip out .py extension
|
||||
AVAILABLE_COMPONENTS.append(
|
||||
'custom_components.{}'.format(fil[0:-3]))
|
||||
|
||||
PREPARED = True
|
||||
DATA_KEY = 'components'
|
||||
PATH_CUSTOM_COMPONENTS = 'custom_components'
|
||||
PACKAGE_COMPONENTS = 'homeassistant.components'
|
||||
|
||||
|
||||
def set_component(comp_name: str, component: ModuleType) -> None:
|
||||
def set_component(hass, comp_name: str, component: ModuleType) -> None:
|
||||
"""Set a component in the cache.
|
||||
|
||||
Async friendly.
|
||||
"""
|
||||
_check_prepared()
|
||||
|
||||
_COMPONENT_CACHE[comp_name] = component
|
||||
cache = hass.data.get(DATA_KEY)
|
||||
if cache is None:
|
||||
cache = hass.data[DATA_KEY] = {}
|
||||
cache[comp_name] = component
|
||||
|
||||
|
||||
def get_platform(domain: str, platform: str) -> Optional[ModuleType]:
|
||||
def get_platform(hass, domain: str, platform: str) -> Optional[ModuleType]:
|
||||
"""Try to load specified platform.
|
||||
|
||||
Async friendly.
|
||||
"""
|
||||
return get_component(PLATFORM_FORMAT.format(domain, platform))
|
||||
return get_component(hass, PLATFORM_FORMAT.format(domain, platform))
|
||||
|
||||
|
||||
def get_component(comp_name) -> Optional[ModuleType]:
|
||||
"""Try to load specified component.
|
||||
def get_component(hass, comp_or_platform):
|
||||
"""Load a module from either custom component or built-in."""
|
||||
try:
|
||||
return hass.data[DATA_KEY][comp_or_platform]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
Looks in config dir first, then built-in components.
|
||||
Only returns it if also found to be valid.
|
||||
|
||||
Async friendly.
|
||||
"""
|
||||
if comp_name in _COMPONENT_CACHE:
|
||||
return _COMPONENT_CACHE[comp_name]
|
||||
|
||||
_check_prepared()
|
||||
|
||||
# If we ie. try to load custom_components.switch.wemo but the parent
|
||||
# custom_components.switch does not exist, importing it will trigger
|
||||
# an exception because it will try to import the parent.
|
||||
# Because of this behavior, we will approach loading sub components
|
||||
# with caution: only load it if we can verify that the parent exists.
|
||||
# We do not want to silent the ImportErrors as they provide valuable
|
||||
# information to track down when debugging Home Assistant.
|
||||
|
||||
# First check custom, then built-in
|
||||
potential_paths = ['custom_components.{}'.format(comp_name),
|
||||
'homeassistant.components.{}'.format(comp_name)]
|
||||
|
||||
for path in potential_paths:
|
||||
# Validate here that root component exists
|
||||
# If path contains a '.' we are specifying a sub-component
|
||||
# Using rsplit we get the parent component from sub-component
|
||||
root_comp = path.rsplit(".", 1)[0] if '.' in comp_name else path
|
||||
|
||||
if root_comp not in AVAILABLE_COMPONENTS:
|
||||
continue
|
||||
# Try custom component
|
||||
module = _load_module(hass.config.path(PATH_CUSTOM_COMPONENTS),
|
||||
comp_or_platform)
|
||||
|
||||
if module is None:
|
||||
try:
|
||||
module = importlib.import_module(path)
|
||||
module = importlib.import_module(
|
||||
'{}.{}'.format(PACKAGE_COMPONENTS, comp_or_platform))
|
||||
except ImportError:
|
||||
module = None
|
||||
|
||||
# In Python 3 you can import files from directories that do not
|
||||
# contain the file __init__.py. A directory is a valid module if
|
||||
# it contains a file with the .py extension. In this case Python
|
||||
# will succeed in importing the directory as a module and call it
|
||||
# a namespace. We do not care about namespaces.
|
||||
# This prevents that when only
|
||||
# custom_components/switch/some_platform.py exists,
|
||||
# the import custom_components.switch would succeed.
|
||||
if module.__spec__.origin == 'namespace':
|
||||
continue
|
||||
cache = hass.data.get(DATA_KEY)
|
||||
if cache is None:
|
||||
cache = hass.data[DATA_KEY] = {}
|
||||
cache[comp_or_platform] = module
|
||||
|
||||
_LOGGER.info("Loaded %s from %s", comp_name, path)
|
||||
return module
|
||||
|
||||
_COMPONENT_CACHE[comp_name] = module
|
||||
|
||||
return module
|
||||
|
||||
except ImportError as err:
|
||||
# This error happens if for example custom_components/switch
|
||||
# exists and we try to load switch.demo.
|
||||
if str(err) != "No module named '{}'".format(path):
|
||||
_LOGGER.exception(
|
||||
("Error loading %s. Make sure all "
|
||||
"dependencies are installed"), path)
|
||||
|
||||
_LOGGER.error("Unable to find component %s", comp_name)
|
||||
|
||||
def _find_spec(path, name):
|
||||
for finder in sys.meta_path:
|
||||
try:
|
||||
spec = finder.find_spec(name, path=path)
|
||||
if spec is not None:
|
||||
return spec
|
||||
except AttributeError:
|
||||
# Not all finders have the find_spec method
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def _load_module(path, name):
|
||||
"""Load a module based on a folder and a name."""
|
||||
spec = _find_spec([path], name)
|
||||
|
||||
# Special handling if loading platforms and the folder is a namespace
|
||||
# (namespace is a folder without __init__.py)
|
||||
if spec is None and '.' in name:
|
||||
parent_spec = _find_spec([path], name.split('.')[0])
|
||||
if (parent_spec is None or
|
||||
parent_spec.submodule_search_locations is None):
|
||||
return None
|
||||
spec = _find_spec(parent_spec.submodule_search_locations, name)
|
||||
|
||||
# Not found
|
||||
if spec is None:
|
||||
return None
|
||||
|
||||
# This is a namespace
|
||||
if spec.loader is None:
|
||||
return None
|
||||
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
class Components:
|
||||
"""Helper to load components."""
|
||||
|
||||
@ -180,7 +137,7 @@ class Components:
|
||||
|
||||
def __getattr__(self, comp_name):
|
||||
"""Fetch a component."""
|
||||
component = get_component(comp_name)
|
||||
component = get_component(self._hass, comp_name)
|
||||
if component is None:
|
||||
raise ImportError('Unable to load {}'.format(comp_name))
|
||||
wrapped = ModuleWrapper(self._hass, component)
|
||||
@ -230,7 +187,7 @@ def bind_hass(func):
|
||||
return func
|
||||
|
||||
|
||||
def load_order_component(comp_name: str) -> OrderedSet:
|
||||
def load_order_component(hass, comp_name: str) -> OrderedSet:
|
||||
"""Return an OrderedSet of components in the correct order of loading.
|
||||
|
||||
Raises HomeAssistantError if a circular dependency is detected.
|
||||
@ -238,16 +195,16 @@ def load_order_component(comp_name: str) -> OrderedSet:
|
||||
|
||||
Async friendly.
|
||||
"""
|
||||
return _load_order_component(comp_name, OrderedSet(), set())
|
||||
return _load_order_component(hass, comp_name, OrderedSet(), set())
|
||||
|
||||
|
||||
def _load_order_component(comp_name: str, load_order: OrderedSet,
|
||||
def _load_order_component(hass, comp_name: str, load_order: OrderedSet,
|
||||
loading: Set) -> OrderedSet:
|
||||
"""Recursive function to get load order of components.
|
||||
|
||||
Async friendly.
|
||||
"""
|
||||
component = get_component(comp_name)
|
||||
component = get_component(hass, comp_name)
|
||||
|
||||
# If None it does not exist, error already thrown by get_component.
|
||||
if component is None:
|
||||
@ -266,7 +223,8 @@ def _load_order_component(comp_name: str, load_order: OrderedSet,
|
||||
comp_name, dependency)
|
||||
return OrderedSet()
|
||||
|
||||
dep_load_order = _load_order_component(dependency, load_order, loading)
|
||||
dep_load_order = _load_order_component(
|
||||
hass, dependency, load_order, loading)
|
||||
|
||||
# length == 0 means error loading dependency or children
|
||||
if not dep_load_order:
|
||||
@ -280,14 +238,3 @@ def _load_order_component(comp_name: str, load_order: OrderedSet,
|
||||
loading.remove(comp_name)
|
||||
|
||||
return load_order
|
||||
|
||||
|
||||
def _check_prepared() -> None:
|
||||
"""Issue a warning if loader.prepare() has never been called.
|
||||
|
||||
Async friendly.
|
||||
"""
|
||||
if not PREPARED:
|
||||
_LOGGER.warning((
|
||||
"You did not call loader.prepare() yet. "
|
||||
"Certain functionality might not be working"))
|
||||
|
@ -16,8 +16,8 @@ from homeassistant import bootstrap, core, loader
|
||||
from homeassistant.config import (
|
||||
get_default_config_dir, CONF_CORE, CORE_CONFIG_SCHEMA,
|
||||
CONF_PACKAGES, merge_packages_config, _format_config_error,
|
||||
find_config_file, load_yaml_config_file, get_component,
|
||||
extract_domain_configs, config_per_platform, get_platform)
|
||||
find_config_file, load_yaml_config_file,
|
||||
extract_domain_configs, config_per_platform)
|
||||
import homeassistant.util.yaml as yaml
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
@ -201,18 +201,10 @@ def check(config_dir, secrets=False):
|
||||
yaml.yaml.SafeLoader.add_constructor('!secret', yaml._secret_yaml)
|
||||
|
||||
try:
|
||||
class HassConfig():
|
||||
"""Hass object with config."""
|
||||
|
||||
def __init__(self, conf_dir):
|
||||
"""Init the config_dir."""
|
||||
self.config = core.Config()
|
||||
self.config.config_dir = conf_dir
|
||||
|
||||
loader.prepare(HassConfig(config_dir))
|
||||
|
||||
res['components'] = check_ha_config_file(config_dir)
|
||||
hass = core.HomeAssistant()
|
||||
hass.config.config_dir = config_dir
|
||||
|
||||
res['components'] = check_ha_config_file(hass)
|
||||
res['secret_cache'] = OrderedDict(yaml.__SECRET_CACHE)
|
||||
|
||||
for err in res['components'].errors:
|
||||
@ -222,6 +214,7 @@ def check(config_dir, secrets=False):
|
||||
res['except'].setdefault(domain, []).append(err.config)
|
||||
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
_LOGGER.exception("BURB")
|
||||
print(color('red', 'Fatal error while loading config:'), str(err))
|
||||
res['except'].setdefault(ERROR_STR, []).append(str(err))
|
||||
finally:
|
||||
@ -290,8 +283,9 @@ class HomeAssistantConfig(OrderedDict):
|
||||
return self
|
||||
|
||||
|
||||
def check_ha_config_file(config_dir):
|
||||
def check_ha_config_file(hass):
|
||||
"""Check if Home Assistant configuration file is valid."""
|
||||
config_dir = hass.config.config_dir
|
||||
result = HomeAssistantConfig()
|
||||
|
||||
def _pack_error(package, component, config, message):
|
||||
@ -330,7 +324,7 @@ def check_ha_config_file(config_dir):
|
||||
|
||||
# Merge packages
|
||||
merge_packages_config(
|
||||
config, core_config.get(CONF_PACKAGES, {}), _pack_error)
|
||||
hass, config, core_config.get(CONF_PACKAGES, {}), _pack_error)
|
||||
del core_config[CONF_PACKAGES]
|
||||
|
||||
# Ensure we have no None values after merge
|
||||
@ -343,7 +337,7 @@ def check_ha_config_file(config_dir):
|
||||
|
||||
# Process and validate config
|
||||
for domain in components:
|
||||
component = get_component(domain)
|
||||
component = loader.get_component(hass, domain)
|
||||
if not component:
|
||||
result.add_error("Component not found: {}".format(domain))
|
||||
continue
|
||||
@ -375,7 +369,7 @@ def check_ha_config_file(config_dir):
|
||||
platforms.append(p_validated)
|
||||
continue
|
||||
|
||||
platform = get_platform(domain, p_name)
|
||||
platform = loader.get_platform(hass, domain, p_name)
|
||||
|
||||
if platform is None:
|
||||
result.add_error(
|
||||
|
@ -98,14 +98,14 @@ async def _async_setup_component(hass: core.HomeAssistant,
|
||||
_LOGGER.error("Setup failed for %s: %s", domain, msg)
|
||||
async_notify_setup_error(hass, domain, link)
|
||||
|
||||
component = loader.get_component(domain)
|
||||
component = loader.get_component(hass, domain)
|
||||
|
||||
if not component:
|
||||
log_error("Component not found.", False)
|
||||
return False
|
||||
|
||||
# Validate no circular dependencies
|
||||
components = loader.load_order_component(domain)
|
||||
components = loader.load_order_component(hass, domain)
|
||||
|
||||
# OrderedSet is empty if component or dependencies could not be resolved
|
||||
if not components:
|
||||
@ -159,7 +159,7 @@ async def _async_setup_component(hass: core.HomeAssistant,
|
||||
elif result is not True:
|
||||
log_error("Component did not return boolean if setup was successful. "
|
||||
"Disabling component.")
|
||||
loader.set_component(domain, None)
|
||||
loader.set_component(hass, domain, None)
|
||||
return False
|
||||
|
||||
for entry in hass.config_entries.async_entries(domain):
|
||||
@ -193,7 +193,7 @@ async def async_prepare_setup_platform(hass: core.HomeAssistant, config,
|
||||
platform_path, msg)
|
||||
async_notify_setup_error(hass, platform_path)
|
||||
|
||||
platform = loader.get_platform(domain, platform_name)
|
||||
platform = loader.get_platform(hass, domain, platform_name)
|
||||
|
||||
# Not found
|
||||
if platform is None:
|
||||
|
@ -10,8 +10,7 @@ import logging
|
||||
import threading
|
||||
from contextlib import contextmanager
|
||||
|
||||
from homeassistant import (
|
||||
auth, core as ha, loader, data_entry_flow, config_entries)
|
||||
from homeassistant import auth, core as ha, data_entry_flow, config_entries
|
||||
from homeassistant.setup import setup_component, async_setup_component
|
||||
from homeassistant.config import async_process_component_config
|
||||
from homeassistant.helpers import (
|
||||
@ -138,9 +137,6 @@ def async_test_home_assistant(loop):
|
||||
hass.config.units = METRIC_SYSTEM
|
||||
hass.config.skip_pip = True
|
||||
|
||||
if 'custom_components.test' not in loader.AVAILABLE_COMPONENTS:
|
||||
yield from loop.run_in_executor(None, loader.prepare, hass)
|
||||
|
||||
hass.state = ha.CoreState.running
|
||||
|
||||
# Mock async_start
|
||||
|
@ -116,7 +116,7 @@ class TestGenericThermostatHeaterSwitching(unittest.TestCase):
|
||||
|
||||
def test_heater_switch(self):
|
||||
"""Test heater switching test switch."""
|
||||
platform = loader.get_component('switch.test')
|
||||
platform = loader.get_component(self.hass, 'switch.test')
|
||||
platform.init()
|
||||
self.switch_1 = platform.DEVICES[1]
|
||||
assert setup_component(self.hass, switch.DOMAIN, {'switch': {
|
||||
|
@ -17,10 +17,10 @@ from homeassistant.loader import set_component
|
||||
from tests.common import MockConfigEntry, MockModule, mock_coro_func
|
||||
|
||||
|
||||
@pytest.fixture(scope='session', autouse=True)
|
||||
def mock_test_component():
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_test_component(hass):
|
||||
"""Ensure a component called 'test' exists."""
|
||||
set_component('test', MockModule('test'))
|
||||
set_component(hass, 'test', MockModule('test'))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -172,7 +172,8 @@ def test_abort(hass, client):
|
||||
def test_create_account(hass, client):
|
||||
"""Test a flow that creates an account."""
|
||||
set_component(
|
||||
'test', MockModule('test', async_setup_entry=mock_coro_func(True)))
|
||||
hass, 'test',
|
||||
MockModule('test', async_setup_entry=mock_coro_func(True)))
|
||||
|
||||
class TestFlow(FlowHandler):
|
||||
VERSION = 1
|
||||
@ -204,7 +205,8 @@ def test_create_account(hass, client):
|
||||
def test_two_step_flow(hass, client):
|
||||
"""Test we can finish a two step flow."""
|
||||
set_component(
|
||||
'test', MockModule('test', async_setup_entry=mock_coro_func(True)))
|
||||
hass, 'test',
|
||||
MockModule('test', async_setup_entry=mock_coro_func(True)))
|
||||
|
||||
class TestFlow(FlowHandler):
|
||||
VERSION = 1
|
||||
|
@ -3,9 +3,9 @@ import os
|
||||
from datetime import timedelta
|
||||
import unittest
|
||||
from unittest import mock
|
||||
import socket
|
||||
|
||||
import voluptuous as vol
|
||||
from future.backports import socket
|
||||
|
||||
from homeassistant.setup import setup_component
|
||||
from homeassistant.components import device_tracker
|
||||
|
@ -189,7 +189,7 @@ class TestComponentsDeviceTracker(unittest.TestCase):
|
||||
|
||||
def test_update_stale(self):
|
||||
"""Test stalled update."""
|
||||
scanner = get_component('device_tracker.test').SCANNER
|
||||
scanner = get_component(self.hass, 'device_tracker.test').SCANNER
|
||||
scanner.reset()
|
||||
scanner.come_home('DEV1')
|
||||
|
||||
@ -251,7 +251,7 @@ class TestComponentsDeviceTracker(unittest.TestCase):
|
||||
hide_if_away=True)
|
||||
device_tracker.update_config(self.yaml_devices, dev_id, device)
|
||||
|
||||
scanner = get_component('device_tracker.test').SCANNER
|
||||
scanner = get_component(self.hass, 'device_tracker.test').SCANNER
|
||||
scanner.reset()
|
||||
|
||||
with assert_setup_component(1, device_tracker.DOMAIN):
|
||||
@ -270,7 +270,7 @@ class TestComponentsDeviceTracker(unittest.TestCase):
|
||||
hide_if_away=True)
|
||||
device_tracker.update_config(self.yaml_devices, dev_id, device)
|
||||
|
||||
scanner = get_component('device_tracker.test').SCANNER
|
||||
scanner = get_component(self.hass, 'device_tracker.test').SCANNER
|
||||
scanner.reset()
|
||||
|
||||
with assert_setup_component(1, device_tracker.DOMAIN):
|
||||
@ -431,7 +431,7 @@ class TestComponentsDeviceTracker(unittest.TestCase):
|
||||
'zone': zone_info
|
||||
})
|
||||
|
||||
scanner = get_component('device_tracker.test').SCANNER
|
||||
scanner = get_component(self.hass, 'device_tracker.test').SCANNER
|
||||
scanner.reset()
|
||||
scanner.come_home('dev1')
|
||||
|
||||
@ -547,7 +547,7 @@ def test_bad_platform(hass):
|
||||
|
||||
async def test_adding_unknown_device_to_config(mock_device_tracker_conf, hass):
|
||||
"""Test the adding of unknown devices to configuration file."""
|
||||
scanner = get_component('device_tracker.test').SCANNER
|
||||
scanner = get_component(hass, 'device_tracker.test').SCANNER
|
||||
scanner.reset()
|
||||
scanner.come_home('DEV1')
|
||||
|
||||
|
@ -118,7 +118,7 @@ class TestLight(unittest.TestCase):
|
||||
|
||||
def test_services(self):
|
||||
"""Test the provided services."""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
@ -267,7 +267,7 @@ class TestLight(unittest.TestCase):
|
||||
|
||||
def test_broken_light_profiles(self):
|
||||
"""Test light profiles."""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
|
||||
user_light_file = self.hass.config.path(light.LIGHT_PROFILES_FILE)
|
||||
@ -282,7 +282,7 @@ class TestLight(unittest.TestCase):
|
||||
|
||||
def test_light_profiles(self):
|
||||
"""Test light profiles."""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
|
||||
user_light_file = self.hass.config.path(light.LIGHT_PROFILES_FILE)
|
||||
|
@ -16,7 +16,7 @@ class TestScene(unittest.TestCase):
|
||||
def setUp(self): # pylint: disable=invalid-name
|
||||
"""Setup things to be run when tests are started."""
|
||||
self.hass = get_test_home_assistant()
|
||||
test_light = loader.get_component('light.test')
|
||||
test_light = loader.get_component(self.hass, 'light.test')
|
||||
test_light.init()
|
||||
|
||||
self.assertTrue(setup_component(self.hass, light.DOMAIN, {
|
||||
|
@ -71,7 +71,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
def test_flux_when_switch_is_off(self):
|
||||
"""Test the flux switch when it is off."""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -113,7 +113,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
def test_flux_before_sunrise(self):
|
||||
"""Test the flux switch before sunrise."""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -160,7 +160,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
# pylint: disable=invalid-name
|
||||
def test_flux_after_sunrise_before_sunset(self):
|
||||
"""Test the flux switch after sunrise and before sunset."""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -207,7 +207,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
# pylint: disable=invalid-name
|
||||
def test_flux_after_sunset_before_stop(self):
|
||||
"""Test the flux switch after sunset and before stop."""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -255,7 +255,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
# pylint: disable=invalid-name
|
||||
def test_flux_after_stop_before_sunrise(self):
|
||||
"""Test the flux switch after stop and before sunrise."""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -302,7 +302,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
# pylint: disable=invalid-name
|
||||
def test_flux_with_custom_start_stop_times(self):
|
||||
"""Test the flux with custom start and stop times."""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -353,7 +353,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
This test has the stop_time on the next day (after midnight).
|
||||
"""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -405,7 +405,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
This test has the stop_time on the next day (after midnight).
|
||||
"""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -456,7 +456,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
This test has the stop_time on the next day (after midnight).
|
||||
"""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -507,7 +507,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
This test has the stop_time on the next day (after midnight).
|
||||
"""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -558,7 +558,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
This test has the stop_time on the next day (after midnight).
|
||||
"""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -606,7 +606,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
# pylint: disable=invalid-name
|
||||
def test_flux_with_custom_colortemps(self):
|
||||
"""Test the flux with custom start and stop colortemps."""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -656,7 +656,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
# pylint: disable=invalid-name
|
||||
def test_flux_with_custom_brightness(self):
|
||||
"""Test the flux with custom start and stop colortemps."""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -704,7 +704,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
def test_flux_with_multiple_lights(self):
|
||||
"""Test the flux switch with multiple light entities."""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -773,7 +773,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
def test_flux_with_mired(self):
|
||||
"""Test the flux switch´s mode mired."""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
@ -818,7 +818,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
def test_flux_with_rgb(self):
|
||||
"""Test the flux switch´s mode rgb."""
|
||||
platform = loader.get_component('light.test')
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform.init()
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, light.DOMAIN,
|
||||
|
@ -17,7 +17,7 @@ class TestSwitch(unittest.TestCase):
|
||||
def setUp(self):
|
||||
"""Setup things to be run when tests are started."""
|
||||
self.hass = get_test_home_assistant()
|
||||
platform = loader.get_component('switch.test')
|
||||
platform = loader.get_component(self.hass, 'switch.test')
|
||||
platform.init()
|
||||
# Switch 1 is ON, switch 2 is OFF
|
||||
self.switch_1, self.switch_2, self.switch_3 = \
|
||||
@ -79,10 +79,10 @@ class TestSwitch(unittest.TestCase):
|
||||
def test_setup_two_platforms(self):
|
||||
"""Test with bad configuration."""
|
||||
# Test if switch component returns 0 switches
|
||||
test_platform = loader.get_component('switch.test')
|
||||
test_platform = loader.get_component(self.hass, 'switch.test')
|
||||
test_platform.init(True)
|
||||
|
||||
loader.set_component('switch.test2', test_platform)
|
||||
loader.set_component(self.hass, 'switch.test2', test_platform)
|
||||
test_platform.init(False)
|
||||
|
||||
self.assertTrue(setup_component(
|
||||
|
@ -22,12 +22,12 @@ class TestDeviceSunLightTrigger(unittest.TestCase):
|
||||
self.hass = get_test_home_assistant()
|
||||
|
||||
self.scanner = loader.get_component(
|
||||
'device_tracker.test').get_scanner(None, None)
|
||||
self.hass, 'device_tracker.test').get_scanner(None, None)
|
||||
|
||||
self.scanner.reset()
|
||||
self.scanner.come_home('DEV1')
|
||||
|
||||
loader.get_component('light.test').init()
|
||||
loader.get_component(self.hass, 'light.test').init()
|
||||
|
||||
with patch(
|
||||
'homeassistant.components.device_tracker.load_yaml_config_file',
|
||||
|
@ -10,8 +10,6 @@ import voluptuous as vol
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
from tests.common import get_test_home_assistant
|
||||
|
||||
|
||||
def test_boolean():
|
||||
"""Test boolean validation."""
|
||||
@ -256,24 +254,6 @@ def test_event_schema():
|
||||
cv.EVENT_SCHEMA(value)
|
||||
|
||||
|
||||
def test_platform_validator():
|
||||
"""Test platform validation."""
|
||||
hass = None
|
||||
|
||||
try:
|
||||
hass = get_test_home_assistant()
|
||||
|
||||
schema = vol.Schema(cv.platform_validator('light'))
|
||||
|
||||
with pytest.raises(vol.MultipleInvalid):
|
||||
schema('platform_that_does_not_exist')
|
||||
|
||||
schema('hue')
|
||||
finally:
|
||||
if hass is not None:
|
||||
hass.stop()
|
||||
|
||||
|
||||
def test_icon():
|
||||
"""Test icon validation."""
|
||||
schema = vol.Schema(cv.icon)
|
||||
|
@ -129,11 +129,11 @@ class TestHelpersDiscovery:
|
||||
platform_calls.append('disc' if discovery_info else 'component')
|
||||
|
||||
loader.set_component(
|
||||
'test_component',
|
||||
self.hass, 'test_component',
|
||||
MockModule('test_component', setup=component_setup))
|
||||
|
||||
loader.set_component(
|
||||
'switch.test_circular',
|
||||
self.hass, 'switch.test_circular',
|
||||
MockPlatform(setup_platform,
|
||||
dependencies=['test_component']))
|
||||
|
||||
@ -177,11 +177,11 @@ class TestHelpersDiscovery:
|
||||
return True
|
||||
|
||||
loader.set_component(
|
||||
'test_component1',
|
||||
self.hass, 'test_component1',
|
||||
MockModule('test_component1', setup=component1_setup))
|
||||
|
||||
loader.set_component(
|
||||
'test_component2',
|
||||
self.hass, 'test_component2',
|
||||
MockModule('test_component2', setup=component2_setup))
|
||||
|
||||
@callback
|
||||
|
@ -75,9 +75,9 @@ class TestHelpersEntityComponent(unittest.TestCase):
|
||||
component_setup = Mock(return_value=True)
|
||||
platform_setup = Mock(return_value=None)
|
||||
loader.set_component(
|
||||
'test_component',
|
||||
self.hass, 'test_component',
|
||||
MockModule('test_component', setup=component_setup))
|
||||
loader.set_component('test_domain.mod2',
|
||||
loader.set_component(self.hass, 'test_domain.mod2',
|
||||
MockPlatform(platform_setup, ['test_component']))
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, self.hass)
|
||||
@ -100,8 +100,10 @@ class TestHelpersEntityComponent(unittest.TestCase):
|
||||
platform1_setup = Mock(side_effect=Exception('Broken'))
|
||||
platform2_setup = Mock(return_value=None)
|
||||
|
||||
loader.set_component('test_domain.mod1', MockPlatform(platform1_setup))
|
||||
loader.set_component('test_domain.mod2', MockPlatform(platform2_setup))
|
||||
loader.set_component(self.hass, 'test_domain.mod1',
|
||||
MockPlatform(platform1_setup))
|
||||
loader.set_component(self.hass, 'test_domain.mod2',
|
||||
MockPlatform(platform2_setup))
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, self.hass)
|
||||
|
||||
@ -145,7 +147,7 @@ class TestHelpersEntityComponent(unittest.TestCase):
|
||||
"""Test the platform setup."""
|
||||
add_devices([MockEntity(should_poll=True)])
|
||||
|
||||
loader.set_component('test_domain.platform',
|
||||
loader.set_component(self.hass, 'test_domain.platform',
|
||||
MockPlatform(platform_setup))
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, self.hass)
|
||||
@ -172,7 +174,7 @@ class TestHelpersEntityComponent(unittest.TestCase):
|
||||
|
||||
platform = MockPlatform(platform_setup)
|
||||
|
||||
loader.set_component('test_domain.platform', platform)
|
||||
loader.set_component(self.hass, 'test_domain.platform', platform)
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, self.hass)
|
||||
|
||||
@ -220,7 +222,8 @@ def test_platform_not_ready(hass):
|
||||
"""Test that we retry when platform not ready."""
|
||||
platform1_setup = Mock(side_effect=[PlatformNotReady, PlatformNotReady,
|
||||
None])
|
||||
loader.set_component('test_domain.mod1', MockPlatform(platform1_setup))
|
||||
loader.set_component(hass, 'test_domain.mod1',
|
||||
MockPlatform(platform1_setup))
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
|
||||
@ -316,10 +319,11 @@ def test_setup_dependencies_platform(hass):
|
||||
We're explictely testing that we process dependencies even if a component
|
||||
with the same name has already been loaded.
|
||||
"""
|
||||
loader.set_component('test_component', MockModule('test_component'))
|
||||
loader.set_component('test_component2', MockModule('test_component2'))
|
||||
loader.set_component(hass, 'test_component', MockModule('test_component'))
|
||||
loader.set_component(hass, 'test_component2',
|
||||
MockModule('test_component2'))
|
||||
loader.set_component(
|
||||
'test_domain.test_component',
|
||||
hass, 'test_domain.test_component',
|
||||
MockPlatform(dependencies=['test_component', 'test_component2']))
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
@ -341,7 +345,7 @@ async def test_setup_entry(hass):
|
||||
"""Test setup entry calls async_setup_entry on platform."""
|
||||
mock_setup_entry = Mock(return_value=mock_coro(True))
|
||||
loader.set_component(
|
||||
'test_domain.entry_domain',
|
||||
hass, 'test_domain.entry_domain',
|
||||
MockPlatform(async_setup_entry=mock_setup_entry))
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
@ -366,7 +370,7 @@ async def test_setup_entry_fails_duplicate(hass):
|
||||
"""Test we don't allow setting up a config entry twice."""
|
||||
mock_setup_entry = Mock(return_value=mock_coro(True))
|
||||
loader.set_component(
|
||||
'test_domain.entry_domain',
|
||||
hass, 'test_domain.entry_domain',
|
||||
MockPlatform(async_setup_entry=mock_setup_entry))
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
@ -382,7 +386,7 @@ async def test_unload_entry_resets_platform(hass):
|
||||
"""Test unloading an entry removes all entities."""
|
||||
mock_setup_entry = Mock(return_value=mock_coro(True))
|
||||
loader.set_component(
|
||||
'test_domain.entry_domain',
|
||||
hass, 'test_domain.entry_domain',
|
||||
MockPlatform(async_setup_entry=mock_setup_entry))
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
|
@ -147,7 +147,7 @@ class TestHelpersEntityPlatform(unittest.TestCase):
|
||||
platform = MockPlatform(platform_setup)
|
||||
platform.SCAN_INTERVAL = timedelta(seconds=30)
|
||||
|
||||
loader.set_component('test_domain.platform', platform)
|
||||
loader.set_component(self.hass, 'test_domain.platform', platform)
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, self.hass)
|
||||
|
||||
@ -184,7 +184,7 @@ def test_platform_warn_slow_setup(hass):
|
||||
"""Warn we log when platform setup takes a long time."""
|
||||
platform = MockPlatform()
|
||||
|
||||
loader.set_component('test_domain.platform', platform)
|
||||
loader.set_component(hass, 'test_domain.platform', platform)
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
|
||||
@ -218,7 +218,7 @@ def test_platform_error_slow_setup(hass, caplog):
|
||||
|
||||
platform = MockPlatform(async_setup_platform=setup_platform)
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
loader.set_component('test_domain.test_platform', platform)
|
||||
loader.set_component(hass, 'test_domain.test_platform', platform)
|
||||
yield from component.async_setup({
|
||||
DOMAIN: {
|
||||
'platform': 'test_platform',
|
||||
@ -260,7 +260,7 @@ def test_parallel_updates_async_platform(hass):
|
||||
|
||||
platform.async_setup_platform = mock_update
|
||||
|
||||
loader.set_component('test_domain.platform', platform)
|
||||
loader.set_component(hass, 'test_domain.platform', platform)
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
component._platforms = {}
|
||||
@ -288,7 +288,7 @@ def test_parallel_updates_async_platform_with_constant(hass):
|
||||
platform.async_setup_platform = mock_update
|
||||
platform.PARALLEL_UPDATES = 1
|
||||
|
||||
loader.set_component('test_domain.platform', platform)
|
||||
loader.set_component(hass, 'test_domain.platform', platform)
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
component._platforms = {}
|
||||
@ -309,7 +309,7 @@ def test_parallel_updates_sync_platform(hass):
|
||||
"""Warn we log when platform setup takes a long time."""
|
||||
platform = MockPlatform(setup_platform=lambda *args: None)
|
||||
|
||||
loader.set_component('test_domain.platform', platform)
|
||||
loader.set_component(hass, 'test_domain.platform', platform)
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
component._platforms = {}
|
||||
|
@ -138,7 +138,7 @@ class TestServiceHelpers(unittest.TestCase):
|
||||
self.hass.states.set('light.Ceiling', STATE_OFF)
|
||||
self.hass.states.set('light.Kitchen', STATE_OFF)
|
||||
|
||||
loader.get_component('group').Group.create_group(
|
||||
loader.get_component(self.hass, 'group').Group.create_group(
|
||||
self.hass, 'test', ['light.Ceiling', 'light.Kitchen'])
|
||||
|
||||
call = ha.ServiceCall('light', 'turn_on',
|
||||
@ -160,7 +160,7 @@ class TestServiceHelpers(unittest.TestCase):
|
||||
@asyncio.coroutine
|
||||
def test_async_get_all_descriptions(hass):
|
||||
"""Test async_get_all_descriptions."""
|
||||
group = loader.get_component('group')
|
||||
group = loader.get_component(hass, 'group')
|
||||
group_config = {group.DOMAIN: {}}
|
||||
yield from async_setup_component(hass, group.DOMAIN, group_config)
|
||||
descriptions = yield from service.async_get_all_descriptions(hass)
|
||||
@ -170,7 +170,7 @@ def test_async_get_all_descriptions(hass):
|
||||
assert 'description' in descriptions['group']['reload']
|
||||
assert 'fields' in descriptions['group']['reload']
|
||||
|
||||
logger = loader.get_component('logger')
|
||||
logger = loader.get_component(hass, 'logger')
|
||||
logger_config = {logger.DOMAIN: {}}
|
||||
yield from async_setup_component(hass, logger.DOMAIN, logger_config)
|
||||
descriptions = yield from service.async_get_all_descriptions(hass)
|
||||
|
@ -50,15 +50,15 @@ async def test_component_translation_file(hass):
|
||||
})
|
||||
|
||||
assert path.normpath(translation.component_translation_file(
|
||||
'switch.test', 'en')) == path.normpath(hass.config.path(
|
||||
hass, 'switch.test', 'en')) == path.normpath(hass.config.path(
|
||||
'custom_components', 'switch', '.translations', 'test.en.json'))
|
||||
|
||||
assert path.normpath(translation.component_translation_file(
|
||||
'test_standalone', 'en')) == path.normpath(hass.config.path(
|
||||
hass, 'test_standalone', 'en')) == path.normpath(hass.config.path(
|
||||
'custom_components', '.translations', 'test_standalone.en.json'))
|
||||
|
||||
assert path.normpath(translation.component_translation_file(
|
||||
'test_package', 'en')) == path.normpath(hass.config.path(
|
||||
hass, 'test_package', 'en')) == path.normpath(hass.config.path(
|
||||
'custom_components', 'test_package', '.translations', 'en.json'))
|
||||
|
||||
|
||||
|
@ -7,7 +7,6 @@ from unittest.mock import patch
|
||||
|
||||
import homeassistant.scripts.check_config as check_config
|
||||
from homeassistant.config import YAML_CONFIG_FILE
|
||||
from homeassistant.loader import set_component
|
||||
from tests.common import patch_yaml_files, get_test_config_dir
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@ -106,7 +105,6 @@ class TestCheckConfig(unittest.TestCase):
|
||||
def test_component_platform_not_found(self, isfile_patch):
|
||||
"""Test errors if component or platform not found."""
|
||||
# Make sure they don't exist
|
||||
set_component('beer', None)
|
||||
files = {
|
||||
YAML_CONFIG_FILE: BASE_CONFIG + 'beer:',
|
||||
}
|
||||
@ -119,7 +117,6 @@ class TestCheckConfig(unittest.TestCase):
|
||||
assert res['secrets'] == {}
|
||||
assert len(res['yaml_files']) == 1
|
||||
|
||||
set_component('light.beer', None)
|
||||
files = {
|
||||
YAML_CONFIG_FILE: BASE_CONFIG + 'light:\n platform: beer',
|
||||
}
|
||||
|
@ -568,7 +568,7 @@ def merge_log_err(hass):
|
||||
yield logerr
|
||||
|
||||
|
||||
def test_merge(merge_log_err):
|
||||
def test_merge(merge_log_err, hass):
|
||||
"""Test if we can merge packages."""
|
||||
packages = {
|
||||
'pack_dict': {'input_boolean': {'ib1': None}},
|
||||
@ -582,7 +582,7 @@ def test_merge(merge_log_err):
|
||||
'input_boolean': {'ib2': None},
|
||||
'light': {'platform': 'test'}
|
||||
}
|
||||
config_util.merge_packages_config(config, packages)
|
||||
config_util.merge_packages_config(hass, config, packages)
|
||||
|
||||
assert merge_log_err.call_count == 0
|
||||
assert len(config) == 5
|
||||
@ -592,7 +592,7 @@ def test_merge(merge_log_err):
|
||||
assert config['wake_on_lan'] is None
|
||||
|
||||
|
||||
def test_merge_try_falsy(merge_log_err):
|
||||
def test_merge_try_falsy(merge_log_err, hass):
|
||||
"""Ensure we dont add falsy items like empty OrderedDict() to list."""
|
||||
packages = {
|
||||
'pack_falsy_to_lst': {'automation': OrderedDict()},
|
||||
@ -603,7 +603,7 @@ def test_merge_try_falsy(merge_log_err):
|
||||
'automation': {'do': 'something'},
|
||||
'light': {'some': 'light'},
|
||||
}
|
||||
config_util.merge_packages_config(config, packages)
|
||||
config_util.merge_packages_config(hass, config, packages)
|
||||
|
||||
assert merge_log_err.call_count == 0
|
||||
assert len(config) == 3
|
||||
@ -611,7 +611,7 @@ def test_merge_try_falsy(merge_log_err):
|
||||
assert len(config['light']) == 1
|
||||
|
||||
|
||||
def test_merge_new(merge_log_err):
|
||||
def test_merge_new(merge_log_err, hass):
|
||||
"""Test adding new components to outer scope."""
|
||||
packages = {
|
||||
'pack_1': {'light': [{'platform': 'one'}]},
|
||||
@ -624,7 +624,7 @@ def test_merge_new(merge_log_err):
|
||||
config = {
|
||||
config_util.CONF_CORE: {config_util.CONF_PACKAGES: packages},
|
||||
}
|
||||
config_util.merge_packages_config(config, packages)
|
||||
config_util.merge_packages_config(hass, config, packages)
|
||||
|
||||
assert merge_log_err.call_count == 0
|
||||
assert 'api' in config
|
||||
@ -633,7 +633,7 @@ def test_merge_new(merge_log_err):
|
||||
assert len(config['panel_custom']) == 1
|
||||
|
||||
|
||||
def test_merge_type_mismatch(merge_log_err):
|
||||
def test_merge_type_mismatch(merge_log_err, hass):
|
||||
"""Test if we have a type mismatch for packages."""
|
||||
packages = {
|
||||
'pack_1': {'input_boolean': [{'ib1': None}]},
|
||||
@ -646,7 +646,7 @@ def test_merge_type_mismatch(merge_log_err):
|
||||
'input_select': [{'ib2': None}],
|
||||
'light': [{'platform': 'two'}]
|
||||
}
|
||||
config_util.merge_packages_config(config, packages)
|
||||
config_util.merge_packages_config(hass, config, packages)
|
||||
|
||||
assert merge_log_err.call_count == 2
|
||||
assert len(config) == 4
|
||||
@ -654,7 +654,7 @@ def test_merge_type_mismatch(merge_log_err):
|
||||
assert len(config['light']) == 2
|
||||
|
||||
|
||||
def test_merge_once_only(merge_log_err):
|
||||
def test_merge_once_only(merge_log_err, hass):
|
||||
"""Test if we have a merge for a comp that may occur only once."""
|
||||
packages = {
|
||||
'pack_2': {
|
||||
@ -666,7 +666,7 @@ def test_merge_once_only(merge_log_err):
|
||||
config_util.CONF_CORE: {config_util.CONF_PACKAGES: packages},
|
||||
'mqtt': {}, 'api': {}
|
||||
}
|
||||
config_util.merge_packages_config(config, packages)
|
||||
config_util.merge_packages_config(hass, config, packages)
|
||||
assert merge_log_err.call_count == 1
|
||||
assert len(config) == 3
|
||||
|
||||
@ -682,13 +682,13 @@ def test_merge_id_schema(hass):
|
||||
'qwikswitch': 'dict',
|
||||
}
|
||||
for name, expected_type in types.items():
|
||||
module = config_util.get_component(name)
|
||||
module = config_util.get_component(hass, name)
|
||||
typ, _ = config_util._identify_config_schema(module)
|
||||
assert typ == expected_type, "{} expected {}, got {}".format(
|
||||
name, expected_type, typ)
|
||||
|
||||
|
||||
def test_merge_duplicate_keys(merge_log_err):
|
||||
def test_merge_duplicate_keys(merge_log_err, hass):
|
||||
"""Test if keys in dicts are duplicates."""
|
||||
packages = {
|
||||
'pack_1': {'input_select': {'ib1': None}},
|
||||
@ -697,7 +697,7 @@ def test_merge_duplicate_keys(merge_log_err):
|
||||
config_util.CONF_CORE: {config_util.CONF_PACKAGES: packages},
|
||||
'input_select': {'ib1': None},
|
||||
}
|
||||
config_util.merge_packages_config(config, packages)
|
||||
config_util.merge_packages_config(hass, config, packages)
|
||||
|
||||
assert merge_log_err.call_count == 1
|
||||
assert len(config) == 2
|
||||
|
@ -27,7 +27,7 @@ def test_call_setup_entry(hass):
|
||||
mock_setup_entry = MagicMock(return_value=mock_coro(True))
|
||||
|
||||
loader.set_component(
|
||||
'comp',
|
||||
hass, 'comp',
|
||||
MockModule('comp', async_setup_entry=mock_setup_entry))
|
||||
|
||||
result = yield from async_setup_component(hass, 'comp', {})
|
||||
@ -36,12 +36,12 @@ def test_call_setup_entry(hass):
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_remove_entry(manager):
|
||||
def test_remove_entry(hass, manager):
|
||||
"""Test that we can remove an entry."""
|
||||
mock_unload_entry = MagicMock(return_value=mock_coro(True))
|
||||
|
||||
loader.set_component(
|
||||
'test',
|
||||
hass, 'test',
|
||||
MockModule('comp', async_unload_entry=mock_unload_entry))
|
||||
|
||||
MockConfigEntry(domain='test', entry_id='test1').add_to_manager(manager)
|
||||
@ -63,7 +63,7 @@ def test_remove_entry(manager):
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_remove_entry_raises(manager):
|
||||
def test_remove_entry_raises(hass, manager):
|
||||
"""Test if a component raises while removing entry."""
|
||||
@asyncio.coroutine
|
||||
def mock_unload_entry(hass, entry):
|
||||
@ -71,7 +71,7 @@ def test_remove_entry_raises(manager):
|
||||
raise Exception("BROKEN")
|
||||
|
||||
loader.set_component(
|
||||
'test',
|
||||
hass, 'test',
|
||||
MockModule('comp', async_unload_entry=mock_unload_entry))
|
||||
|
||||
MockConfigEntry(domain='test', entry_id='test1').add_to_manager(manager)
|
||||
@ -96,7 +96,7 @@ def test_add_entry_calls_setup_entry(hass, manager):
|
||||
mock_setup_entry = MagicMock(return_value=mock_coro(True))
|
||||
|
||||
loader.set_component(
|
||||
'comp',
|
||||
hass, 'comp',
|
||||
MockModule('comp', async_setup_entry=mock_setup_entry))
|
||||
|
||||
class TestFlow(data_entry_flow.FlowHandler):
|
||||
@ -151,6 +151,8 @@ def test_domains_gets_uniques(manager):
|
||||
@asyncio.coroutine
|
||||
def test_saving_and_loading(hass):
|
||||
"""Test that we're saving and loading correctly."""
|
||||
loader.set_component(hass, 'test', MockModule('test'))
|
||||
|
||||
class TestFlow(data_entry_flow.FlowHandler):
|
||||
VERSION = 5
|
||||
|
||||
@ -217,12 +219,12 @@ async def test_forward_entry_sets_up_component(hass):
|
||||
|
||||
mock_original_setup_entry = MagicMock(return_value=mock_coro(True))
|
||||
loader.set_component(
|
||||
'original',
|
||||
hass, 'original',
|
||||
MockModule('original', async_setup_entry=mock_original_setup_entry))
|
||||
|
||||
mock_forwarded_setup_entry = MagicMock(return_value=mock_coro(True))
|
||||
loader.set_component(
|
||||
'forwarded',
|
||||
hass, 'forwarded',
|
||||
MockModule('forwarded', async_setup_entry=mock_forwarded_setup_entry))
|
||||
|
||||
await hass.config_entries.async_forward_entry_setup(entry, 'forwarded')
|
||||
@ -236,7 +238,7 @@ async def test_forward_entry_does_not_setup_entry_if_setup_fails(hass):
|
||||
|
||||
mock_setup = MagicMock(return_value=mock_coro(False))
|
||||
mock_setup_entry = MagicMock()
|
||||
loader.set_component('forwarded', MockModule(
|
||||
hass, loader.set_component(hass, 'forwarded', MockModule(
|
||||
'forwarded',
|
||||
async_setup=mock_setup,
|
||||
async_setup_entry=mock_setup_entry,
|
||||
@ -249,6 +251,7 @@ async def test_forward_entry_does_not_setup_entry_if_setup_fails(hass):
|
||||
|
||||
async def test_discovery_notification(hass):
|
||||
"""Test that we create/dismiss a notification when source is discovery."""
|
||||
loader.set_component(hass, 'test', MockModule('test'))
|
||||
await async_setup_component(hass, 'persistent_notification', {})
|
||||
|
||||
class TestFlow(data_entry_flow.FlowHandler):
|
||||
|
@ -27,37 +27,40 @@ class TestLoader(unittest.TestCase):
|
||||
|
||||
def test_set_component(self):
|
||||
"""Test if set_component works."""
|
||||
loader.set_component('switch.test_set', http)
|
||||
comp = object()
|
||||
loader.set_component(self.hass, 'switch.test_set', comp)
|
||||
|
||||
self.assertEqual(http, loader.get_component('switch.test_set'))
|
||||
self.assertEqual(comp,
|
||||
loader.get_component(self.hass, 'switch.test_set'))
|
||||
|
||||
def test_get_component(self):
|
||||
"""Test if get_component works."""
|
||||
self.assertEqual(http, loader.get_component('http'))
|
||||
|
||||
self.assertIsNotNone(loader.get_component('switch.test'))
|
||||
self.assertEqual(http, loader.get_component(self.hass, 'http'))
|
||||
self.assertIsNotNone(loader.get_component(self.hass, 'light.hue'))
|
||||
|
||||
def test_load_order_component(self):
|
||||
"""Test if we can get the proper load order of components."""
|
||||
loader.set_component('mod1', MockModule('mod1'))
|
||||
loader.set_component('mod2', MockModule('mod2', ['mod1']))
|
||||
loader.set_component('mod3', MockModule('mod3', ['mod2']))
|
||||
loader.set_component(self.hass, 'mod1', MockModule('mod1'))
|
||||
loader.set_component(self.hass, 'mod2', MockModule('mod2', ['mod1']))
|
||||
loader.set_component(self.hass, 'mod3', MockModule('mod3', ['mod2']))
|
||||
|
||||
self.assertEqual(
|
||||
['mod1', 'mod2', 'mod3'], loader.load_order_component('mod3'))
|
||||
['mod1', 'mod2', 'mod3'],
|
||||
loader.load_order_component(self.hass, 'mod3'))
|
||||
|
||||
# Create circular dependency
|
||||
loader.set_component('mod1', MockModule('mod1', ['mod3']))
|
||||
loader.set_component(self.hass, 'mod1', MockModule('mod1', ['mod3']))
|
||||
|
||||
self.assertEqual([], loader.load_order_component('mod3'))
|
||||
self.assertEqual([], loader.load_order_component(self.hass, 'mod3'))
|
||||
|
||||
# Depend on non-existing component
|
||||
loader.set_component('mod1', MockModule('mod1', ['nonexisting']))
|
||||
loader.set_component(self.hass, 'mod1',
|
||||
MockModule('mod1', ['nonexisting']))
|
||||
|
||||
self.assertEqual([], loader.load_order_component('mod1'))
|
||||
self.assertEqual([], loader.load_order_component(self.hass, 'mod1'))
|
||||
|
||||
# Try to get load order for non-existing component
|
||||
self.assertEqual([], loader.load_order_component('mod1'))
|
||||
self.assertEqual([], loader.load_order_component(self.hass, 'mod1'))
|
||||
|
||||
|
||||
def test_component_loader(hass):
|
||||
|
@ -35,7 +35,8 @@ class TestRequirements:
|
||||
mock_dirname.return_value = 'ha_package_path'
|
||||
self.hass.config.skip_pip = False
|
||||
loader.set_component(
|
||||
'comp', MockModule('comp', requirements=['package==0.0.1']))
|
||||
self.hass, 'comp',
|
||||
MockModule('comp', requirements=['package==0.0.1']))
|
||||
assert setup.setup_component(self.hass, 'comp')
|
||||
assert 'comp' in self.hass.config.components
|
||||
assert mock_install.call_args == mock.call(
|
||||
@ -53,7 +54,8 @@ class TestRequirements:
|
||||
mock_dirname.return_value = 'ha_package_path'
|
||||
self.hass.config.skip_pip = False
|
||||
loader.set_component(
|
||||
'comp', MockModule('comp', requirements=['package==0.0.1']))
|
||||
self.hass, 'comp',
|
||||
MockModule('comp', requirements=['package==0.0.1']))
|
||||
assert setup.setup_component(self.hass, 'comp')
|
||||
assert 'comp' in self.hass.config.components
|
||||
assert mock_install.call_args == mock.call(
|
||||
|
@ -49,6 +49,7 @@ class TestSetup:
|
||||
}
|
||||
}, required=True)
|
||||
loader.set_component(
|
||||
self.hass,
|
||||
'comp_conf', MockModule('comp_conf', config_schema=config_schema))
|
||||
|
||||
with assert_setup_component(0):
|
||||
@ -93,10 +94,12 @@ class TestSetup:
|
||||
'hello': str,
|
||||
})
|
||||
loader.set_component(
|
||||
self.hass,
|
||||
'platform_conf',
|
||||
MockModule('platform_conf', platform_schema=platform_schema))
|
||||
|
||||
loader.set_component(
|
||||
self.hass,
|
||||
'platform_conf.whatever', MockPlatform('whatever'))
|
||||
|
||||
with assert_setup_component(0):
|
||||
@ -179,7 +182,8 @@ class TestSetup:
|
||||
"""Test we do not setup a component twice."""
|
||||
mock_setup = mock.MagicMock(return_value=True)
|
||||
|
||||
loader.set_component('comp', MockModule('comp', setup=mock_setup))
|
||||
loader.set_component(
|
||||
self.hass, 'comp', MockModule('comp', setup=mock_setup))
|
||||
|
||||
assert setup.setup_component(self.hass, 'comp')
|
||||
assert mock_setup.called
|
||||
@ -195,6 +199,7 @@ class TestSetup:
|
||||
"""Component setup should fail if requirement can't install."""
|
||||
self.hass.config.skip_pip = False
|
||||
loader.set_component(
|
||||
self.hass,
|
||||
'comp', MockModule('comp', requirements=['package==0.0.1']))
|
||||
|
||||
assert not setup.setup_component(self.hass, 'comp')
|
||||
@ -210,6 +215,7 @@ class TestSetup:
|
||||
result.append(1)
|
||||
|
||||
loader.set_component(
|
||||
self.hass,
|
||||
'comp', MockModule('comp', async_setup=async_setup))
|
||||
|
||||
def setup_component():
|
||||
@ -227,20 +233,23 @@ class TestSetup:
|
||||
def test_component_not_setup_missing_dependencies(self):
|
||||
"""Test we do not setup a component if not all dependencies loaded."""
|
||||
deps = ['non_existing']
|
||||
loader.set_component('comp', MockModule('comp', dependencies=deps))
|
||||
loader.set_component(
|
||||
self.hass, 'comp', MockModule('comp', dependencies=deps))
|
||||
|
||||
assert not setup.setup_component(self.hass, 'comp', {})
|
||||
assert 'comp' not in self.hass.config.components
|
||||
|
||||
self.hass.data.pop(setup.DATA_SETUP)
|
||||
|
||||
loader.set_component('non_existing', MockModule('non_existing'))
|
||||
loader.set_component(
|
||||
self.hass, 'non_existing', MockModule('non_existing'))
|
||||
assert setup.setup_component(self.hass, 'comp', {})
|
||||
|
||||
def test_component_failing_setup(self):
|
||||
"""Test component that fails setup."""
|
||||
loader.set_component(
|
||||
'comp', MockModule('comp', setup=lambda hass, config: False))
|
||||
self.hass, 'comp',
|
||||
MockModule('comp', setup=lambda hass, config: False))
|
||||
|
||||
assert not setup.setup_component(self.hass, 'comp', {})
|
||||
assert 'comp' not in self.hass.config.components
|
||||
@ -251,7 +260,8 @@ class TestSetup:
|
||||
"""Setup that raises exception."""
|
||||
raise Exception('fail!')
|
||||
|
||||
loader.set_component('comp', MockModule('comp', setup=exception_setup))
|
||||
loader.set_component(
|
||||
self.hass, 'comp', MockModule('comp', setup=exception_setup))
|
||||
|
||||
assert not setup.setup_component(self.hass, 'comp', {})
|
||||
assert 'comp' not in self.hass.config.components
|
||||
@ -264,11 +274,12 @@ class TestSetup:
|
||||
return True
|
||||
raise Exception('Config not passed in: {}'.format(config))
|
||||
|
||||
loader.set_component('comp_a',
|
||||
MockModule('comp_a', setup=config_check_setup))
|
||||
loader.set_component(
|
||||
self.hass, 'comp_a',
|
||||
MockModule('comp_a', setup=config_check_setup))
|
||||
|
||||
loader.set_component('switch.platform_a', MockPlatform('comp_b',
|
||||
['comp_a']))
|
||||
loader.set_component(
|
||||
self.hass, 'switch.platform_a', MockPlatform('comp_b', ['comp_a']))
|
||||
|
||||
setup.setup_component(self.hass, 'switch', {
|
||||
'comp_a': {
|
||||
@ -289,6 +300,7 @@ class TestSetup:
|
||||
mock_setup = mock.MagicMock(spec_set=True)
|
||||
|
||||
loader.set_component(
|
||||
self.hass,
|
||||
'switch.platform_a',
|
||||
MockPlatform(platform_schema=platform_schema,
|
||||
setup_platform=mock_setup))
|
||||
@ -330,29 +342,34 @@ class TestSetup:
|
||||
def test_disable_component_if_invalid_return(self):
|
||||
"""Test disabling component if invalid return."""
|
||||
loader.set_component(
|
||||
self.hass,
|
||||
'disabled_component',
|
||||
MockModule('disabled_component', setup=lambda hass, config: None))
|
||||
|
||||
assert not setup.setup_component(self.hass, 'disabled_component')
|
||||
assert loader.get_component('disabled_component') is None
|
||||
assert loader.get_component(self.hass, 'disabled_component') is None
|
||||
assert 'disabled_component' not in self.hass.config.components
|
||||
|
||||
self.hass.data.pop(setup.DATA_SETUP)
|
||||
loader.set_component(
|
||||
self.hass,
|
||||
'disabled_component',
|
||||
MockModule('disabled_component', setup=lambda hass, config: False))
|
||||
|
||||
assert not setup.setup_component(self.hass, 'disabled_component')
|
||||
assert loader.get_component('disabled_component') is not None
|
||||
assert loader.get_component(
|
||||
self.hass, 'disabled_component') is not None
|
||||
assert 'disabled_component' not in self.hass.config.components
|
||||
|
||||
self.hass.data.pop(setup.DATA_SETUP)
|
||||
loader.set_component(
|
||||
self.hass,
|
||||
'disabled_component',
|
||||
MockModule('disabled_component', setup=lambda hass, config: True))
|
||||
|
||||
assert setup.setup_component(self.hass, 'disabled_component')
|
||||
assert loader.get_component('disabled_component') is not None
|
||||
assert loader.get_component(
|
||||
self.hass, 'disabled_component') is not None
|
||||
assert 'disabled_component' in self.hass.config.components
|
||||
|
||||
def test_all_work_done_before_start(self):
|
||||
@ -373,14 +390,17 @@ class TestSetup:
|
||||
return True
|
||||
|
||||
loader.set_component(
|
||||
self.hass,
|
||||
'test_component1',
|
||||
MockModule('test_component1', setup=component1_setup))
|
||||
|
||||
loader.set_component(
|
||||
self.hass,
|
||||
'test_component2',
|
||||
MockModule('test_component2', setup=component_track_setup))
|
||||
|
||||
loader.set_component(
|
||||
self.hass,
|
||||
'test_component3',
|
||||
MockModule('test_component3', setup=component_track_setup))
|
||||
|
||||
@ -409,7 +429,8 @@ def test_component_cannot_depend_config(hass):
|
||||
@asyncio.coroutine
|
||||
def test_component_warn_slow_setup(hass):
|
||||
"""Warn we log when a component setup takes a long time."""
|
||||
loader.set_component('test_component1', MockModule('test_component1'))
|
||||
loader.set_component(
|
||||
hass, 'test_component1', MockModule('test_component1'))
|
||||
with mock.patch.object(hass.loop, 'call_later', mock.MagicMock()) \
|
||||
as mock_call:
|
||||
result = yield from setup.async_setup_component(
|
||||
@ -430,7 +451,7 @@ def test_component_warn_slow_setup(hass):
|
||||
def test_platform_no_warn_slow(hass):
|
||||
"""Do not warn for long entity setup time."""
|
||||
loader.set_component(
|
||||
'test_component1',
|
||||
hass, 'test_component1',
|
||||
MockModule('test_component1', platform_schema=PLATFORM_SCHEMA))
|
||||
with mock.patch.object(hass.loop, 'call_later', mock.MagicMock()) \
|
||||
as mock_call:
|
||||
|
@ -2,6 +2,6 @@
|
||||
DOMAIN = 'test_standalone'
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
async def async_setup(hass, config):
|
||||
"""Mock a successful setup."""
|
||||
return True
|
||||
|
Loading…
x
Reference in New Issue
Block a user