From 77d0a35d6937f87f88dcff67c8c52087760a41df Mon Sep 17 00:00:00 2001 From: Vitali Date: Fri, 17 Jul 2026 20:31:53 +0700 Subject: [PATCH] feat: persist pressure history to LittleFS across reboots Co-Authored-By: Claude Opus 4.8 --- WeatherPredictor/WeatherPredictor.ino | 11 ++++++++- WeatherPredictor/history.cpp | 33 +++++++++++++++++++++++++++ WeatherPredictor/history.h | 2 ++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/WeatherPredictor/WeatherPredictor.ino b/WeatherPredictor/WeatherPredictor.ino index 2ec88ca..238adb4 100644 --- a/WeatherPredictor/WeatherPredictor.ino +++ b/WeatherPredictor/WeatherPredictor.ino @@ -13,6 +13,7 @@ AppState g_state; static unsigned long tSample = 0; static unsigned long tHistory = 0; +static unsigned long tFlush = 0; static void sampleNow() { g_state.now = rtcNow(); @@ -47,12 +48,14 @@ void setup() { } settingsBegin(); historyBegin(); + historyLoad(); // restore prior samples (empty on first ever boot) + Serial.printf("history restored: %d samples\n", historyCount()); // Seed first sample immediately. sampleNow(); historyAdd(rtcEpoch(), g_state.mslHpa, g_state.tempC); displayRender(g_state); - tSample = tHistory = millis(); + tSample = tHistory = tFlush = millis(); } void loop() { @@ -68,4 +71,10 @@ void loop() { tHistory = now; historyAdd(rtcEpoch(), g_state.mslHpa, g_state.tempC); } + + if (now - tFlush >= FLUSH_INTERVAL_MS) { + tFlush = now; + historySave(); + Serial.printf("history flushed: %d samples\n", historyCount()); + } } diff --git a/WeatherPredictor/history.cpp b/WeatherPredictor/history.cpp index 440c28e..0df389d 100644 --- a/WeatherPredictor/history.cpp +++ b/WeatherPredictor/history.cpp @@ -1,3 +1,4 @@ +#include #include "config.h" #include "history.h" @@ -36,3 +37,35 @@ bool historyTrendDelta(float& outDelta) { outDelta = latest.mslHpa - past.mslHpa; return true; } + +static const char* HPATH = "/history.dat"; + +// Binary format: [int32 count][count * Sample], stored oldest-first. +bool historySave() { + File f = LittleFS.open(HPATH, "w"); + if (!f) return false; + int32_t n = s_count; + f.write((const uint8_t*)&n, sizeof(n)); + for (int i = 0; i < s_count; i++) { + Sample s = historyGet(i); + f.write((const uint8_t*)&s, sizeof(s)); + } + f.close(); + return true; +} + +bool historyLoad() { + File f = LittleFS.open(HPATH, "r"); + if (!f) return false; + int32_t n = 0; + if (f.read((uint8_t*)&n, sizeof(n)) != sizeof(n)) { f.close(); return false; } + if (n < 0 || n > HISTORY_SIZE) { f.close(); return false; } + s_head = 0; s_count = 0; + for (int i = 0; i < n; i++) { + Sample s; + if (f.read((uint8_t*)&s, sizeof(s)) != sizeof(s)) break; + historyAdd(s.epoch, s.mslHpa, s.tempC); + } + f.close(); + return true; +} diff --git a/WeatherPredictor/history.h b/WeatherPredictor/history.h index f63b36b..8423a24 100644 --- a/WeatherPredictor/history.h +++ b/WeatherPredictor/history.h @@ -13,3 +13,5 @@ int historyCount(); Sample historyGet(int i); // 0 = oldest Sample historyLatest(); bool historyTrendDelta(float& outDeltaHpa); +bool historySave(); +bool historyLoad();