mirror of
https://github.com/pelgraine/Meck.git
synced 2026-07-28 20:32:47 +02:00
Contacts: cap chunked save to twice a day; flush on low battery
Throttle the ESP32 lazy contact save from a 5s debounce to a 12h interval (CONTACTS_SAVE_INTERVAL). A new _nextContactSaveDue anchors the next flush 12h out on the first dirty pass and only writes once reached, clearing after each save so the next dirty event re-anchors. Cuts the recurring ~95KB LittleFS rewrites on busy meshes. nRF52/STM32 blocking-save path unchanged. Flush contacts (blocking) in the AUTO_SHUTDOWN_MILLIVOLTS path before shutdown() so low-battery power-off doesn't drop up to 12h of contact learning. Manual power-off left untouched. Gate the SHUTDOWN home page out on the watch (MECK_TWATCH): removed from the HomePage enum with render/input/isOnShutdownPage guarded. The AXP2101 PWR-button long-press is the shutdown path there. Files: MyMesh.h, MyMesh.cpp, UITask.cpp
This commit is contained in:
@@ -119,6 +119,7 @@
|
||||
#define DIRECT_SEND_PERHOP_EXTRA_MILLIS 250
|
||||
#define LAZY_CONTACTS_WRITE_DELAY 5000
|
||||
#define USER_IDLE_SAVE_THRESHOLD 15000 // Defer saves until 15s after last keypress
|
||||
#define CONTACTS_SAVE_INTERVAL 43200000 // 12h: cap chunked contact flush to twice a day
|
||||
|
||||
#define PUBLIC_GROUP_PSK "izOH6cXN6mrJ5e26oRXNcg=="
|
||||
|
||||
@@ -1495,6 +1496,7 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
|
||||
next_ack_idx = 0;
|
||||
sign_data = NULL;
|
||||
dirty_contacts_expiry = 0;
|
||||
_nextContactSaveDue = 0;
|
||||
advert_paths = nullptr; // PSRAM-allocated in begin()
|
||||
_rxlog = nullptr; // PSRAM-allocated in begin()
|
||||
_rxlog_head = 0;
|
||||
@@ -3714,8 +3716,15 @@ void MyMesh::loop() {
|
||||
// Voice session or active keyboard use -- push save forward
|
||||
dirty_contacts_expiry = futureMillis(2000);
|
||||
} else if (!_store->isSaveInProgress()) {
|
||||
_store->beginSaveContacts(this);
|
||||
dirty_contacts_expiry = 0;
|
||||
// Cap the chunked flush to CONTACTS_SAVE_INTERVAL (twice a day): anchor
|
||||
// the next-due time on the first dirty pass, then only write once it is
|
||||
// reached. Cleared after a save so the next dirty event re-anchors.
|
||||
if (_nextContactSaveDue == 0) _nextContactSaveDue = futureMillis(CONTACTS_SAVE_INTERVAL);
|
||||
if (millisHasNowPassed(_nextContactSaveDue)) {
|
||||
_store->beginSaveContacts(this);
|
||||
dirty_contacts_expiry = 0;
|
||||
_nextContactSaveDue = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -346,6 +346,7 @@ private:
|
||||
uint8_t *sign_data;
|
||||
uint32_t sign_data_len;
|
||||
unsigned long dirty_contacts_expiry;
|
||||
unsigned long _nextContactSaveDue; // ESP32 chunked save: next scheduled flush (0 = unscheduled)
|
||||
|
||||
TransportKey send_scope;
|
||||
|
||||
|
||||
@@ -183,7 +183,9 @@ class HomeScreen : public UIScreen {
|
||||
#if HAS_BQ27220
|
||||
BATTERY,
|
||||
#endif
|
||||
#if !defined(MECK_TWATCH)
|
||||
SHUTDOWN,
|
||||
#endif
|
||||
Count // keep as last
|
||||
};
|
||||
|
||||
@@ -366,7 +368,11 @@ public:
|
||||
bool isEditingUTC() const { return _editing_utc; }
|
||||
bool isFirstPage() const { return _page == HomePage::FIRST; }
|
||||
bool isOnRecentPage() const { return _page == HomePage::RECENT; }
|
||||
#if defined(MECK_TWATCH)
|
||||
bool isOnShutdownPage() const { return false; }
|
||||
#else
|
||||
bool isOnShutdownPage() const { return _page == HomePage::SHUTDOWN; }
|
||||
#endif
|
||||
void cancelEditing() {
|
||||
if (_editing_utc) {
|
||||
_node_prefs->utc_offset_hours = _saved_utc_offset;
|
||||
@@ -1260,7 +1266,9 @@ public:
|
||||
sprintf(buf, "%d.%d C", battTemp / 10, abs(battTemp % 10));
|
||||
display.drawTextRightAlign(display.width()-1-EINK_X_OFFSET, y, buf);
|
||||
#endif
|
||||
} else if (_page == HomePage::SHUTDOWN) {
|
||||
}
|
||||
#if !defined(MECK_TWATCH)
|
||||
else if (_page == HomePage::SHUTDOWN) {
|
||||
display.setColor(DisplayDriver::GREEN);
|
||||
display.setTextSize(1);
|
||||
if (_shutdown_init) {
|
||||
@@ -1304,6 +1312,7 @@ public:
|
||||
display.drawTextCentered(display.width() / 2, y2, line2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return _editing_utc ? 700 : 5000;
|
||||
}
|
||||
|
||||
@@ -1342,6 +1351,7 @@ public:
|
||||
return true; // Consume all other keys while editing
|
||||
}
|
||||
|
||||
#if !defined(MECK_TWATCH)
|
||||
// SHUTDOWN page -- intercept up/down and Enter before page cycling
|
||||
if (_page == HomePage::SHUTDOWN) {
|
||||
if (_poweroff_confirm) {
|
||||
@@ -1376,6 +1386,7 @@ public:
|
||||
}
|
||||
// Left/right fall through to page cycling below
|
||||
}
|
||||
#endif
|
||||
|
||||
if (c == KEY_LEFT || c == KEY_PREV || c == 'a') {
|
||||
_page = (_page + HomePage::Count - 1) % HomePage::Count;
|
||||
@@ -2894,6 +2905,10 @@ if (curr) curr->poll();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Flush contacts before the battery dies -- the chunked lazy save may not
|
||||
// have run for hours. Blocking save (tmp-then-rename, brownout-safe).
|
||||
the_mesh.saveContacts();
|
||||
|
||||
shutdown();
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user