def __init__(self, service_call: ServiceCall) -> None: """Extract ids from service call data.""" entity_ids: str | list | None = service_call.data.get(ATTR_ENTITY_ID) device_ids: str | list | None = service_call.data.get(ATTR_DEVICE_ID) area_ids: str | list | None = service_call.data.get(ATTR_AREA_ID) self.entity_ids = (set(cv.ensure_list(entity_ids)) if _has_match(entity_ids) else set()) self.device_ids = (set(cv.ensure_list(device_ids)) if _has_match(device_ids) else set()) self.area_ids = set( cv.ensure_list(area_ids)) if _has_match(area_ids) else set()
async def async_validate_config(opp, config): """Validate config.""" if DOMAIN not in config: return config config_sections = [] for cfg in cv.ensure_list(config[DOMAIN]): try: cfg = CONFIG_SECTION_SCHEMA(cfg) if CONF_TRIGGER in cfg: cfg[CONF_TRIGGER] = await async_validate_trigger_config( opp, cfg[CONF_TRIGGER]) except vol.Invalid as err: async_log_exception(err, DOMAIN, cfg, opp) continue legacy_warn_printed = False for old_key, new_key, transform in ( ( CONF_SENSORS, SENSOR_DOMAIN, sensor_platform.rewrite_legacy_to_modern_conf, ), ( CONF_BINARY_SENSORS, BINARY_SENSOR_DOMAIN, binary_sensor_platform.rewrite_legacy_to_modern_conf, ), ): if old_key not in cfg: continue if not legacy_warn_printed: legacy_warn_printed = True logging.getLogger(__name__).warning( "The entity definition format under template: differs from the platform " "configuration format. See " "https://www.openpeerpower.io/integrations/template#configuration-for-trigger-based-template-sensors" ) definitions = list(cfg[new_key]) if new_key in cfg else [] definitions.extend(transform(cfg[old_key])) cfg = {**cfg, new_key: definitions} config_sections.append(cfg) # Create a copy of the configuration with all config for current # component removed and add validated config back in. config = config_without_domain(config, DOMAIN) config[DOMAIN] = config_sections return config
def _recursive_merge(conf: dict[str, Any], package: dict[str, Any]) -> bool | str: """Merge package into conf, recursively.""" error: bool | str = False for key, pack_conf in package.items(): if isinstance(pack_conf, dict): if not pack_conf: continue conf[key] = conf.get(key, OrderedDict()) error = _recursive_merge(conf=conf[key], package=pack_conf) elif isinstance(pack_conf, list): conf[key] = cv.remove_falsy( cv.ensure_list(conf.get(key)) + cv.ensure_list(pack_conf)) else: if conf.get(key) is not None: return key conf[key] = pack_conf return error
OFF_STATES = [STATE_IDLE, STATE_OFF, STATE_UNAVAILABLE] ATTRS_SCHEMA = cv.schema_with_slug_keys(cv.string) CMD_SCHEMA = cv.schema_with_slug_keys(cv.SERVICE_SCHEMA) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Required(CONF_NAME): cv.string, vol.Optional(CONF_CHILDREN, default=[]): cv.entity_ids, vol.Optional(CONF_COMMANDS, default={}): CMD_SCHEMA, vol.Optional(CONF_ATTRS, default={}): vol.Or(cv.ensure_list(ATTRS_SCHEMA), ATTRS_SCHEMA), vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA, vol.Optional(CONF_STATE_TEMPLATE): cv.template, }, extra=vol.REMOVE_EXTRA, ) async def async_setup_platform(opp, config, async_add_entities, discovery_info=None): """Set up the universal media players.""" await async_setup_reload_service(opp, "universal", ["media_player"])
from openpeerpower import config_entries from openpeerpower.const import CONF_NAME from openpeerpower.core import OpenPeerPower import openpeerpower.helpers.config_validation as cv from .const import ATTR_TARIFF, DEFAULT_NAME, DEFAULT_TARIFF, DOMAIN, PLATFORMS, TARIFFS UI_CONFIG_SCHEMA = vol.Schema({ vol.Required(CONF_NAME, default=DEFAULT_NAME): str, vol.Required(ATTR_TARIFF, default=DEFAULT_TARIFF): vol.In(TARIFFS), }) CONFIG_SCHEMA = vol.Schema( vol.All(cv.deprecated(DOMAIN), {DOMAIN: cv.ensure_list(UI_CONFIG_SCHEMA)}), extra=vol.ALLOW_EXTRA, ) async def async_setup(opp: OpenPeerPower, config: dict): """ Set up the electricity price sensor from configuration.yaml. ```yaml pvpc_hourly_pricing: - name: PVPC manual ve tariff: electric_car - name: PVPC manual nocturna tariff: discrimination timeout: 3
async def merge_packages_config( opp: OpenPeerPower, config: dict, packages: dict[str, Any], _log_pkg_error: Callable = _log_pkg_error, ) -> dict: """Merge packages into the top-level configuration. Mutate config.""" PACKAGES_CONFIG_SCHEMA(packages) for pack_name, pack_conf in packages.items(): for comp_name, comp_conf in pack_conf.items(): if comp_name == CONF_CORE: continue # If component name is given with a trailing description, remove it # when looking for component domain = comp_name.split(" ")[0] try: integration = await async_get_integration_with_requirements( opp, domain) component = integration.get_component() except INTEGRATION_LOAD_EXCEPTIONS as ex: _log_pkg_error(pack_name, comp_name, config, str(ex)) continue merge_list = hasattr(component, "PLATFORM_SCHEMA") if not merge_list and hasattr(component, "CONFIG_SCHEMA"): merge_list = _identify_config_schema(component) == "list" if merge_list: config[comp_name] = cv.remove_falsy( cv.ensure_list(config.get(comp_name)) + cv.ensure_list(comp_conf)) continue if comp_conf is None: comp_conf = OrderedDict() if not isinstance(comp_conf, dict): _log_pkg_error(pack_name, comp_name, config, "cannot be merged. Expected a dict.") continue if comp_name not in config or config[comp_name] is None: config[comp_name] = OrderedDict() if not isinstance(config[comp_name], dict): _log_pkg_error( pack_name, comp_name, config, "cannot be merged. Dict expected in main config.", ) continue error = _recursive_merge(conf=config[comp_name], package=comp_conf) if error: _log_pkg_error(pack_name, comp_name, config, f"has duplicate key '{error}'") return config
vol.Any(None, cv.string), }) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_BIN): cv.string, vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_PIN): cv.string, vol.Required(CONF_URL): cv.string, vol.Optional(CONF_NAME): cv.string, vol.Optional(CONF_ACCOUNTS, default=[]): cv.ensure_list(SCHEMA_ACCOUNTS), vol.Optional(CONF_HOLDINGS, default=[]): cv.ensure_list(SCHEMA_ACCOUNTS), }) def setup_platform(opp, config, add_entities, discovery_info=None): """Set up the sensors. Login to the bank and get a list of existing accounts. Create a sensor for each account. """ credentials = BankCredentials(config[CONF_BIN], config[CONF_USERNAME], config[CONF_PIN], config[CONF_URL]) fints_name = config.get(CONF_NAME, config[CONF_BIN])
cv.positive_int, vol.Optional(ATTR_MAX_POSITION): cv.positive_int, vol.Optional(ATTR_ROTATION): vol.In(ROTATIONS), vol.Optional(ATTR_SCALE): vol.In(SCALES), vol.Optional(ATTR_TICKS): cv.positive_int, }) DIAL_STATE_SCHEMA = make_entity_service_schema({ vol.Required(ATTR_VALUE): vol.Coerce(int), vol.Optional(ATTR_LABELS): cv.ensure_list(cv.string), }) WINK_COMPONENTS = [ "binary_sensor", "sensor", "light", "switch", "lock", "cover", "climate", "fan", "alarm_control_panel", "scene", "water_heater", ]