Records what d4b2ab7 did and what genuinely remains: confirming the left-edge
artefacts by eye (the timing win was measured, the visual result was not),
OTA download logic, optional backlight scheduling, and the thermostat itself.
Co-Authored-By: Claude <noreply@anthropic.com>
Keep the HTTP session alive between weather polls (TODO #1). Re-creating the
client each time forced a fresh TLS handshake inside the window where the UI
is frozen. Measured on hardware: the fetch went from ~1.3s to ~80ms, so the
pause is no longer long enough to matter once thermostat controls exist. The
timeout drops from 30s to 10s once a session is warm, since only a cold
handshake needs the longer budget. Any transport error or non-200 tears the
session down so a half-open connection cannot poison every later poll.
The response buffer is now reset per request rather than on
HTTP_EVENT_ON_CONNECTED -- a kept-alive connection does not re-fire that
event, so the buffer would have accumulated across polls.
Indicate stale readings (TODO #2). After two consecutive failures the
temperature dims and the status line shows the age. Age comes from tick
counts, not weather_data_t.last_update: there is no SNTP client here, so
time(NULL) starts at the epoch and any age derived from it is meaningless.
Gate the touch readout behind UI_DEBUG_TOUCH, default off (TODO #3). Kept the
note about LVGL not bubbling events to parents -- it documents a real trap.
Delete main/utils (TODO #4); it had no callers outside itself. Also refreshed
project_structure.txt, which was additionally missing i2c_bus and backlight.
Lay out two 4MB OTA slots (TODO #5) while no devices are fielded, and document
in the README that an OTA download cannot run while the panel is scanning --
the flash write faults the bounce-buffer ISR.
Log the truncation warning once per response instead of once per chunk, and
record the weather task's stack high-water mark (TODO #6): ~2400 bytes spare
of 6144.
Co-Authored-By: Claude <noreply@anthropic.com>
Records the design-level suggestions from the 2026-08-03 review that were
not part of dd2d428 (UI freeze during fetches, stale-data indication,
debug readout removal, dead utils.c, OTA partitions, small cleanups),
plus the facts already verified and questions already answered so a
future agent does not re-derive or re-ask them.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Clear WIFI_CONNECTED_BIT on disconnect so wifi_is_connected() stops
reporting a link that is gone; the weather task's reconnect path was
dead code without it.
- After the 8 fast retries are spent, retry every 30s via an esp_timer
forever instead of giving up until power cycle. FAIL_BIT now only
unblocks the boot-time wait and is cleared on reconnect.
- Start the weather task even when the boot-time connect times out --
the background retries may still bring WiFi up later. Only an empty
SSID skips it.
- Round temperatures with lroundf(): the old +0.5f-and-truncate rounded
toward zero below 0degF (-10.6 displayed as -10).
- Drop the stale single-framebuffer "Partial-mode flush" comment in
display_rgb.c, fix the README paragraph claiming the bounce buffer is
disabled (it is enabled and load-bearing), and correct the
sdkconfig.defaults header to N16R8/16MB.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>