def run_esptool(baud_rate): cmd = [ "esptool.py", "--before", "default_reset", "--after", "hard_reset", "--baud", str(baud_rate), "--chip", "esp8266", "--port", port, "write_flash", "0x0", path, ] if os.environ.get("ESPHOME_USE_SUBPROCESS") is None: import esptool # pylint: disable=protected-access return run_external_command(esptool._main, *cmd) return run_external_process(*cmd)
def run_platformio_cli(*args, **kwargs): os.environ["PLATFORMIO_FORCE_COLOR"] = "true" cmd = ['platformio'] + list(args) if os.environ.get('ESPHOME_USE_SUBPROCESS') is None: import platformio.__main__ return run_external_command(platformio.__main__.main, *cmd, **kwargs) return run_external_process(*cmd, **kwargs)
def run_esptool(baud_rate): cmd = ['esptool.py', '--before', 'default_reset', '--after', 'hard_reset', '--baud', str(baud_rate), '--chip', 'esp8266', '--port', port, 'write_flash', '0x0', path] if os.environ.get('ESPHOME_USE_SUBPROCESS') is None: import esptool # pylint: disable=protected-access return run_external_command(esptool._main, *cmd) return run_external_process(*cmd)
def upload_using_esptool(config, port): path = CORE.firmware_bin cmd = ['esptool.py', '--before', 'default_reset', '--after', 'hard_reset', '--chip', 'esp8266', '--port', port, 'write_flash', '0x0', path] if os.environ.get('ESPHOME_USE_SUBPROCESS') is None: import esptool # pylint: disable=protected-access return run_external_command(esptool._main, *cmd) return run_external_process(*cmd)
def run_platformio_cli(*args, **kwargs): os.environ["PLATFORMIO_FORCE_COLOR"] = "true" os.environ["PLATFORMIO_BUILD_DIR"] = os.path.abspath( CORE.relative_pioenvs_path()) os.environ["PLATFORMIO_LIBDEPS_DIR"] = os.path.abspath( CORE.relative_piolibdeps_path()) cmd = ['platformio'] + list(args) if os.environ.get('ESPHOME_USE_SUBPROCESS') is not None: return run_external_process(*cmd, **kwargs) import platformio.__main__ patch_structhash() return run_external_command(platformio.__main__.main, *cmd, **kwargs)
def run_esptool(baud_rate): idedata = platformio_api.get_idedata(config) firmware_offset = "0x10000" if CORE.is_esp32 else "0x0" flash_images = [ platformio_api.FlashImage( path=idedata.firmware_bin_path, offset=firmware_offset, ), *idedata.extra_flash_images, ] mcu = "esp8266" if CORE.is_esp32: from esphome.components.esp32 import get_esp32_variant mcu = get_esp32_variant().lower() cmd = [ "esptool.py", "--before", "default_reset", "--after", "hard_reset", "--baud", str(baud_rate), "--port", port, "--chip", mcu, "write_flash", "-z", "--flash_size", "detect", ] for img in flash_images: cmd += [img.offset, img.path] if os.environ.get("ESPHOME_USE_SUBPROCESS") is None: import esptool # pylint: disable=protected-access return run_external_command(esptool._main, *cmd) return run_external_process(*cmd)
def run_platformio_cli(*args, **kwargs) -> Union[str, int]: os.environ["PLATFORMIO_FORCE_COLOR"] = "true" os.environ["PLATFORMIO_BUILD_DIR"] = os.path.abspath(CORE.relative_pioenvs_path()) os.environ.setdefault( "PLATFORMIO_LIBDEPS_DIR", os.path.abspath(CORE.relative_piolibdeps_path()) ) cmd = ["platformio"] + list(args) if not CORE.verbose: kwargs["filter_lines"] = FILTER_PLATFORMIO_LINES if os.environ.get("ESPHOME_USE_SUBPROCESS") is not None: return run_external_process(*cmd, **kwargs) import platformio.__main__ patch_structhash() return run_external_command(platformio.__main__.main, *cmd, **kwargs)
def run_platformio_cli(*args, **kwargs): os.environ["PLATFORMIO_FORCE_COLOR"] = "true" os.environ["PLATFORMIO_BUILD_DIR"] = os.path.abspath( CORE.relative_pioenvs_path()) os.environ["PLATFORMIO_LIBDEPS_DIR"] = os.path.abspath( CORE.relative_piolibdeps_path()) cmd = ['platformio'] + list(args) if os.environ.get('ESPHOME_USE_SUBPROCESS') is None: import platformio.__main__ try: if IS_PY2: patch_structhash() except Exception: # pylint: disable=broad-except # Ignore when patch fails pass return run_external_command(platformio.__main__.main, *cmd, **kwargs) return run_external_process(*cmd, **kwargs)
def command_update_all(args): import click success = {} files = list_yaml_files(args.configuration[0]) twidth = 60 def print_bar(middle_text): middle_text = f" {middle_text} " width = len(click.unstyle(middle_text)) half_line = "=" * ((twidth - width) // 2) click.echo(f"{half_line}{middle_text}{half_line}") for f in files: print("Updating {}".format(color("cyan", f))) print("-" * twidth) print() rc = run_external_process( "esphome", "--dashboard", f, "run", "--no-logs", "--upload-port", "OTA" ) if rc == 0: print_bar("[{}] {}".format(color("bold_green", "SUCCESS"), f)) success[f] = True else: print_bar("[{}] {}".format(color("bold_red", "ERROR"), f)) success[f] = False print() print() print() print_bar("[{}]".format(color("bold_white", "SUMMARY"))) failed = 0 for f in files: if success[f]: print(" - {}: {}".format(f, color("green", "SUCCESS"))) else: print(" - {}: {}".format(f, color("bold_red", "FAILED"))) failed += 1 return failed
def command_update_all(args): import click success = {} files = list_yaml_files(args.configuration) twidth = 60 def print_bar(middle_text): middle_text = f" {middle_text} " width = len(click.unstyle(middle_text)) half_line = "=" * ((twidth - width) // 2) click.echo(f"{half_line}{middle_text}{half_line}") for f in files: print(f"Updating {color(Fore.CYAN, f)}") print("-" * twidth) print() rc = run_external_process( "esphome", "--dashboard", "run", f, "--no-logs", "--device", "OTA" ) if rc == 0: print_bar(f"[{color(Fore.BOLD_GREEN, 'SUCCESS')}] {f}") success[f] = True else: print_bar(f"[{color(Fore.BOLD_RED, 'ERROR')}] {f}") success[f] = False print() print() print() print_bar(f"[{color(Fore.BOLD_WHITE, 'SUMMARY')}]") failed = 0 for f in files: if success[f]: print(f" - {f}: {color(Fore.GREEN, 'SUCCESS')}") else: print(f" - {f}: {color(Fore.BOLD_RED, 'FAILED')}") failed += 1 return failed
def command_update_all(args): import click success = {} files = list_yaml_files(args.configuration[0]) twidth = 60 def print_bar(middle_text): middle_text = f" {middle_text} " width = len(click.unstyle(middle_text)) half_line = "=" * ((twidth - width) // 2) click.echo(f"{half_line}{middle_text}{half_line}") for f in files: print("Updating {}".format(color('cyan', f))) print('-' * twidth) print() rc = run_external_process('esphome', '--dashboard', f, 'run', '--no-logs', '--upload-port', 'OTA') if rc == 0: print_bar("[{}] {}".format(color('bold_green', 'SUCCESS'), f)) success[f] = True else: print_bar("[{}] {}".format(color('bold_red', 'ERROR'), f)) success[f] = False print() print() print() print_bar('[{}]'.format(color('bold_white', 'SUMMARY'))) failed = 0 for f in files: if success[f]: print(" - {}: {}".format(f, color('green', 'SUCCESS'))) else: print(" - {}: {}".format(f, color('bold_red', 'FAILED'))) failed += 1 return failed
def command_rename(args, config): for c in args.name: if c not in ALLOWED_NAME_CHARS: print( color( Fore.BOLD_RED, f"'{c}' is an invalid character for names. Valid characters are: " f"{ALLOWED_NAME_CHARS} (lowercase, no spaces)", )) return 1 # Load existing yaml file with open(CORE.config_path, mode="r+", encoding="utf-8") as raw_file: raw_contents = raw_file.read() yaml = yaml_util.load_yaml(CORE.config_path) if CONF_ESPHOME not in yaml or CONF_NAME not in yaml[CONF_ESPHOME]: print( color(Fore.BOLD_RED, "Complex YAML files cannot be automatically renamed.")) return 1 old_name = yaml[CONF_ESPHOME][CONF_NAME] match = re.match(r"^\$\{?([a-zA-Z0-9_]+)\}?$", old_name) if match is None: new_raw = re.sub( rf"name:\s+[\"']?{old_name}[\"']?", f'name: "{args.name}"', raw_contents, ) else: old_name = yaml[CONF_SUBSTITUTIONS][match.group(1)] if (len( re.findall( rf"^\s+{match.group(1)}:\s+[\"']?{old_name}[\"']?", raw_contents, flags=re.MULTILINE, )) > 1): print( color(Fore.BOLD_RED, "Too many matches in YAML to safely rename")) return 1 new_raw = re.sub( rf"^(\s+{match.group(1)}):\s+[\"']?{old_name}[\"']?", f'\\1: "{args.name}"', raw_contents, flags=re.MULTILINE, ) new_path = os.path.join(CORE.config_dir, args.name + ".yaml") print( f"Updating {color(Fore.CYAN, CORE.config_path)} to {color(Fore.CYAN, new_path)}" ) print() with open(new_path, mode="w", encoding="utf-8") as new_file: new_file.write(new_raw) rc = run_external_process("esphome", "config", new_path) if rc != 0: print(color(Fore.BOLD_RED, "Rename failed. Reverting changes.")) os.remove(new_path) return 1 cli_args = [ "run", new_path, "--no-logs", "--device", CORE.address, ] if args.dashboard: cli_args.insert(0, "--dashboard") try: rc = run_external_process("esphome", *cli_args) except KeyboardInterrupt: rc = 1 if rc != 0: os.remove(new_path) return 1 os.remove(CORE.config_path) print(color(Fore.BOLD_GREEN, "SUCCESS")) print() return 0