示例#1
0
def do_substitution_pass(config, command_line_substitutions):
    if CONF_SUBSTITUTIONS not in config and not command_line_substitutions:
        return

    substitutions = config[CONF_SUBSTITUTIONS]
    if substitutions is None:
        substitutions = command_line_substitutions
    elif command_line_substitutions:
        substitutions = {**substitutions, **command_line_substitutions}
    with cv.prepend_path("substitutions"):
        if not isinstance(substitutions, dict):
            raise cv.Invalid(
                "Substitutions must be a key to value mapping, got {}"
                "".format(type(substitutions)))

        replace_keys = []
        for key, value in substitutions.items():
            with cv.prepend_path(key):
                sub = validate_substitution_key(key)
                if sub != key:
                    replace_keys.append((key, sub))
                substitutions[key] = cv.string_strict(value)
        for old, new in replace_keys:
            substitutions[new] = substitutions[old]
            del substitutions[old]

    config[CONF_SUBSTITUTIONS] = substitutions
    # Move substitutions to the first place to replace substitutions in them correctly
    config.move_to_end(CONF_SUBSTITUTIONS, False)
    _substitute_item(substitutions, config, [])
示例#2
0
def do_external_components_pass(config: dict) -> None:
    conf = config.get(DOMAIN)
    if conf is None:
        return
    with cv.prepend_path(DOMAIN):
        conf = CONFIG_SCHEMA(conf)
        for i, c in enumerate(conf):
            with cv.prepend_path(i):
                _process_single_config(c)
示例#3
0
def _process_single_config(config: dict):
    conf = config[CONF_SOURCE]
    if conf[CONF_TYPE] == TYPE_GIT:
        with cv.prepend_path([CONF_SOURCE]):
            components_dir = _process_git_config(config[CONF_SOURCE],
                                                 config[CONF_REFRESH])
    elif conf[CONF_TYPE] == TYPE_LOCAL:
        components_dir = Path(CORE.relative_config_path(conf[CONF_PATH]))
    else:
        raise NotImplementedError()

    if config[CONF_COMPONENTS] == "all":
        num_components = len(list(components_dir.glob("*/__init__.py")))
        if num_components > 100:
            # Prevent accidentally including all components from an esphome fork/branch
            # In this case force the user to manually specify which components they want to include
            raise cv.Invalid(
                "This source is an ESPHome fork or branch. Please manually specify the components you want to import using the 'components' key",
                [CONF_COMPONENTS],
            )
        allowed_components = None
    else:
        for i, name in enumerate(config[CONF_COMPONENTS]):
            expected = components_dir / name / "__init__.py"
            if not expected.is_file():
                raise cv.Invalid(
                    f"Could not find __init__.py file for component {name}. Please check the component is defined by this source (search path: {expected})",
                    [CONF_COMPONENTS, i],
                )
        allowed_components = config[CONF_COMPONENTS]

    loader.install_meta_finder(components_dir,
                               allowed_components=allowed_components)
def preload_core_config(config):
    core_key = 'esphome'
    if 'esphomeyaml' in config:
        _LOGGER.warning("The esphomeyaml section has been renamed to esphome in 1.11.0. "
                        "Please replace 'esphomeyaml:' in your configuration with 'esphome:'.")
        config[CONF_ESPHOME] = config.pop('esphomeyaml')
        core_key = 'esphomeyaml'
    if CONF_ESPHOME not in config:
        raise cv.RequiredFieldInvalid("required key not provided", CONF_ESPHOME)
    with cv.prepend_path(core_key):
        out = PRELOAD_CONFIG_SCHEMA(config[CONF_ESPHOME])
    CORE.name = out[CONF_NAME]
    CORE.esp_platform = out[CONF_PLATFORM]
    with cv.prepend_path(core_key):
        out2 = PRELOAD_CONFIG_SCHEMA2(config[CONF_ESPHOME])
    CORE.board = out2[CONF_BOARD]
    CORE.build_path = CORE.relative_config_path(out2[CONF_BUILD_PATH])
示例#5
0
def do_packages_pass(config: dict):
    if CONF_PACKAGES not in config:
        return config
    packages = config[CONF_PACKAGES]
    with cv.prepend_path(CONF_PACKAGES):
        if not isinstance(packages, dict):
            raise cv.Invalid(
                "Packages must be a key to value mapping, got {} instead"
                "".format(type(packages)))

        for package_name, package_config in packages.items():
            with cv.prepend_path(package_name):
                recursive_package = package_config
                if isinstance(package_config, dict):
                    recursive_package = do_packages_pass(package_config)
                config = _merge_package(recursive_package, config)

        del config[CONF_PACKAGES]
    return config
示例#6
0
def do_packages_pass(config: dict):
    if CONF_PACKAGES not in config:
        return config
    packages = config[CONF_PACKAGES]
    with cv.prepend_path(CONF_PACKAGES):
        packages = CONFIG_SCHEMA(packages)
        if not isinstance(packages, dict):
            raise cv.Invalid(
                f"Packages must be a key to value mapping, got {type(packages)} instead"
            )

        for package_name, package_config in packages.items():
            with cv.prepend_path(package_name):
                recursive_package = package_config
                if CONF_URL in package_config:
                    package_config = _process_base_package(package_config)
                if isinstance(package_config, dict):
                    recursive_package = do_packages_pass(package_config)
                config = _merge_package(recursive_package, config)

        del config[CONF_PACKAGES]
    return config
示例#7
0
def do_substitution_pass(config):
    if CONF_SUBSTITUTIONS not in config:
        return

    substitutions = config[CONF_SUBSTITUTIONS]
    with cv.prepend_path('substitutions'):
        if not isinstance(substitutions, dict):
            raise cv.Invalid(
                u"Substitutions must be a key to value mapping, got {}"
                u"".format(type(substitutions)))

        replace_keys = []
        for key, value in substitutions.items():
            with cv.prepend_path(key):
                sub = validate_substitution_key(key)
                if sub != key:
                    replace_keys.append((key, sub))
                substitutions[key] = cv.string_strict(value)
        for old, new in replace_keys:
            substitutions[new] = substitutions[old]
            del substitutions[old]

    config[CONF_SUBSTITUTIONS] = substitutions
    _substitute_item(substitutions, config, [])
示例#8
0
def validate_git_package(config: dict):
    new_config = config
    for key, conf in config.items():
        if CONF_URL in conf:
            try:
                conf = BASE_SCHEMA(conf)
                if CONF_FILE in conf:
                    new_config[key][CONF_FILES] = [conf[CONF_FILE]]
                    del new_config[key][CONF_FILE]
            except cv.MultipleInvalid as e:
                with cv.prepend_path([key]):
                    raise e
            except cv.Invalid as e:
                raise cv.Invalid(
                    "Extra keys not allowed in git based package",
                    path=[key] + e.path,
                ) from e
    return new_config
示例#9
0
 def validator(value):
     fconf = full_config.get()
     path = fconf.get_path_for_id(value)[:-1]
     declaration_config = fconf.get_config_for_path(path)
     with cv.prepend_path([cv.ROOT_CONFIG_PATH] + path):
         return schema(declaration_config)
示例#10
0
def preload_core_config(config, result):
    with cv.prepend_path(CONF_ESPHOME):
        conf = PRELOAD_CONFIG_SCHEMA(config[CONF_ESPHOME])

    CORE.name = conf[CONF_NAME]
    CORE.data[KEY_CORE] = {}

    if CONF_BUILD_PATH not in conf:
        conf[CONF_BUILD_PATH] = f".esphome/build/{CORE.name}"
    CORE.build_path = CORE.relative_config_path(conf[CONF_BUILD_PATH])

    has_oldstyle = CONF_PLATFORM in conf
    newstyle_found = [key for key in TARGET_PLATFORMS if key in config]
    oldstyle_opts = [
        CONF_ESP8266_RESTORE_FROM_FLASH,
        CONF_BOARD_FLASH_MODE,
        CONF_ARDUINO_VERSION,
        CONF_BOARD,
    ]

    if not has_oldstyle and not newstyle_found:
        raise cv.Invalid("Platform missing for core options!", [CONF_ESPHOME])
    if has_oldstyle and newstyle_found:
        raise cv.Invalid(
            f"Please remove the `platform` key from the [esphome] block. You're already using the new style with the [{conf[CONF_PLATFORM]}] block",
            [CONF_ESPHOME, CONF_PLATFORM],
        )
    if len(newstyle_found) > 1:
        raise cv.Invalid(
            f"Found multiple target platform blocks: {', '.join(newstyle_found)}. Only one is allowed.",
            [newstyle_found[0]],
        )
    if newstyle_found:
        # Convert to newstyle
        for key in oldstyle_opts:
            if key in conf:
                raise cv.Invalid(
                    f"Please move {key} to the [{newstyle_found[0]}] block.",
                    [CONF_ESPHOME, key],
                )

    if has_oldstyle:
        plat = conf.pop(CONF_PLATFORM)
        plat_conf = {}
        if CONF_ESP8266_RESTORE_FROM_FLASH in conf:
            plat_conf["restore_from_flash"] = conf.pop(
                CONF_ESP8266_RESTORE_FROM_FLASH)
        if CONF_BOARD_FLASH_MODE in conf:
            plat_conf[CONF_BOARD_FLASH_MODE] = conf.pop(CONF_BOARD_FLASH_MODE)
        if CONF_ARDUINO_VERSION in conf:
            plat_conf[CONF_FRAMEWORK] = {}
            if plat != PLATFORM_ESP8266:
                plat_conf[CONF_FRAMEWORK][CONF_TYPE] = "arduino"

            try:
                if conf[CONF_ARDUINO_VERSION] not in ("recommended", "latest",
                                                      "dev"):
                    cv.Version.parse(conf[CONF_ARDUINO_VERSION])
                plat_conf[CONF_FRAMEWORK][CONF_VERSION] = conf.pop(
                    CONF_ARDUINO_VERSION)
            except ValueError:
                plat_conf[CONF_FRAMEWORK][CONF_SOURCE] = conf.pop(
                    CONF_ARDUINO_VERSION)
        if CONF_BOARD in conf:
            plat_conf[CONF_BOARD] = conf.pop(CONF_BOARD)
        # Insert generated target platform config to main config
        config[plat] = plat_conf
    config[CONF_ESPHOME] = conf