mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Allow platforms to specify PLATFORM_SCHEMA
This commit is contained in:
parent
4fba89b789
commit
f6d584af09
@ -108,14 +108,33 @@ def _setup_component(hass, domain, config):
|
|||||||
|
|
||||||
elif hasattr(component, 'PLATFORM_SCHEMA'):
|
elif hasattr(component, 'PLATFORM_SCHEMA'):
|
||||||
platforms = []
|
platforms = []
|
||||||
for _, platform in config_per_platform(config, domain):
|
for p_name, p_config in config_per_platform(config, domain):
|
||||||
|
# Validate component specific platform schema
|
||||||
try:
|
try:
|
||||||
platforms.append(component.PLATFORM_SCHEMA(platform))
|
p_validated = component.PLATFORM_SCHEMA(p_config)
|
||||||
except vol.MultipleInvalid as ex:
|
except vol.MultipleInvalid as ex:
|
||||||
_LOGGER.error('Invalid platform config for [%s]: %s. %s',
|
_LOGGER.error('Invalid platform config for [%s]: %s. %s',
|
||||||
domain, ex, platform)
|
domain, ex, p_config)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
platform = prepare_setup_platform(hass, config, domain,
|
||||||
|
p_name)
|
||||||
|
|
||||||
|
if platform is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Validate platform specific schema
|
||||||
|
if hasattr(platform, 'PLATFORM_SCHEMA'):
|
||||||
|
try:
|
||||||
|
p_validated = platform.PLATFORM_SCHEMA(p_validated)
|
||||||
|
except vol.MultipleInvalid as ex:
|
||||||
|
_LOGGER.error(
|
||||||
|
'Invalid platform config for [%s.%s]: %s. %s',
|
||||||
|
domain, p_name, ex, p_config)
|
||||||
|
return False
|
||||||
|
|
||||||
|
platforms.append(p_validated)
|
||||||
|
|
||||||
# Create a copy of the configuration with all config for current
|
# Create a copy of the configuration with all config for current
|
||||||
# component removed and add validated config back in.
|
# component removed and add validated config back in.
|
||||||
filter_keys = extract_domain_configs(config, domain)
|
filter_keys = extract_domain_configs(config, domain)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_PLATFORM, TEMP_CELCIUS, TEMP_FAHRENHEIT)
|
CONF_PLATFORM, CONF_SCAN_INTERVAL, TEMP_CELCIUS, TEMP_FAHRENHEIT)
|
||||||
from homeassistant.helpers.entity import valid_entity_id
|
from homeassistant.helpers.entity import valid_entity_id
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
@ -10,6 +10,7 @@ import homeassistant.util.dt as dt_util
|
|||||||
|
|
||||||
PLATFORM_SCHEMA = vol.Schema({
|
PLATFORM_SCHEMA = vol.Schema({
|
||||||
vol.Required(CONF_PLATFORM): str,
|
vol.Required(CONF_PLATFORM): str,
|
||||||
|
CONF_SCAN_INTERVAL: vol.All(vol.Coerce(int), vol.Range(min=1)),
|
||||||
}, extra=vol.ALLOW_EXTRA)
|
}, extra=vol.ALLOW_EXTRA)
|
||||||
|
|
||||||
byte = vol.All(vol.Coerce(int), vol.Range(min=0, max=255))
|
byte = vol.All(vol.Coerce(int), vol.Range(min=0, max=255))
|
||||||
|
@ -79,24 +79,22 @@ class EntityComponent(object):
|
|||||||
platform = prepare_setup_platform(
|
platform = prepare_setup_platform(
|
||||||
self.hass, self.config, self.domain, platform_type)
|
self.hass, self.config, self.domain, platform_type)
|
||||||
|
|
||||||
if platform is None:
|
# Config > Platform > Component
|
||||||
return
|
scan_interval = platform_config.get(
|
||||||
|
CONF_SCAN_INTERVAL,
|
||||||
|
getattr(platform, 'SCAN_INTERVAL', self.scan_interval))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Config > Platform > Component
|
|
||||||
scan_interval = platform_config.get(
|
|
||||||
CONF_SCAN_INTERVAL,
|
|
||||||
getattr(platform, 'SCAN_INTERVAL', self.scan_interval))
|
|
||||||
platform.setup_platform(
|
platform.setup_platform(
|
||||||
self.hass, platform_config,
|
self.hass, platform_config,
|
||||||
EntityPlatform(self, scan_interval).add_entities,
|
EntityPlatform(self, scan_interval).add_entities,
|
||||||
discovery_info)
|
discovery_info)
|
||||||
platform_name = '{}.{}'.format(self.domain, platform_type)
|
|
||||||
self.hass.config.components.append(platform_name)
|
self.hass.config.components.append(
|
||||||
|
'{}.{}'.format(self.domain, platform_type))
|
||||||
except Exception: # pylint: disable=broad-except
|
except Exception: # pylint: disable=broad-except
|
||||||
self.logger.exception(
|
self.logger.exception(
|
||||||
'Error while setting up platform %s', platform_type)
|
'Error while setting up platform %s', platform_type)
|
||||||
return
|
|
||||||
|
|
||||||
def add_entity(self, entity):
|
def add_entity(self, entity):
|
||||||
"""Add entity to component."""
|
"""Add entity to component."""
|
||||||
|
@ -143,12 +143,12 @@ class MockHTTP(object):
|
|||||||
class MockModule(object):
|
class MockModule(object):
|
||||||
"""Representation of a fake module."""
|
"""Representation of a fake module."""
|
||||||
|
|
||||||
def __init__(self, domain=None, dependencies=[], setup=None,
|
def __init__(self, domain=None, dependencies=None, setup=None,
|
||||||
requirements=[], config_schema=None, platform_schema=None):
|
requirements=None, config_schema=None, platform_schema=None):
|
||||||
"""Initialize the mock module."""
|
"""Initialize the mock module."""
|
||||||
self.DOMAIN = domain
|
self.DOMAIN = domain
|
||||||
self.DEPENDENCIES = dependencies
|
self.DEPENDENCIES = dependencies or []
|
||||||
self.REQUIREMENTS = requirements
|
self.REQUIREMENTS = requirements or []
|
||||||
|
|
||||||
if config_schema is not None:
|
if config_schema is not None:
|
||||||
self.CONFIG_SCHEMA = config_schema
|
self.CONFIG_SCHEMA = config_schema
|
||||||
@ -166,11 +166,15 @@ class MockModule(object):
|
|||||||
class MockPlatform(object):
|
class MockPlatform(object):
|
||||||
"""Provide a fake platform."""
|
"""Provide a fake platform."""
|
||||||
|
|
||||||
def __init__(self, setup_platform=None, dependencies=[]):
|
def __init__(self, setup_platform=None, dependencies=None,
|
||||||
|
platform_schema=None):
|
||||||
"""Initialize the platform."""
|
"""Initialize the platform."""
|
||||||
self.DEPENDENCIES = dependencies
|
self.DEPENDENCIES = dependencies or []
|
||||||
self._setup_platform = setup_platform
|
self._setup_platform = setup_platform
|
||||||
|
|
||||||
|
if platform_schema is not None:
|
||||||
|
self.PLATFORM_SCHEMA = platform_schema
|
||||||
|
|
||||||
def setup_platform(self, hass, config, add_devices, discovery_info=None):
|
def setup_platform(self, hass, config, add_devices, discovery_info=None):
|
||||||
"""Setup the platform."""
|
"""Setup the platform."""
|
||||||
if self._setup_platform is not None:
|
if self._setup_platform is not None:
|
||||||
|
@ -165,11 +165,14 @@ class TestBootstrap:
|
|||||||
"""Test validating platform configuration."""
|
"""Test validating platform configuration."""
|
||||||
platform_schema = PLATFORM_SCHEMA.extend({
|
platform_schema = PLATFORM_SCHEMA.extend({
|
||||||
'hello': str,
|
'hello': str,
|
||||||
}, required=True)
|
})
|
||||||
loader.set_component(
|
loader.set_component(
|
||||||
'platform_conf',
|
'platform_conf',
|
||||||
MockModule('platform_conf', platform_schema=platform_schema))
|
MockModule('platform_conf', platform_schema=platform_schema))
|
||||||
|
|
||||||
|
loader.set_component(
|
||||||
|
'platform_conf.whatever', MockPlatform('whatever'))
|
||||||
|
|
||||||
assert not bootstrap._setup_component(self.hass, 'platform_conf', {
|
assert not bootstrap._setup_component(self.hass, 'platform_conf', {
|
||||||
'platform_conf': None
|
'platform_conf': None
|
||||||
})
|
})
|
||||||
@ -196,6 +199,13 @@ class TestBootstrap:
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
assert not bootstrap._setup_component(self.hass, 'platform_conf', {
|
||||||
|
'platform_conf': {
|
||||||
|
'platform': 'not_existing',
|
||||||
|
'hello': 'world',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
assert bootstrap._setup_component(self.hass, 'platform_conf', {
|
assert bootstrap._setup_component(self.hass, 'platform_conf', {
|
||||||
'platform_conf': {
|
'platform_conf': {
|
||||||
'platform': 'whatever',
|
'platform': 'whatever',
|
||||||
@ -318,7 +328,7 @@ class TestBootstrap:
|
|||||||
loader.set_component('switch.platform_a', MockPlatform('comp_b',
|
loader.set_component('switch.platform_a', MockPlatform('comp_b',
|
||||||
['comp_a']))
|
['comp_a']))
|
||||||
|
|
||||||
assert bootstrap.setup_component(self.hass, 'switch', {
|
bootstrap.setup_component(self.hass, 'switch', {
|
||||||
'comp_a': {
|
'comp_a': {
|
||||||
'valid': True
|
'valid': True
|
||||||
},
|
},
|
||||||
@ -327,3 +337,36 @@ class TestBootstrap:
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
assert 'comp_a' in self.hass.config.components
|
assert 'comp_a' in self.hass.config.components
|
||||||
|
|
||||||
|
def test_platform_specific_config_validation(self):
|
||||||
|
"""Test platform that specifies config."""
|
||||||
|
|
||||||
|
platform_schema = PLATFORM_SCHEMA.extend({
|
||||||
|
'valid': True,
|
||||||
|
}, extra=vol.PREVENT_EXTRA)
|
||||||
|
|
||||||
|
loader.set_component(
|
||||||
|
'switch.platform_a',
|
||||||
|
MockPlatform('comp_b', platform_schema=platform_schema))
|
||||||
|
|
||||||
|
assert not bootstrap.setup_component(self.hass, 'switch', {
|
||||||
|
'switch': {
|
||||||
|
'platform': 'platform_a',
|
||||||
|
'invalid': True
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
assert not bootstrap.setup_component(self.hass, 'switch', {
|
||||||
|
'switch': {
|
||||||
|
'platform': 'platform_a',
|
||||||
|
'valid': True,
|
||||||
|
'invalid_extra': True,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
assert bootstrap.setup_component(self.hass, 'switch', {
|
||||||
|
'switch': {
|
||||||
|
'platform': 'platform_a',
|
||||||
|
'valid': True
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user