The X-macro file requires ENTITY_TYPE_ and ENTITY_CONTROLLER_TYPE_
macros to be defined before inclusion. The generated esphome.h includes
all .h files bare, which causes compilation errors.
Neither PlatformIO nor ESP-IDF/CMake copy .inc files to the build
directory. Rename to .h so it's recognized by both build systems.
Exempt from pragma-once lint since this file is intentionally included
multiple times with different macro definitions.
clang-tidy flags macro arguments that aren't parenthesized, but
wrapping template type arguments in parentheses would break C++ syntax.
Add NOLINTBEGIN/END around the remaining macro blocks.
PlatformIO only copies files with extensions listed in
SOURCE_FILE_EXTENSIONS to the build directory. Add .inc so that
X-macro include files (entity_types.inc) are available during
compilation.
Introduce entity_types.inc X-macro and entity_includes.h shared header
to eliminate ~1000 lines of repetitive #ifdef/entity-type blocks across
core files.
entity_types.inc defines each entity type once with two macros:
- ENTITY_TYPE_ for non-controller entities (button, infrared)
- ENTITY_CONTROLLER_TYPE_ for entities with controller callbacks
Each consumer includes the file with appropriate macro definitions.
Sites wanting all entities delegate ENTITY_CONTROLLER_TYPE_ to
ENTITY_TYPE_. Sites wanting only controller entities define
ENTITY_TYPE_ as empty.
entity_includes.h consolidates the conditional entity header includes
shared by application.h, controller.h, and controller_registry.h.
Also makes ComponentIterator::on_media_player pure virtual for
consistency (trivial override added to web_server::ListEntitiesIterator).
Add a new message-level option (inline_encode) that causes the code
generator to inline sub-message encoding directly into the parent's
encode/calculate_size methods instead of going through the
encode_sub_message function pointer indirection.
When set on a sub-message type, the generator:
- Inlines field encoding directly (no function pointer, no backpatch overhead)
- Inlines size calculation (no separate method call)
- Skips generating standalone encode/calculate_size methods
- Validates at generation time that max encoded size < 128 bytes
Applied to BluetoothLERawAdvertisement which is encoded 12 times per
BLE advertisement batch in a hot loop.
When the client sends 6+ messages during handshake (HelloReq, AuthReq,
GetTimeResp, SubscribeLogsReq, DeviceInfoReq, ListEntitiesReq),
MAX_MESSAGES_PER_LOOP=5 caused ListEntitiesReq to remain unread in
the socket buffer.
LWIP's rcvevent counter (used by is_socket_ready) tracks pbuf dequeues,
not remaining bytes. When multiple ESPHome messages share a single TCP
segment/pbuf, reading all but the last message exhausts rcvevent to 0
while the last message's data remains in LWIP's internal lastdata cache.
is_socket_ready() then returns false, and the data is never read — the
entity listing silently stalls until something else (like a keepalive
ping) triggers new socket activity.
Fix:
- Track when the read loop hits MAX_MESSAGES_PER_LOOP and retry on the
next iteration without the is_socket_ready() gate
- Increase MAX_MESSAGES_PER_LOOP from 5 to 10 (decode cost is now 3x
cheaper, and we batch 24-34 messages per write)
- Move set_nodelay_for_message(false) before try_to_clear_buffer in
process_batch_() so NODELAY is set before draining overflow