Commit graph

26 commits

Author SHA1 Message Date
cjkas
a49fa5d953 fix: don't hold position updates back while the radio is full
processQueue stopped draining web commands whenever the radio queue was
near full, including set_positions, which never transmits.  Look at the
command at the head and only hold it back if it needs the radio, keeping
the commands in order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:59:48 +02:00
cjkas
ab0eba2035 fix: leave out /controller items that overflow instead of breaking the JSON
The formatter drops a value that doesn't fit but keeps appending the
commas and braces after it, so an oversized shade or group streamed
invalid JSON.  Check overflowed() after each unit, log the item and skip
it, and keep producing until a unit or the end so a skip never ends the
stream early.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:59:39 +02:00
cjkas
a8bb377957 fix: track the JSON length instead of recounting it
Every append found the end of the buffer with strlen(), up to four
times per append and four appends per field, so building a response
cost the square of its size. /discovery fills a 4 KB buffer and spent
about 195 ms of its ~210 ms there (shades 126 ms, groups 69 ms), all on
the async_tcp task that serves every socket and web request.

Keep the length in the formatter and write every append at the end
through one helper. The web response and socket event subclasses and
ControllerChunker use the tracked length too. Output is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:04:13 +02:00
cjkas
0610dc4369 feat: log where /discovery spends its time
The /discovery handler takes about 200ms on the async_tcp task on every
call with no obvious cause. When it takes 50ms or more, log how long
the header, memory stats, rooms, shades, groups and sending took.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 20:50:49 +02:00
cjkas
f1eac31957 fix: report the real flipPosition for linked shades
serializeShadeRef sent flipCommands as flipPosition, so group linked
shades and the /shadeCommand reply showed the wrong setting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 20:50:42 +02:00
cjkas
dd47c04905 feat: log timings for slow work, socket clients and boot crashes
Add Timing.h and use it to log what holds up the main loop, how long a
new socket client's setup takes, slow socket sends, and how long each
web request took and from which client. Socket connects and disconnects
are logged with how long the client stayed, and late pings as warnings.
Routine sends and pings are not logged, as each line costs several ms
on a 115200 baud console.

Report a stored crash once with the crashed and running build IDs, then
erase it, since it was reported on every boot and its backtrace only
decodes against the build that crashed. Mount the file system once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 20:35:43 +02:00
cjkas
1f394ca9df fix: back-pressure web commands and report radio failures
Web commands are answered once queued, but the main loop handed all of
them to the radio at once and anything past its free slots was dropped
silently.  Unpair also cleared paired even when the Prog wasn't sent.

- processQueue leaves commands queued until the radio has room.
- Commands that transmit get a 503 straight away during a frequency
  scan instead of being dropped later.
- Unpair restores paired when the Prog can't be sent.
- Failed web commands are logged.
- Note that /setPositions and /setSensor answer with the state before
  the command; the socket events carry the result.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:46:40 +02:00
cjkas
2a54740f52 fix: never leave radio TX suspended after a scan or aborted OTA
- endFrequencyScan always resumes TX; applying radio settings ends a scan.
- Frequency scans time out after 5 minutes.
- Reboot when an OTA upload is abandoned mid-transfer.
- /sendRemoteCommand returns 503 when the radio can't take the frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:23:20 +02:00
cjkas
9d16d6cc6d fix: address radio TX task review findings
- Abort in-flight transmissions on flush so config save, frequency scan
  and OTA never wait on the radio lock for a whole job
- Suspend TX during frequency scan and OTA
- Refuse commands the radio queue cannot take before consuming a rolling
  code or moving simulated shade state; shift movement start when a job
  goes on air late
- Apply radio config changes under the radio lock
- Re-check receiver idle before repeater transmissions
- Return 503 from web handlers when the command queue is full
- Restore 200 ms settle delay before the set-My command
- Report RSSI 0 instead of a stale value when the radio is busy
- Encode each frame once and centralise the repeat clamp

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-10 20:39:18 +02:00
cjkas
9a9afa5e86 fix: move radio TX to a dedicated task so HA WebSocket stays connected
Web command handlers ran on the async_tcp task and blocked up to 3s
waiting for loop() to bit-bang radio frames. async_tcp also services the
WebSocket on port 8080, so pongs stalled and Home Assistant
(ping_timeout=15) disconnected when several covers were commanded.

- Add a radio_tx FreeRTOS task with a job queue; sendFrame/repeatFrame
  and repeater frames enqueue instead of transmitting inline.
- Serialize CC1101 access with a recursive mutex (TX task, apply, end,
  frequency scan, RSSI read).
- Make Web::queueCommand fire-and-forget; drop the done semaphore.
- Route /setMyPosition and /unpairShade through the command queue.
- Clamp repeats to MAX_TX_REPEATS (40).
- Pin AsyncTCP to core 0 on dual-core targets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 20:13:31 +02:00
cjkas
6365f16850 Memory-bounded streaming builder for /controller. Produces the JSON payload one small unit at a time into a fixed 3KB buffer, so a chunked HTTP response can drain it as the TCP send window allows — no growing cbuf in the async response stream. 2026-04-21 14:56:20 +02:00
cjkas
5a167e3b11 Fix bkp bug 2026-04-03 20:07:40 +02:00
cjkas
0dbb1da2bf Tsury noise detection 2026-03-30 09:22:22 +02:00
cjkas
72bfd26443 Added c6 support 2026-03-29 21:53:57 +02:00
cjkas
d5b8acecda fix race condition with multiple simultaneus requests 2026-03-25 16:09:08 +01:00
cjkas
2e379e6c1e Cleanup build warnings 2026-03-24 22:15:17 +01:00
cjkas
a220b9ecc2 replace Serial.print with logger 2026-03-24 20:28:06 +01:00
cjkas
8262f392f5 remove sync server 2026-03-24 19:23:35 +01:00
cjkas
a55dc7f66b update to async web server 2026-03-24 19:23:35 +01:00
cjkas
73f39d67c3 refactor 2026-03-24 19:23:35 +01:00
cjkas
8c51e1a518 up 2026-03-24 19:23:35 +01:00
cjkas
9ccc2d4ff5 async server introduction 2026-03-24 19:22:57 +01:00
cjkas
c94819e928 fix crash 2026-03-24 19:22:56 +01:00
cjkas
2509030c49 backup with RAM 2026-03-13 18:40:34 +01:00
cjkas
96d66c1b45 add gzip support 2026-03-12 13:59:17 +01:00
cjkas
a64b648f7a init 2026-03-10 20:23:48 +01:00
Renamed from Web.cpp (Browse further)