From 4e53e7388fba3a2944cc70f643290d68babd661d Mon Sep 17 00:00:00 2001 From: Vitali Date: Fri, 17 Jul 2026 20:08:03 +0700 Subject: [PATCH] feat: persistent settings in LittleFS JSON Co-Authored-By: Claude Opus 4.8 --- WeatherPredictor/WeatherPredictor.ino | 9 +++++ WeatherPredictor/app_settings.cpp | 52 +++++++++++++++++++++++++++ WeatherPredictor/app_settings.h | 15 ++++++++ 3 files changed, 76 insertions(+) create mode 100644 WeatherPredictor/app_settings.cpp create mode 100644 WeatherPredictor/app_settings.h diff --git a/WeatherPredictor/WeatherPredictor.ino b/WeatherPredictor/WeatherPredictor.ino index 0a6d4af..1954855 100644 --- a/WeatherPredictor/WeatherPredictor.ino +++ b/WeatherPredictor/WeatherPredictor.ino @@ -6,6 +6,7 @@ #include "rtc_time.h" #include "forecast.h" #include "history.h" +#include "app_settings.h" static void i2cScan() { Serial.println(F("I2C scan:")); @@ -59,6 +60,14 @@ void setup() { historyCount(), d, classifyTrend(d)); else Serial.println(F("history: not enough data for trend")); + + // --- settings self-test (remove after Task 8) --- + settingsBegin(); + Serial.printf("settings: alt=%.0f tz=%d lat=%.4f lon=%.4f\n", + settings.altitudeM, settings.tzOffsetMin, settings.lat, settings.lon); + settings.altitudeM += 1.0f; // change and persist to test round-trip + settingsSave(); + Serial.println(F("settings: incremented altitude and saved")); } void loop() { diff --git a/WeatherPredictor/app_settings.cpp b/WeatherPredictor/app_settings.cpp new file mode 100644 index 0000000..537b48c --- /dev/null +++ b/WeatherPredictor/app_settings.cpp @@ -0,0 +1,52 @@ +#include +#include +#include "config.h" +#include "app_settings.h" + +AppSettings settings; +static const char* PATH = "/settings.json"; + +void settingsDefaults() { + settings.altitudeM = DEFAULT_ALTITUDE_M; + settings.tzOffsetMin = DEFAULT_TZ_OFFSET_MIN; + settings.lat = DEFAULT_LAT; + settings.lon = DEFAULT_LON; +} + +static bool settingsLoad() { + File f = LittleFS.open(PATH, "r"); + if (!f) return false; + JsonDocument doc; + DeserializationError err = deserializeJson(doc, f); + f.close(); + if (err) return false; + settings.altitudeM = doc["altitude"] | DEFAULT_ALTITUDE_M; + settings.tzOffsetMin = doc["tz"] | DEFAULT_TZ_OFFSET_MIN; + settings.lat = doc["lat"] | DEFAULT_LAT; + settings.lon = doc["lon"] | DEFAULT_LON; + return true; +} + +bool settingsSave() { + JsonDocument doc; + doc["altitude"] = settings.altitudeM; + doc["tz"] = settings.tzOffsetMin; + doc["lat"] = settings.lat; + doc["lon"] = settings.lon; + File f = LittleFS.open(PATH, "w"); + if (!f) return false; + serializeJson(doc, f); + f.close(); + return true; +} + +void settingsBegin() { + if (!LittleFS.begin()) { + LittleFS.format(); + LittleFS.begin(); + } + settingsDefaults(); + if (!settingsLoad()) { // first boot: persist defaults + settingsSave(); + } +} diff --git a/WeatherPredictor/app_settings.h b/WeatherPredictor/app_settings.h new file mode 100644 index 0000000..f7166ee --- /dev/null +++ b/WeatherPredictor/app_settings.h @@ -0,0 +1,15 @@ +#pragma once +#include + +struct AppSettings { + float altitudeM; + int tzOffsetMin; + float lat; + float lon; +}; + +extern AppSettings settings; + +void settingsBegin(); +bool settingsSave(); +void settingsDefaults();