`const Ts &...` is ill-formed when Ts is already a reference (e.g. a
trigger that passes `std::string &`). Forward Ts by-value so the
generated lambda matches ApplyFn for any valid trigger arg type.
Restore tighter feed cadence on ESP8266 to match the smaller WDT
budgets on this platform. ESP8266 soft WDT is ~1.6 s and HW WDT is
~6 s; a single long iteration (mDNS reply, wifi scan, OTA verify,
lwIP TCP retransmit) can easily push the loop past a few hundred ms.
The 300 ms shared default left only ~1.3 s of soft-WDT headroom; 100 ms
restores ~16x margin to the soft WDT (matching pre-#15846 behavior in
spirit) without per-iteration arch_feed_wdt() cost.
Reports of Hardware WDT - Level1Int crashes on ESP8266 line up with
this margin being too tight under the new main-loop cadence.
_run_idedata raises EsphomeError() with no message, so the warning
shows 'unavailable ()' which looks like a bug. Use a generic fallback
explanation when str(exc) is empty.
_decode_pc shells out to PlatformIO via _run_idedata; without a
populated build dir for the device that subprocess fails for every
PC/BT line in a crash dump. Disable decoding after the first
EsphomeError (per logs session) and emit a single user-facing warning
instead of retrying on every line.
Also rename the helper to _LogLineProcessor since it now owns the
per-session decode-enabled state, not just the decode call.
When 'esphome logs' processes a crash backtrace from the device,
process_stacktrace -> _decode_pc -> _run_idedata can raise
EsphomeError if the local build dir hasn't been populated (e.g. the
device was flashed from a different machine). on_log runs inside an
asyncio protocol callback, so the unhandled exception triggers
'Fatal error: protocol.data_received() call failed.', the loop tears
the connection down, and ReconnectLogic immediately reconnects. The
device replays the same crash trace and we loop forever.
Wrap the per-line decode in a helper that swallows EsphomeError so
the connection stays up. Also covered with unit tests for the new
helper.
Last step in the HAL reorg started in #15977 and continued in the
per-platform follow-ups #16111 (esp32), #16112 (esp8266), #16113
(libretiny), #16114 (rp2040), #16115 (host), #16116 (zephyr) — each of
which moved its platform's out-of-line HAL bodies from
components/<platform>/core.cpp into a new components/<platform>/hal.cpp.
This PR moves each platform's HAL header next to its hal.cpp inside
components/<platform>/, rather than under core/hal/. The dispatcher
core/hal.h is updated to include from the new locations and the
now-empty core/hal/ directory is removed.
Unlike the wake split (#15978) where freertos-class platforms (ESP32 +
LibreTiny) share a single wake_freertos.{h,cpp}, HAL primitives are
genuinely per-platform — there is no shared HAL implementation across
platforms — so the natural home is alongside each platform component
rather than in a separate core/ subdirectory.
Each .h file gains an empty 'namespace esphome::<platform> {}' block to
satisfy ci-custom's lint_namespace check. HAL functions live in
'namespace esphome' (root); they are not part of the per-component API,
matching the convention used by the corresponding hal.cpp files.
Comment-only updates to the components/<platform>/hal.cpp files to
reflect the new include path. No public API change, no behavior change.