Narrow packed fields to 8 bits each, reserve 8 bits for future use

8 bits per field (max 255) is more than sufficient — even large
configs use fewer than 40 unique icons, 14 device classes, and
11 units of measurement. This frees up 8 bits in the packed
uint32_t for future use.
This commit is contained in:
J. Nick Koston
2026-02-21 00:18:44 -06:00
parent 6c92e284c7
commit 2e93a7db78
2 changed files with 16 additions and 16 deletions
+8 -8
View File
@@ -21,13 +21,13 @@ 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..20] icon (12 bits) | [19..10] UoM (10 bits) | [9..0] device_class (10 bits)
// [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 = 10;
static constexpr uint8_t ENTITY_STR_ICON_SHIFT = 20;
static constexpr uint16_t ENTITY_STR_DC_MASK = 0x3FF;
static constexpr uint16_t ENTITY_STR_UOM_MASK = 0x3FF;
static constexpr uint16_t ENTITY_STR_ICON_MASK = 0xFFF;
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;
@@ -105,7 +105,7 @@ class EntityBase {
}
// Set packed entity string indices — one call per entity from codegen.
// Bit layout: [31..20] icon (12 bits) | [19..10] UoM (10 bits) | [9..0] device_class (10 bits)
// 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; }
// Get device class as StringRef (from packed index)
@@ -199,7 +199,7 @@ class EntityBase {
void calc_object_id_();
StringRef name_;
uint32_t entity_string_packed_{0}; // bits 0-9: device_class, 10-19: uom, 20-31: icon
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_{};
+8 -8
View File
@@ -34,18 +34,18 @@ _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 .......... 20][19 ......... 10][9 ........... 0]
# icon (12 bits) UoM (10 bits) device_class (10 bits)
# max 4095 max 1023 max 1023
# [31 ...... 24][23 ...... 16][15 ....... 8][7 ........ 0]
# reserved (8) icon (8) UoM (8) device_class (8)
# max 255 max 255 max 255
#
_DC_SHIFT = 0
_UOM_SHIFT = 10
_ICON_SHIFT = 20
_UOM_SHIFT = 8
_ICON_SHIFT = 16
# Maximum unique strings per category (must match bit widths above)
_MAX_DEVICE_CLASSES = 0x3FF # 10 bits → 1023
_MAX_UNITS = 0x3FF # 10 bits → 1023
_MAX_ICONS = 0xFFF # 12 bits → 4095
_MAX_DEVICE_CLASSES = 0xFF # 8 bits → 255
_MAX_UNITS = 0xFF # 8 bits → 255
_MAX_ICONS = 0xFF # 8 bits → 255
@dataclass