Benchmarking in #15034 showed that esp_log_printf and vsnprintf_chk
dominate sensor publish time (95%+ of internal_send_state_to_frontend).
At the default DEBUG log level, every state change generates log output
that overwhelms the log output making it hard to actually debug and
wastes significant CPU time on string formatting.
Move all entity state publish (>>) and setting logs from ESP_LOGD to
ESP_LOGV across all base entity types: sensor, binary_sensor, switch,
number, text_sensor, select, text, event, lock, cover, valve, climate,
fan, light, media_player, alarm_control_panel, datetime, update, and
water_heater.
- Remove dead DEFAULT_SLOT_COUNT constant from host header
- Fix misleading BSS comments (Logger is heap-allocated via new_Pvariable)
- Add comment explaining Zephyr BUF_WORD_COUNT formula
Follow-up to #15071 which moved the TaskLogBuffer allocation into the
Logger constructor to fix a race condition where another task could log
before the buffer was initialized.
This takes that fix further by eliminating the heap allocation entirely.
The buffer size is a codegen constant, so we emit it as a define
(ESPHOME_TASK_LOG_BUFFER_SIZE) and use it to size member arrays directly.
The TaskLogBuffer becomes a direct member of Logger rather than a
heap-allocated pointer, placing the entire buffer in BSS.
Changes per platform:
- ESP32: storage_ from RAMAllocator heap to member array
- Host: slots_ from unique_ptr<LogMessage[]> to member array
- LibreTiny: storage_ from RAMAllocator heap to member array
- Zephyr: mpsc buf from new uint32_t[] to member array
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
The API component calls status_set_warning() without a message when no
client is connected and reboot timeout is enabled. This results in a
confusing log line: "api set Warning flag: unspecified"
Replace with a descriptive message so users see:
"api set Warning flag: waiting for client connection"
Closes https://github.com/esphome/esphome/issues/15140
IfAction now takes a bool HasElse template parameter. When false (the
common case — most if actions have no else branch), the else_ ActionList
is replaced by an empty struct with [[no_unique_address]], saving 8
bytes per instance.
The codegen already knows at generation time whether an else branch
exists and passes the appropriate template argument.
Replace the inline optional<LightStateRTCState> (~44 bytes) with a
function pointer callback (4 bytes) that populates the initial state
during setup. The callback is a stateless lambda whose values live in
flash as code, not in the LightState object.
Saves ~40 bytes per LightState instance unconditionally — the optional
reserved space for the struct even when initial_state was not configured
(the common case).
Replace 14 TemplatableValue fields with a per-field union that stores
either a constant value or a callable pointer in the same 4 bytes
(on 32-bit targets). A 2-bit-per-field type tag in a uint32_t tracks
field state (unset/constant/stateless lambda/stateful lambda).
Reduces LightControlAction from 128 to 76 bytes per instance on ESP32.
For a config with 8 light actions, this saves 416 bytes of RAM and
476 bytes of flash (from eliminated TemplatableValue template
instantiations).
Replace 14 TemplatableValue fields with a per-field union that stores
either a constant value or a callable pointer in the same 4 bytes
(on 32-bit targets). A 2-bit-per-field type tag in a uint32_t tracks
field state (unset/constant/stateless lambda/stateful lambda).
Reduces LightControlAction from 128 to 76 bytes per instance on ESP32.
For a config with 8 light actions, this saves 416 bytes of RAM and
476 bytes of flash (from eliminated TemplatableValue template
instantiations).