In debug builds (HAS_PROTO_MESSAGE_DUMP), skip dump logging for
SubscribeLogsResponse (recursive logging risk) and CameraImageResponse
(high-frequency image data noise). This matches the base branch behavior
where both bypassed dump logging via direct send_message_impl() calls.
Reduces per-instantiation cost of send_message<T> and
encode_message_to_buffer<T> by moving the DumpBuffer/log code
into send_message_() and encode_to_buffer(). The dump methods
(message_name, dump_to) are still virtual on ProtoMessage, so
they work correctly through the void* → ProtoMessage* cast.
Defense-in-depth: validate device class strings don't exceed the
48-byte PROGMEM buffer limit (47 chars + null), matching the same
pattern used for icon strings.
Same treatment as icons in #14437. Device class strings were in
.rodata (RAM on ESP8266). Now stored as individual PROGMEM char arrays.
- Add get_device_class_to(std::span<char, MAX_DEVICE_CLASS_LENGTH>)
buffer API matching get_icon_to() pattern
- Add fill_and_encode_entity_info_with_device_class() wrapper to
deduplicate buffer handling across 10 API entity types
- Centralize MQTT device_class in send_discovery_() lambda where
buffer lifetime outlives ArduinoJson serialization
- Deprecate get_device_class_ref()/get_device_class() on non-ESP8266
- static_assert error on ESP8266 directing to get_device_class_to()
- Update all callers: api, mqtt, web_server, log helper
- When USE_ENTITY_ICON is disabled, return "" directly without
calling through the lookup table
- When enabled, ensure the empty-string fallback (index 0 / out of
range) is a PROGMEM char array so strncpy_P on ESP8266 is safe
The switch from cyw43_tcpip_link_status to cyw43_wifi_link_status
was intended for 2026.3.0 alongside the arduino-pico 5.5.0 framework
update but was accidentally included in 2026.2.3.
With the old framework (3.9.4), cyw43_wifi_link_status never returns
CYW43_LINK_UP, so the CONNECTED state is unreachable. The device
connects to WiFi but the status stays at CONNECTING until timeout,
causing a connect/disconnect loop.
Fixes https://github.com/esphome/esphome/issues/14422