예제 #1
0
파일: writer.py 프로젝트: rnauber/esphome
def copy_src_tree():
    import filecmp
    import shutil

    source_files = {}
    for _, component, _ in iter_components(CORE.config):
        source_files.update(component.source_files)

    # Convert to list and sort
    source_files_l = [it for it in source_files.items()]
    source_files_l.sort()

    # Build #include list for esphome.h
    include_l = []
    for target, path in source_files_l:
        if os.path.splitext(path)[1] in HEADER_FILE_EXTENSIONS:
            include_l.append(u'#include "{}"'.format(target))
    include_l.append(u'')
    include_s = u'\n'.join(include_l)

    source_files_copy = source_files.copy()
    source_files_copy.pop(DEFINES_H_TARGET)

    for path in walk_files(CORE.relative_src_path('esphome')):
        if os.path.splitext(path)[1] not in SOURCE_FILE_EXTENSIONS:
            # Not a source file, ignore
            continue
        # Transform path to target path name
        target = os.path.relpath(path, CORE.relative_src_path()).replace(
            os.path.sep, '/')
        if target == DEFINES_H_TARGET:
            # Ignore defines.h, will be dealt with later
            continue
        if target not in source_files_copy:
            # Source file removed, delete target
            os.remove(path)
        else:
            src_path = source_files_copy.pop(target)
            if not filecmp.cmp(path, src_path):
                # Files are not same, copy
                shutil.copy(src_path, path)

    # Now copy new files
    for target, src_path in source_files_copy.items():
        dst_path = CORE.relative_src_path(*target.split('/'))
        mkdir_p(os.path.dirname(dst_path))
        shutil.copy(src_path, dst_path)

    # Finally copy defines
    write_file_if_changed(
        generate_defines_h(),
        CORE.relative_src_path('esphome', 'core', 'defines.h'))
    write_file_if_changed(ESPHOME_README_TXT,
                          CORE.relative_src_path('esphome', 'README.txt'))
    write_file_if_changed(ESPHOME_H_FORMAT.format(include_s),
                          CORE.relative_src_path('esphome.h'))
    write_file_if_changed(
        VERSION_H_FORMAT.format(__version__),
        CORE.relative_src_path('esphome'
                               'core', 'version.h'))
예제 #2
0
def write_cpp(config):
    _LOGGER.info("Generating C++ source...")

    CORE.add_job(core_config.to_code, config[CONF_ESPHOME], domain='esphome')
    for domain in PRE_INITIALIZE:
        if domain == CONF_ESPHOME or domain not in config:
            continue
        CORE.add_job(get_component(domain).to_code,
                     config[domain],
                     domain=domain)

    for domain, component, conf in iter_components(config):
        if domain in PRE_INITIALIZE or not hasattr(component, 'to_code'):
            continue
        CORE.add_job(component.to_code, conf, domain=domain)

    CORE.flush_tasks()
    add(RawStatement(''))
    add(RawStatement(''))
    all_code = []
    for exp in CORE.expressions:
        if not config[CONF_ESPHOME][CONF_USE_CUSTOM_CODE]:
            if isinstance(exp, Expression) and not exp.required:
                continue
        all_code.append(text_type(statement(exp)))

    writer.write_platformio_project()

    code_s = indent('\n'.join(line.rstrip() for line in all_code))
    writer.write_cpp(code_s)
    return 0
예제 #3
0
def copy_src_tree():
    source_files: Dict[Path, loader.SourceFile] = CORE.extra_source_files
    for _, component, _ in iter_components(CORE.config):
        source_files.update(component.source_files)

    # Convert to list and sort
    source_files_l = list(source_files.items())
    source_files_l.sort()

    # Build #include list for esphome.h
    include_l = []
    for target, _ in source_files_l:
        if target.suffix in HEADER_FILE_EXTENSIONS:
            include_l.append(f'#include "{target}"')
    include_l.append("")
    include_s = "\n".join(include_l)

    source_files_copy = source_files.copy()
    ignore_targets = [Path(x) for x in (DEFINES_H_TARGET, VERSION_H_TARGET)]
    for t in ignore_targets:
        source_files_copy.pop(t)

    for fname in walk_files(CORE.relative_src_path("esphome")):
        p = Path(fname)
        if p.suffix not in SOURCE_FILE_EXTENSIONS:
            # Not a source file, ignore
            continue
        # Transform path to target path name
        target = p.relative_to(CORE.relative_src_path())
        if target in ignore_targets:
            # Ignore defines.h, will be dealt with later
            continue
        if target not in source_files_copy:
            # Source file removed, delete target
            p.unlink()
        else:
            src_file = source_files_copy.pop(target)
            with src_file.path() as src_path:
                copy_file_if_changed(src_path, p)

    # Now copy new files
    for target, src_file in source_files_copy.items():
        dst_path = CORE.relative_src_path(*target.parts)
        with src_file.path() as src_path:
            copy_file_if_changed(src_path, dst_path)

    # Finally copy defines
    write_file_if_changed(
        CORE.relative_src_path("esphome", "core", "defines.h"),
        generate_defines_h())
    write_file_if_changed(CORE.relative_src_path("esphome", "README.txt"),
                          ESPHOME_README_TXT)
    write_file_if_changed(CORE.relative_src_path("esphome.h"),
                          ESPHOME_H_FORMAT.format(include_s))
    write_file_if_changed(
        CORE.relative_src_path("esphome", "core", "version.h"),
        VERSION_H_FORMAT.format(__version__),
    )
예제 #4
0
def generate_cpp_contents(config):
    _LOGGER.info("Generating C++ source...")

    for name, component, conf in iter_components(CORE.config):
        if component.to_code is not None:
            coro = wrap_to_code(name, component)
            CORE.add_job(coro, conf)

    CORE.flush_tasks()
예제 #5
0
def copy_src_tree():
    source_files = {}
    for _, component, _ in iter_components(CORE.config):
        source_files.update(component.source_files)

    # Convert to list and sort
    source_files_l = list(source_files.items())
    source_files_l.sort()

    # Build #include list for esphome.h
    include_l = []
    for target, path in source_files_l:
        if os.path.splitext(path)[1] in HEADER_FILE_EXTENSIONS:
            include_l.append(f'#include "{target}"')
    include_l.append("")
    include_s = "\n".join(include_l)

    source_files_copy = source_files.copy()
    source_files_copy.pop(DEFINES_H_TARGET)

    for path in walk_files(CORE.relative_src_path("esphome")):
        if os.path.splitext(path)[1] not in SOURCE_FILE_EXTENSIONS:
            # Not a source file, ignore
            continue
        # Transform path to target path name
        target = os.path.relpath(path, CORE.relative_src_path()).replace(
            os.path.sep, "/"
        )
        if target in (DEFINES_H_TARGET, VERSION_H_TARGET):
            # Ignore defines.h, will be dealt with later
            continue
        if target not in source_files_copy:
            # Source file removed, delete target
            os.remove(path)
        else:
            src_path = source_files_copy.pop(target)
            copy_file_if_changed(src_path, path)

    # Now copy new files
    for target, src_path in source_files_copy.items():
        dst_path = CORE.relative_src_path(*target.split("/"))
        copy_file_if_changed(src_path, dst_path)

    # Finally copy defines
    write_file_if_changed(
        CORE.relative_src_path("esphome", "core", "defines.h"), generate_defines_h()
    )
    write_file_if_changed(
        CORE.relative_src_path("esphome", "README.txt"), ESPHOME_README_TXT
    )
    write_file_if_changed(
        CORE.relative_src_path("esphome.h"), ESPHOME_H_FORMAT.format(include_s)
    )
    write_file_if_changed(
        CORE.relative_src_path("esphome", "core", "version.h"),
        VERSION_H_FORMAT.format(__version__),
    )
예제 #6
0
def get_build_flags(key):
    build_flags = set()
    for _, component, conf in iter_components(CORE.config):
        if not hasattr(component, key):
            continue
        flags = getattr(component, key)
        if callable(flags):
            flags = flags(conf)
        if flags is None:
            continue
        if isinstance(flags, string_types):
            flags = [flags]
        build_flags |= set(flags)
    return build_flags
예제 #7
0
def write_cpp(config):
    _LOGGER.info("Generating C++ source...")

    for name, component, conf in iter_components(CORE.config):
        if component.to_code is not None:
            coro = wrap_to_code(name, component)
            CORE.add_job(coro, conf)

    CORE.flush_tasks()

    writer.write_platformio_project()

    code_s = indent(CORE.cpp_main_section)
    writer.write_cpp(code_s)
    return 0
예제 #8
0
def get_include_text():
    include_text = '#include "esphome.h"\nusing namespace esphome;\n'
    for _, component, conf in iter_components(CORE.config):
        if not hasattr(component, "includes"):
            continue
        includes = component.includes
        if callable(includes):
            includes = includes(conf)
        if includes is None:
            continue
        if isinstance(includes, list):
            includes = "\n".join(includes)
        if not includes:
            continue
        include_text += includes + "\n"
    return include_text
예제 #9
0
def command_hass_config(args, config):
    from esphome.components import mqtt as mqtt_component

    _LOGGER.info(
        "This is what you should put in your Home Assistant YAML configuration."
    )
    _LOGGER.info(
        "Please note this is only necessary if you're not using MQTT discovery."
    )
    data = mqtt_component.GenerateHassConfigData(config)
    hass_config = OrderedDict()
    for domain, component, conf in iter_components(config):
        if not hasattr(component, 'to_hass_config'):
            continue
        func = getattr(component, 'to_hass_config')
        ret = func(data, conf)
        if not isinstance(ret, (list, tuple)):
            ret = [ret]
        ret = [x for x in ret if x is not None]
        domain_conf = hass_config.setdefault(domain.split('.')[0], [])
        domain_conf += ret

    safe_print(yaml_util.dump(hass_config))
    return 0
예제 #10
0
def get_flags(key):
    flags = set()
    for _, component, conf in iter_components(CORE.config):
        flags |= getattr(component, key)(conf)
    return flags