feat(nav): WaypointStore — persistent /waypoints table

Phase 3. Fixed 16-entry table of (lat, lon, ts, label[12]) persisted to
/waypoints with a magic+version header (mirrors TrailStore's format).
Unlike the RAM-only trail, waypoints are loaded in UITask::begin() and
rewritten on change via UITask::saveWaypoints(), so they survive reboots.

add/remove/rename/clear operate on the in-RAM table; the screen layer
(phase 5) drives persistence after each edit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-06-03 08:23:11 +02:00
co-authored by Claude Opus 4.8
parent 11c0b7c4a5
commit b1dfde5fcb
3 changed files with 126 additions and 0 deletions
@@ -1160,6 +1160,15 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
ui_started_at = millis();
_alert_expiry = 0;
_batt_mv = AbstractUITask::getBattMilliVolts(); // seed EMA with first reading
// Load persisted waypoints (table survives reboots, unlike the RAM trail).
{
DataStore* ds = the_mesh.getDataStore();
if (ds) {
File f = ds->openRead("/waypoints");
if (f) { _waypoints.readFrom(f); f.close(); }
}
}
// Initialize ping state
_ping_active = false;
@@ -1962,6 +1971,15 @@ bool UITask::currentCourse(int& deg_out) const {
return true;
}
void UITask::saveWaypoints() {
DataStore* ds = the_mesh.getDataStore();
if (!ds) return;
File f = ds->openWrite("/waypoints");
if (!f) return;
_waypoints.writeTo(f);
f.close();
}
char UITask::checkDisplayOn(char c) {
if (_display != NULL) {
if (!_display->isOn()) {