Commit Graph
27929 Commits
Author SHA1 Message Date
J. Nick Koston 49584c1f15 Merge remote-tracking branch 'upstream/dev' into integration 2026-04-24 09:56:10 -05:00
Kevin Ahrendt 55bcf33446 [sendspin] Add metadata sensor component (#15971) 2026-04-24 14:32:47 +00:00
Kevin Ahrendt f132b7dc07 [media_player][speaker][speaker_source] Centralize preferred format codegen (#14771) 2026-04-24 14:09:03 +00:00
J. Nick Koston 6cee6d68f4 Merge remote-tracking branch 'upstream/sendspin-sensors' into integration 2026-04-24 09:06:41 -05:00
Kevin Ahrendt 61de24a279 drop bound check on year and track number as they aren't relevant (we only checked text sensors so we wouldn't overflow the character buffer) 2026-04-24 09:56:09 -04:00
J. Nick Koston e694873aa5 Merge remote-tracking branch 'upstream/sendspin-sensors' into integration 2026-04-24 08:52:29 -05:00
Kevin Ahrendt 66019feb8f add year and track number sensors (will remove them from text_sensor in a future PR) 2026-04-24 09:27:37 -04:00
J. Nick Koston baa6d5f96b [web_server_idf] Fix cross-thread race on SSE session state (#15967) 2026-04-24 08:11:47 -05:00
J. Nick Koston 773b4d887b [core] Scheduler: don't sleep while defer queue is non-empty (#15968) 2026-04-24 08:11:29 -05:00
Kevin Ahrendt a179a0de22 log the update interval for the track progress sensor 2026-04-24 08:46:11 -04:00
Kevin Ahrendt f395e29c59 publish immediately on resume 2026-04-24 08:44:41 -04:00
Kevin Ahrendt 6b278e3eb4 make both sensors inherit from the hub's defined child classes to enforce setup priority 2026-04-24 08:44:24 -04:00
Kevin Ahrendt 8f3a2691fa Add a SendspinPolloingChild class to enforce uniform setup priority 2026-04-24 08:43:42 -04:00
Kevin Ahrendt 52eeb52d0e mark get_track_progress_ms as const 2026-04-24 08:43:06 -04:00
Kevin Ahrendt 42f0b1a7e2 add Sendspin sensor component 2026-04-24 08:21:29 -04:00
Kevin Ahrendt ac7f0f0b74 [sendspin] Add a metadata text sensor component (#15969) 2026-04-24 11:07:00 +00:00
J. Nick Koston 761e32bdc5 Merge remote-tracking branch 'upstream/dev' into integration 2026-04-24 05:53:44 -05:00
Kevin AhrendtCopilotCopilotpre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>J. Nick Koston
bc7f35b569 [sendspin] Add a Sendspin media source component for playing audio (PR4) (#15950)
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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@koston.org>
2026-04-24 10:00:22 +00:00
J. Nick Koston b07ec95c13 Merge remote-tracking branch 'upstream/dev' into integration 2026-04-24 03:42:42 -05:00
J. Nick Koston ae02ab3865 [wifi] Fix stale wifi.connected after state transition (#15966) 2026-04-24 03:42:36 -05:00
J. Nick Koston 0542674452 Merge remote-tracking branch 'upstream/web_server_idf_session_ownership' into integration 2026-04-24 03:42:27 -05:00
J. Nick Koston 8bd8be2ac2 [web_server_idf] Add NOLINT at call site for cross-function analyzer path
The function-level NOLINTBEGIN/NOLINTEND on start_session_main_loop_()
only covers bug paths whose primary or note locations fall inside that
function. clang-analyzer now traces the leak through the caller chain
(AsyncEventSource::loop -> adopt_pending_sessions_main_loop_ ->
start_session_main_loop_ -> ArduinoJson), with notes at lines 497/498
and 530/537 that sit outside the wrapped range. Add a NOLINTNEXTLINE
at the call site in adopt_pending_sessions_main_loop_ so the caller's
bug-path location is covered too.
2026-04-24 03:41:48 -05:00
J. Nick Koston de729c6095 Merge remote-tracking branch 'upstream/scheduler_wake_when_defer_pending' into integration 2026-04-24 03:37:51 -05:00
J. Nick Koston d507feaf81 [core] Scheduler::next_schedule_in: also handle single-threaded defer path
On ESPHOME_THREAD_SINGLE builds (ESP8266, RP2040), defer() does not
route through defer_queue_ — set_timer_common_ treats it as an ordinary
0-delay set_timeout that stages in to_add_ (scheduler.cpp:197). Since
next_schedule_in only inspects items_[0], any defer posted from a
component's loop() sits in to_add_ invisible to the sleep calculation
until the next scheduler.call() runs process_to_add().

The symmetric fix checks to_add_empty_() on single-threaded and
short-circuits sleep the same way. This also costs one "skipped sleep"
for any non-zero-delay timer added at runtime, but the next tick
produces a correct next_schedule_in reading and the cost is a single
yield — negligible vs. the stall this closes.

Suggested by Copilot review on #15968.
2026-04-24 03:37:11 -05:00
J. Nick Koston f4b7bb3613 Merge remote-tracking branch 'upstream/web_server_idf_session_ownership' into integration 2026-04-24 03:28:37 -05:00
J. Nick Koston b0ac9477df [web_server_idf] Widen NewDeleteLeaks NOLINT over start_session_main_loop_
The previous narrow NOLINT only wrapped the sorting_groups JSON loop.
Now that the function is invoked through an extra call layer
(loop() -> adopt_pending_sessions_main_loop_ -> start_session_main_loop_),
clang-analyzer traces a leak path through ws->get_config_json() as
well -- also a false positive inside ArduinoJson's VariantData.
Move the NOLINTBEGIN/NOLINTEND to bracket the entire function body.
2026-04-24 03:28:24 -05:00
J. Nick Koston c150041f1a Merge remote-tracking branch 'upstream/scheduler_wake_when_defer_pending' into integration 2026-04-24 03:28:04 -05:00
J. Nick Koston da5c31cb27 [core] Scheduler::next_schedule_in: return 0 when defer queue is non-empty
On multi-thread platforms (ESP32/LibreTiny/host), defer() items go
directly into a separate defer_queue_ instead of the main items_ heap
(scheduler.cpp:200). next_schedule_in previously only looked at
items_[0], so a pending defer posted from a background task was
invisible to the loop's sleep-duration calculation: if items_[0] fired
seconds away, the main loop would sleep that long on ulTaskNotifyTake
while the defer sat unexecuted.

In practice this rarely bit anyone because concurrent socket activity
usually woke the loop via the lwip fast-select path, but a defer with
no accompanying network traffic could stall for seconds.

Check defer_empty_() (cheap atomic/volatile load, scheduler.h:594)
before the items_ check and return 0 if pending. process_defer_queue_
runs at the top of every scheduler.call(), so "defer pending" == "run
immediately."

Single-threaded platforms funnel defers into to_add_ like any other
timeout, so the fix is gated on !ESPHOME_THREAD_SINGLE.
2026-04-24 03:26:21 -05:00
J. Nick Koston ba93b9af18 Merge remote-tracking branch 'upstream/web_server_idf_session_ownership' into integration 2026-04-24 03:19:13 -05:00
J. Nick Koston 4fca594871 [web_server_idf] Drop redundant 'Removing dead event source session' log
destroy() already logs the close with the fd on the httpd task, so the
follow-up log when the main loop reaps the session adds no information
and doubles log volume during reconnect storms.
2026-04-24 03:18:58 -05:00
J. Nick Koston b46ccb5ae0 [web_server_idf] Move NOLINTNEXTLINE adjacent to onConnect declaration 2026-04-24 03:16:42 -05:00
J. Nick Koston c024cfd0dc Merge remote-tracking branch 'upstream/web_server_idf_session_ownership' into integration 2026-04-24 03:11:28 -05:00
J. Nick Koston 3507d567cc [web_server_idf] Preserve on_connect_ ordering and document main-loop context
Pre-refactor, on_connect_ ran after the ctor had already sent the
initial ping/config/sorting_groups. Call start_session_main_loop_()
before on_connect_ so the callback still observes a primed session.

Also document at onConnect() that the callback now runs on the main
loop instead of the httpd task.
2026-04-24 03:10:17 -05:00
J. Nick Koston b2b29cd506 Merge remote-tracking branch 'upstream/web_server_idf_session_ownership' into integration 2026-04-24 03:08:25 -05:00
J. Nick Koston 121b4d6916 [web_server_idf] Move session adoption to out-of-line cold path
Keep the hot path in AsyncEventSource::loop() to the atomic load,
branch, and dead-session cleanup. On a real connect, call a
noinline+cold helper (adopt_pending_sessions_main_loop_) to swap the
pending list out, drop any already-disconnected sessions, and invoke
on_connect_ / start_session_main_loop_ on the rest.
2026-04-24 03:08:01 -05:00
J. Nick Koston fb4a5ccd56 Merge remote-tracking branch 'upstream/web_server_idf_session_ownership' into integration 2026-04-24 03:06:35 -05:00
J. Nick Koston c7a67ac41d [web_server_idf] Rename prime_() to start_session_main_loop_() 2026-04-24 03:04:50 -05:00
J. Nick Koston 1df529cbca [web_server_idf] Drop padding comment 2026-04-24 03:01:48 -05:00
J. Nick Koston a0c8d99c11 Merge remote-tracking branch 'upstream/web_server_idf_session_ownership' into integration 2026-04-24 03:01:18 -05:00
J. Nick Koston 9b28edd23e [web_server_idf] De-dupe destructor delete loops 2026-04-24 03:00:29 -05:00
J. Nick Koston 44b4a20abe [web_server_idf] Hold pending_mutex_ for both deletes in destructor 2026-04-24 03:00:04 -05:00
J. Nick Koston b1390f1679 [web_server_idf] Drop pre-disconnected sessions before on_connect_
If fd_ is already 0 when the main loop adopts an incoming session, the
client closed before we got here. Delete the session immediately instead
of pushing it into sessions_ and firing on_connect_ on a dead socket.
2026-04-24 02:59:03 -05:00
J. Nick Koston 82081fc567 [web_server_idf] Trim comments 2026-04-24 02:58:45 -05:00
J. Nick Koston 5fab869286 [web_server_idf] Move has_pending_sessions_ to end to tighten layout
Keep the single-byte std::atomic<bool> as the last member of
AsyncEventSource so it consumes what would otherwise be trailing
padding instead of introducing 3 bytes of interior padding between
pending_mutex_ and on_connect_.
2026-04-24 02:57:21 -05:00
J. Nick Koston f4a055f342 [web_server_idf] Defer SSE session adoption/priming to the main loop
AsyncEventSource::handleRequest() runs on the ESP-IDF httpd task. Prior to
this change it mutated sessions_, event_buffer_, deferred_queue_, and
entities_iterator_ directly: appending the new response to sessions_,
sending the initial ping/config/sorting_groups through try_send_nodefer()
(which writes event_buffer_), and calling entities_iterator_.begin().
The main loop reads/writes the same fields from WebServer::loop() on the
main task, so every new SSE connect raced with any in-flight loop tick.

The httpd path now only performs the HTTP-level setup that requires the
live httpd_req_t (headers, initial chunk, sess_ctx/free_ctx, fd_, send
override) and parks the response on pending_sessions_ under a mutex.
The main loop checks a std::atomic<bool> fast-path gate per tick; when
set it swaps the pending list out under the lock and then — outside the
lock — pushes into sessions_, invokes on_connect_, and calls prime_()
which performs the initial sends and starts entities_iterator_.

sessions_, event_buffer_, deferred_queue_, and entities_iterator_ are
now mutated exclusively from the main loop. fd_ remains the only
cross-thread signal (std::atomic<int> cleared by destroy() on the
httpd/tcpip task).
2026-04-24 02:55:23 -05:00
J. Nick Koston eceb534895 [deep_sleep] Fix sleep_duration codegen type to uint32_t (#15965) 2026-04-24 07:19:59 +00:00
J. Nick Koston 811d4ddfbd [mdns] Tighten ESP8266 guards, expand window to 15s, document derivation
- mdns_esp8266.cpp: narrow setup()'s listener block and on_ip_state from
  USE_MDNS_EVENT_DRIVEN_POLLING to USE_MDNS_WIFI_LISTENER. ESP8266 has no
  ethernet so the practical effect is identical, but the tighter guard is
  symmetric with mdns_rp2040.cpp and more defensible if the listener macros
  ever drift.
- MDNS_POLL_WINDOW_MS 12000 → 15000. The RFC-compliant LEAmDNS phase is ~9s
  worst case, but a blocked main loop (long component setup, WiFi scan, flash
  writes) can stretch the deadlines between our polls. 6s of margin absorbs
  that without materially extending the steady-state quiet period.
- Header comment for MDNS_POLL_WINDOW_MS now breaks down the 9s derivation
  with the exact LEAmDNS constants (MDNS_PROBE_DELAY × MDNS_PROBE_COUNT +
  MDNS_ANNOUNCE_DELAY × MDNS_ANNOUNCE_COUNT + jitter + debounce hop) so
  future library bumps can be justified against the same math.
2026-04-23 21:48:18 -05:00
tomaszduda23andCopilot 404620b99c [deep_sleep][logger][zephyr][zigbee] add deep sleep support with zigbee wakeup (#13950)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-23 22:31:46 -04:00
J. Nick Koston 097377f7b5 Merge remote-tracking branch 'origin/mdns-event-driven-polling' into integration 2026-04-23 21:30:46 -05:00
J. Nick Koston fad3912997 [mdns] Restore USE_MDNS_EVENT_DRIVEN_POLLING guards around listener definitions
clang-tidy CI compiles with the raw esp8266-arduino-tidy env's flags — no
Python codegen, and it doesn't pick up the feature defines from defines.h in
the same way a real IDE does. USE_WIFI_IP_STATE_LISTENERS ends up undefined,
the derivation in mdns_component.h doesn't fire, and the class doesn't declare
start_polling_window_ / on_ip_state / the MDNS_POLL_* constants. Removing the
guards in the platform cpps made those definitions dangle.

Keep the listener-specific definitions under #ifdef USE_MDNS_EVENT_DRIVEN_POLLING.
The Python validator still enforces the runtime invariant (wifi or ethernet
must be present on ESP8266/RP2040), so production builds always fire through
the listener path; this is purely about what the tidy compiler sees.
2026-04-23 21:20:03 -05:00