diff --git a/esphome/core/__init__.py b/esphome/core/__init__.py index 721cd5787d..5ce968f20d 100644 --- a/esphome/core/__init__.py +++ b/esphome/core/__init__.py @@ -608,6 +608,8 @@ class EsphomeCore: self.current_component: str | None = None # Address cache for DNS and mDNS lookups from command line arguments self.address_cache: AddressCache | None = None + # Cached config hash (computed lazily) + self._config_hash: int | None = None def reset(self): from esphome.pins import PIN_SCHEMA_REGISTRY @@ -636,6 +638,7 @@ class EsphomeCore: self.unique_ids = {} self.current_component = None self.address_cache = None + self._config_hash = None PIN_SCHEMA_REGISTRY.reset() @contextmanager @@ -685,6 +688,20 @@ class EsphomeCore: return None + @property + def config_hash(self) -> int: + """Get the FNV-1a 32-bit hash of the config. + + The hash is computed lazily and cached for performance. + """ + if self._config_hash is None: + from esphome import yaml_util + from esphome.helpers import fnv1a_32bit_hash + + config_str = yaml_util.dump(self.config, show_secrets=True) + self._config_hash = fnv1a_32bit_hash(config_str) + return self._config_hash + @property def config_dir(self) -> Path: if self.config_path.is_dir(): diff --git a/esphome/writer.py b/esphome/writer.py index 11e10d2fd4..629329cbb1 100644 --- a/esphome/writer.py +++ b/esphome/writer.py @@ -21,7 +21,6 @@ from esphome.const import ( from esphome.core import CORE, EsphomeError from esphome.helpers import ( copy_file_if_changed, - fnv1a_32bit_hash, get_str_env, is_ha_addon, read_file, @@ -300,11 +299,7 @@ def get_build_info() -> tuple[int, int, str]: Returns: Tuple of (config_hash, build_time, build_time_str) """ - from esphome import yaml_util - - # Use the same clean YAML representation as 'esphome config' command - config_str = yaml_util.dump(CORE.config, show_secrets=True) - config_hash = fnv1a_32bit_hash(config_str) + config_hash = CORE.config_hash # Check if config_hash and version are unchanged - keep existing build_time build_info_path = CORE.relative_build_path("build_info.json")