Without configTime(), the ESP32 DNS subsystem isn't properly
initialized after WiFi connect, causing HTTPS hostname resolution
to fail silently in the deep sleep wake path. The fix calls
configTime() fire-and-forget (non-blocking, <1ms) which initializes
DNS without the 5-second NTP wait.
Co-authored-by: Cursor <cursoragent@cursor.com>
The syncNTP() call blocks up to 5 seconds waiting for NTP response on
every deep sleep wake cycle (every 10 minutes). Combined with mDNS
startup, this added significant active WiFi time per cycle.
Fix: Add 'minimal' flag to WiFiManager::begin()/startStation(). In
the deep sleep wake path, skip NTP sync and mDNS entirely. The system
clock is already seeded from the hardware RTC at boot, which is
accurate enough for 30-day date window calculations.
Normal interactive boot still does full NTP sync + mDNS as before.
Co-authored-by: Cursor <cursoragent@cursor.com>
Refactor timerWakeCycle() to fetch a single random photo per wake
using cycle-mode-aware server-side filtering via Immich's
POST /api/search/random endpoint.
Changes:
- Add fetchOneRandomAssetId() to ImmichClient with support for
isFavorite, takenAfter, takenBefore filter parameters
- Add timer_last_date NVS field for chronological cursor persistence
- Implement probabilistic filter selection per cycle mode:
- Random: unfiltered size=1
- Chronological/ReverseChronological: date cursor in NVS
- FavoritesWeighted: 66% favorites, 33% unfiltered
- WeightedChronological: 66% recent (30d), 33% unfiltered
- WeightedReverseChronological: 66% older (30d), 33% unfiltered
- Add retry loop with filter relaxation on empty results
- Initialize hardware RTC (RX8130CE) firmware-wide:
- Seed system clock from RTC at boot (immediate time)
- NTP sync after WiFi connect, write back to RTC
- Add time_utils.h with isoNow(), isoNowMinus30d(), hasValidTime()
Normal mode (PhotoQueue + displayTask) is completely untouched.
Co-authored-by: Cursor <cursoragent@cursor.com>