diff --git a/esphome/core/entity_base.cpp b/esphome/core/entity_base.cpp index ba5529a29e..a6c702448e 100644 --- a/esphome/core/entity_base.cpp +++ b/esphome/core/entity_base.cpp @@ -50,25 +50,22 @@ __attribute__((weak)) const char *entity_device_class_lookup(uint16_t) { return __attribute__((weak)) const char *entity_uom_lookup(uint16_t) { return ""; } __attribute__((weak)) const char *entity_icon_lookup(uint16_t) { return ""; } -// Entity device class (from packed index) +// Entity device class (from index) StringRef EntityBase::get_device_class_ref() const { - return StringRef( - entity_device_class_lookup((this->entity_string_packed_ >> ENTITY_STR_DC_SHIFT) & ENTITY_STR_DC_MASK)); + return StringRef(entity_device_class_lookup(this->device_class_idx_)); } std::string EntityBase::get_device_class() const { return std::string(this->get_device_class_ref().c_str()); } -// Entity unit of measurement (from packed index) -StringRef EntityBase::get_unit_of_measurement_ref() const { - return StringRef(entity_uom_lookup((this->entity_string_packed_ >> ENTITY_STR_UOM_SHIFT) & ENTITY_STR_UOM_MASK)); -} +// Entity unit of measurement (from index) +StringRef EntityBase::get_unit_of_measurement_ref() const { return StringRef(entity_uom_lookup(this->uom_idx_)); } std::string EntityBase::get_unit_of_measurement() const { return std::string(this->get_unit_of_measurement_ref().c_str()); } -// Entity icon (from packed index) +// Entity icon (from index) StringRef EntityBase::get_icon_ref() const { #ifdef USE_ENTITY_ICON - return StringRef(entity_icon_lookup((this->entity_string_packed_ >> ENTITY_STR_ICON_SHIFT) & ENTITY_STR_ICON_MASK)); + return StringRef(entity_icon_lookup(this->icon_idx_)); #else return StringRef(entity_icon_lookup(0)); #endif diff --git a/esphome/core/entity_base.h b/esphome/core/entity_base.h index ccb07a4ed0..e381db2f1b 100644 --- a/esphome/core/entity_base.h +++ b/esphome/core/entity_base.h @@ -14,21 +14,12 @@ namespace esphome { -// Extern lookup functions for packed entity string tables. +// Extern lookup functions for entity string tables. // Generated code provides strong definitions; weak defaults return "". extern const char *entity_device_class_lookup(uint16_t index); extern const char *entity_uom_lookup(uint16_t index); extern const char *entity_icon_lookup(uint16_t index); -// Bit layout for entity_string_packed_: -// [31..24] reserved | [23..16] icon (8 bits) | [15..8] UoM (8 bits) | [7..0] device_class (8 bits) -static constexpr uint8_t ENTITY_STR_DC_SHIFT = 0; -static constexpr uint8_t ENTITY_STR_UOM_SHIFT = 8; -static constexpr uint8_t ENTITY_STR_ICON_SHIFT = 16; -static constexpr uint8_t ENTITY_STR_DC_MASK = 0xFF; -static constexpr uint8_t ENTITY_STR_UOM_MASK = 0xFF; -static constexpr uint8_t ENTITY_STR_ICON_MASK = 0xFF; - // Maximum device name length - keep in sync with validate_hostname() in esphome/core/config.py static constexpr size_t ESPHOME_DEVICE_NAME_MAX_LEN = 31; @@ -104,9 +95,13 @@ class EntityBase { this->flags_.entity_category = static_cast(entity_category); } - // Set packed entity string indices — one call per entity from codegen. - // Bit layout: [23..16] icon (8 bits) | [15..8] UoM (8 bits) | [7..0] device_class (8 bits) - void set_entity_strings(uint32_t packed) { this->entity_string_packed_ = packed; } + // Set entity string table indices — one call per entity from codegen. + // Packed: [23..16] icon | [15..8] UoM | [7..0] device_class (each 8 bits) + void set_entity_strings(uint32_t packed) { + this->device_class_idx_ = packed & 0xFF; + this->uom_idx_ = (packed >> 8) & 0xFF; + this->icon_idx_ = (packed >> 16) & 0xFF; + } // Get device class as StringRef (from packed index) StringRef get_device_class_ref() const; @@ -199,7 +194,6 @@ class EntityBase { void calc_object_id_(); StringRef name_; - uint32_t entity_string_packed_{0}; // bits 0-7: device_class, 8-15: uom, 16-23: icon, 24-31: reserved uint32_t object_id_hash_{}; #ifdef USE_DEVICES Device *device_{}; @@ -214,6 +208,10 @@ class EntityBase { uint8_t entity_category : 2; // Supports up to 4 categories uint8_t reserved : 2; // Reserved for future use } flags_{}; + // String table indices — packed into the 3 padding bytes after flags_ + uint8_t device_class_idx_{}; + uint8_t uom_idx_{}; + uint8_t icon_idx_{}; }; /// Log entity icon if set (for use in dump_config) diff --git a/esphome/core/entity_helpers.py b/esphome/core/entity_helpers.py index 5623b5b502..c0bb1b1c08 100644 --- a/esphome/core/entity_helpers.py +++ b/esphome/core/entity_helpers.py @@ -31,21 +31,16 @@ _KEY_DC_IDX = "_entity_dc_idx" _KEY_UOM_IDX = "_entity_uom_idx" _KEY_ICON_IDX = "_entity_icon_idx" -# Bit layout for entity_string_packed_ (must match C++ constants in entity_base.h): -# -# uint32_t entity_string_packed_: -# [31 ...... 24][23 ...... 16][15 ....... 8][7 ........ 0] -# reserved (8) icon (8) UoM (8) device_class (8) -# max 255 max 255 max 255 -# +# Bit layout for set_entity_strings(packed) — must match C++ setter in entity_base.h: +# [23..16] icon (8 bits) | [15..8] UoM (8 bits) | [7..0] device_class (8 bits) _DC_SHIFT = 0 _UOM_SHIFT = 8 _ICON_SHIFT = 16 -# Maximum unique strings per category (must match bit widths above) -_MAX_DEVICE_CLASSES = 0xFF # 8 bits → 255 -_MAX_UNITS = 0xFF # 8 bits → 255 -_MAX_ICONS = 0xFF # 8 bits → 255 +# Maximum unique strings per category (8-bit index, 0 = not set) +_MAX_DEVICE_CLASSES = 0xFF # 255 +_MAX_UNITS = 0xFF # 255 +_MAX_ICONS = 0xFF # 255 @dataclass