Brings ~55 mod-exclusive files to the upstream-based mod/master-resync branch: Activities (migrated to new ActivityManager pattern): - Clock/Time: SetTimeActivity, SetTimezoneOffsetActivity, NtpSyncActivity - Dictionary: DictionaryDefinitionActivity, DictionarySuggestionsActivity, DictionaryWordSelectActivity, LookedUpWordsActivity - Bookmark: EpubReaderBookmarkSelectionActivity - Book management: BookManageMenuActivity, EndOfBookMenuActivity - OPDS: OpdsServerListActivity, OpdsSettingsActivity - Utility: DirectoryPickerActivity, NumericStepperActivity Utilities (unchanged): - BookManager, BookSettings, BookmarkStore, BootNtpSync - Dictionary, LookupHistory, TimeSync, OpdsServerStore Libraries: PlaceholderCover, TableData, ChapterXPathIndexer Scripts: inject_mod_version, generate_book_icon, preview_placeholder_cover Docs: KOReader sync XPath mapping Migration changes: - ActivityWithSubactivity -> Activity base class - Callback constructors -> finish()/setResult() pattern - enterNewActivity() -> startActivityForResult() - Activity::RenderLock&& -> RenderLock&& These files won't compile yet - they reference mod settings and I18n strings that will be added in subsequent phases. Made-with: Cursor
2.8 KiB
2.8 KiB
Clock Bug Fix, NTP Auto-Sync, and Sleep Persistence
Date: 2026-02-17
Task Description
Three clock-related improvements:
- Fix SetTimeActivity immediately dismissing when opened
- Add automatic NTP time sync on WiFi connection
- Verify time persistence across deep sleep modes
Changes Made
1. Bug Fix: SetTimeActivity immediate dismiss (src/activities/settings/SetTimeActivity.cpp)
- Root cause:
loop()usedwasReleased()for Back, Confirm, Left, and Right buttons. The parentSettingsActivityenters this subactivity on awasPressed()event, so the button release from the original press immediately triggered the exit path. - Fix: Changed all four
wasReleased()calls towasPressed(), matching the pattern used by all other subactivities (e.g.,LanguageSelectActivity).
2. Shared NTP Utility (src/util/TimeSync.h, src/util/TimeSync.cpp)
- Created
TimeSyncnamespace with three functions:startNtpSync()-- non-blocking: configures and starts SNTP servicewaitForNtpSync(int timeoutMs = 5000)-- blocking: starts SNTP and polls until sync completes or timeoutstopNtpSync()-- stops the SNTP service
3. NTP on WiFi Connection (src/activities/network/WifiSelectionActivity.cpp)
- Added
#include "util/TimeSync.h"and call toTimeSync::startNtpSync()incheckConnectionStatus()right afterWL_CONNECTEDis detected. This is non-blocking so it doesn't delay the UI flow.
4. KOReaderSync refactor (src/activities/reader/KOReaderSyncActivity.cpp)
- Removed the local
syncTimeWithNTP()anonymous namespace function and#include <esp_sntp.h> - Replaced both call sites with
TimeSync::waitForNtpSync()(blocking, since KOReader needs accurate time for API requests) - Added
#include "util/TimeSync.h"
5. Boot time debug log (src/main.cpp)
- Added
#include <ctime>and a debug log insetup()that prints the current RTC time on boot (or "not set" if epoch). This helps verify time persistence across deep sleep during testing.
Sleep Persistence Notes
- ESP32-C3's default ESP-IDF config uses both RTC and high-resolution timers for timekeeping
- The RTC timer continues during deep sleep, so
time()/gettimeofday()return correct wall-clock time after wake (with drift from the internal ~150kHz RC oscillator) - Time does NOT survive a full power-on reset (RTC timer resets)
- NTP auto-sync on WiFi connection handles drift correction
Build Verification
pio run -e mod-- SUCCESS (RAM: 31.0%, Flash: 78.8%)
Follow-up Items
- Test on hardware: set time manually, sleep, wake, verify time in serial log
- Test NTP: connect to WiFi from Settings, verify time updates automatically
- Consider adding
TimeSync::stopNtpSync()call when WiFi is disconnected (currently SNTP just stops getting responses, which is harmless)