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