The compiled ESPHOME_LOG_LEVEL is what matters - all log calls up
to that level are in the binary and will format/block UART regardless
of runtime initial_level.
Add a warning in dump_config() when the active log level is
VERBOSE or VERY_VERBOSE to remind users these levels are intended
for short-term debugging only.
VERY_VERBOSE triggers an ESP_LOGW, VERBOSE triggers an ESP_LOGI.
Both are guarded by compile-time #if/#elif so no code is added
when compiled at a lower log level.
- static_assert that forwarders are pointer-sized and trivially
copyable so future field additions can't silently cause heap
allocation in Callback::create().
- Widen forwarder parameter type hint to MockObj | MockObjClass.
- TriggerForwarder::operator() now takes const Ts&... to avoid
copies of non-trivial types (e.g., std::string).
- Revert lock to trigger-based pattern: LockStateForwarder holds
two pointers (automation + lock), exceeding sizeof(void*) which
would cause Callback::create to heap-allocate.
- Remove forwarder_extra_args from API since lock was the only user.
Replace bool_filter with generic forwarder parameter that accepts
any struct type. Components can define their own forwarders with
custom fields (e.g., LockStateForwarder needs both automation and
lock entity pointers).
Migrates number (NumberStateTrigger) and lock (LockStateTrigger)
to prove the API is flexible enough for diverse patterns.
Replace per-site lambda generation with TriggerForwarder<Ts...>,
TriggerOnTrueForwarder, and TriggerOnFalseForwarder structs. The
compiler generates one operator() per forwarder type shared across
all call sites, avoiding flash duplication from unique lambdas.
Also cleans up API: replaces condition/callback_args with
bool_filter using TRIGGER_ON_TRUE/TRIGGER_ON_FALSE constants.
Tests the lambda output format for all variations used by
build_callback_automation: no args, typed args, conditions,
multiple args, and empty capture.
Add build_callback_automation() to register automation callbacks
directly on parent components, bypassing the Trigger wrapper object.
Migrates button, sensor, binary_sensor, switch, and text_sensor
to the new pattern, eliminating 12 thin wrapper trigger classes
from runtime instantiation.
Replace the shared noinline notify() dispatch loop with direct
virtual calls in each notify method. This eliminates two levels
of indirection (noinline function call + function pointer) from
every entity state publish while adding only ~20 bytes of flash
per entity type for the duplicated loop.
IDF 6 uses picolibc instead of newlib. In newlib, vfprintf was a thin
36-byte trampoline to _vfprintf_r, so wrapping printf/vprintf/fprintf
was sufficient to dead-code eliminate _vfprintf_r. In picolibc, vfprintf
IS the heavy implementation (~2.8 KB) and is referenced directly by SDK
components. Add vfprintf to the wrap list to intercept those references.