From c1853f8b84098e4de7fb35193da66451d68d4e7c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 22 Jun 2025 21:21:29 +0200 Subject: [PATCH] document design decisions --- esphome/core/config.py | 8 +++++++- esphome/helpers.py | 14 +++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/esphome/core/config.py b/esphome/core/config.py index fb658de6b9..23a18e4c2e 100644 --- a/esphome/core/config.py +++ b/esphome/core/config.py @@ -107,7 +107,13 @@ def validate_hostname(config): def validate_ids_and_references(config: ConfigType) -> ConfigType: - """Validate that there are no hash collisions between IDs and that area_id references are valid.""" + """Validate that there are no hash collisions between IDs and that area_id references are valid. + + This validation is critical because we use 32-bit hashes for performance on microcontrollers. + By detecting collisions at compile time, we prevent any runtime issues while maintaining + optimal performance on 32-bit platforms. In practice, with typical deployments having only + a handful of areas and devices, hash collisions are virtually impossible. + """ # Helper to check hash collisions def check_hash_collision( diff --git a/esphome/helpers.py b/esphome/helpers.py index c84d597999..bf0e3b5cf7 100644 --- a/esphome/helpers.py +++ b/esphome/helpers.py @@ -30,7 +30,19 @@ def ensure_unique_string(preferred_string, current_strings): def fnv1a_32bit_hash(string: str) -> int: - """FNV-1a 32-bit hash function.""" + """FNV-1a 32-bit hash function. + + Note: This uses 32-bit hash instead of 64-bit for several reasons: + 1. ESPHome targets 32-bit microcontrollers with limited RAM (often <320KB) + 2. Using 64-bit hashes would double the RAM usage for storing IDs + 3. 64-bit operations are slower on 32-bit processors + + While there's a ~50% collision probability at ~77,000 unique IDs, + ESPHome validates for collisions at compile time, preventing any + runtime issues. In practice, most ESPHome installations only have + a handful of area_ids and device_ids (typically <10 areas and <100 + devices), making collisions virtually impossible. + """ hash_value = 2166136261 for char in string: hash_value ^= ord(char)