def includes(config): ret = [] for include in config.get(CONF_INCLUDES, []): path = CORE.relative_path(include) res = os.path.relpath(path, CORE.relative_build_path('src')) ret.append(u'#include "{}"'.format(res)) return ret
def to_code(config): from PIL import Image path = CORE.relative_path(config[CONF_FILE]) try: image = Image.open(path) except Exception as e: raise core.EsphomeError(u"Could not load image file {}: {}".format(path, e)) if CONF_RESIZE in config: image.thumbnail(config[CONF_RESIZE]) image = image.convert('1', dither=Image.NONE) width, height = image.size if width > 500 or height > 500: _LOGGER.warning("The image you requested is very big. Please consider using the resize " "parameter") width8 = ((width + 7) // 8) * 8 data = [0 for _ in range(height * width8 // 8)] for y in range(height): for x in range(width): if image.getpixel((x, y)): continue pos = x + y * width8 data[pos // 8] |= 0x80 >> (pos % 8) rhs = safe_exp([HexInt(x) for x in data]) prog_arr = progmem_array(config[CONF_RAW_DATA_ID], rhs) rhs = App.make_image(prog_arr, width, height) Pvariable(config[CONF_ID], rhs)
def preload_core_config(config): 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') if CONF_ESPHOME not in config: raise EsphomeError(u"No esphome section in config") core_conf = config[CONF_ESPHOME] if CONF_PLATFORM not in core_conf: raise EsphomeError("esphome.platform not specified.") if CONF_BOARD not in core_conf: raise EsphomeError("esphome.board not specified.") if CONF_NAME not in core_conf: raise EsphomeError("esphome.name not specified.") try: CORE.esp_platform = validate_platform(core_conf[CONF_PLATFORM]) CORE.board = validate_board(core_conf[CONF_BOARD]) CORE.name = cv.valid_name(core_conf[CONF_NAME]) CORE.build_path = CORE.relative_path( cv.string(core_conf.get(CONF_BUILD_PATH, default_build_path()))) except vol.Invalid as e: raise EsphomeError(text_type(e))
def gather_lib_deps(): lib_deps = set() if CONF_REPOSITORY in CORE.esphome_core_version: repo = CORE.esphome_core_version[CONF_REPOSITORY] ref = next((CORE.esphome_core_version[x] for x in (CONF_COMMIT, CONF_BRANCH, CONF_TAG) if x in CORE.esphome_core_version), None) if CONF_TAG in CORE.esphome_core_version and repo == LIBRARY_URI_REPO: this_version = GITHUB_ARCHIVE_ZIP.format(ref) elif ref is not None: this_version = repo + '#' + ref lib_deps.add(this_version) elif CORE.is_local_esphome_core_copy: src_path = CORE.relative_path(CORE.esphome_core_version[CONF_LOCAL]) # Manually add lib_deps because platformio seems to ignore them inside libs/ library_json_path = os.path.join(src_path, 'library.json') with codecs.open(library_json_path, 'r', encoding='utf-8') as f_handle: library_json_text = f_handle.read() library_json = json.loads(library_json_text) for dep in library_json.get('dependencies', []): if 'version' in dep and VERSION_REGEX.match( dep['version']) is not None: lib_deps.add(dep['name'] + '@' + dep['version']) else: lib_deps.add(dep['version']) else: lib_deps.add(CORE.esphome_core_version) lib_deps |= get_build_flags('LIB_DEPS') lib_deps |= get_build_flags('lib_deps') if CORE.is_esp32: lib_deps |= { 'Preferences', # Preferences helper '[email protected]', # Pin AsyncTCP version } # Manual fix for AsyncTCP if CORE.arduino_version == ARDUINO_VERSION_ESP32_1_0_0: lib_deps.discard('[email protected]') lib_deps.add('[email protected]') lib_deps.add('ESPmDNS') elif CORE.is_esp8266: lib_deps.add('[email protected]') lib_deps.add('ESP8266mDNS') # avoid changing build flags order lib_deps_l = list(lib_deps) lib_deps_l.sort() # Move AsyncTCP to front, see https://github.com/platformio/platformio-core/issues/2115 if '[email protected]' in lib_deps_l: lib_deps_l.insert(0, lib_deps_l.pop(lib_deps_l.index('[email protected]'))) if '[email protected]' in lib_deps_l: lib_deps_l.insert(0, lib_deps_l.pop(lib_deps_l.index('[email protected]'))) return lib_deps_l
def validate_local_esphome_core_version(value): value = cv.directory(value) path = CORE.relative_path(value) library_json = os.path.join(path, 'library.json') if not os.path.exists(library_json): raise vol.Invalid( u"Could not find '{}' file. '{}' does not seem to point to an " u"esphome-core copy.".format(library_json, value)) return value
def file_(value): value = string(value) path = CORE.relative_path(value) if not os.path.exists(path): raise vol.Invalid( u"Could not find file '{}'. Please make sure it exists.".format( path)) if not os.path.isfile(path): raise vol.Invalid(u"Path '{}' is not a file.".format(path)) return value
def directory(value): value = string(value) path = CORE.relative_path(value) if not os.path.exists(path): raise vol.Invalid( u"Could not find directory '{}'. Please make sure it exists.". format(path)) if not os.path.isdir(path): raise vol.Invalid(u"Path '{}' is not a directory.".format(path)) return value
def symlink_esphome_core_version(esphome_core_version): lib_path = CORE.relative_build_path('lib') dst_path = CORE.relative_build_path('lib', 'esphome-core') if CORE.is_local_esphome_core_copy: src_path = CORE.relative_path(esphome_core_version[CONF_LOCAL]) do_write = True if os.path.islink(dst_path): old_path = os.path.join(os.readlink(dst_path), lib_path) if old_path != lib_path: os.unlink(dst_path) else: do_write = False if do_write: mkdir_p(lib_path) symlink(src_path, dst_path) else: # Remove symlink when changing back from local version if os.path.islink(dst_path): os.unlink(dst_path)
def to_code(config): from PIL import ImageFont path = CORE.relative_path(config[CONF_FILE]) try: font = ImageFont.truetype(path, config[CONF_SIZE]) except Exception as e: raise core.EsphomeError(u"Could not load truetype file {}: {}".format( path, e)) ascent, descent = font.getmetrics() glyph_args = {} data = [] for glyph in config[CONF_GLYPHS]: mask = font.getmask(glyph, mode='1') _, (offset_x, offset_y) = font.font.getsize(glyph) width, height = mask.size width8 = ((width + 7) // 8) * 8 glyph_data = [0 for _ in range(height * width8 // 8)] # noqa: F812 for y in range(height): for x in range(width): if not mask.getpixel((x, y)): continue pos = x + y * width8 glyph_data[pos // 8] |= 0x80 >> (pos % 8) glyph_args[glyph] = (len(data), offset_x, offset_y, width, height) data += glyph_data rhs = safe_exp([HexInt(x) for x in data]) prog_arr = progmem_array(config[CONF_RAW_DATA_ID], rhs) glyphs = [] for glyph in config[CONF_GLYPHS]: glyphs.append(Glyph(glyph, prog_arr, *glyph_args[glyph])) rhs = App.make_font(glyphs, ascent, ascent + descent) Pvariable(config[CONF_ID], rhs)
def storage_path(): # type: () -> str return CORE.relative_path('.esphome', '{}.json'.format(CORE.config_filename))
def write_gitignore(): path = CORE.relative_path('.gitignore') if not os.path.isfile(path): with open(path, 'w') as f: f.write(GITIGNORE_CONTENT)