#include #include #include "config.h" #include "sensors.h" #include "rtc_time.h" #include "display_ui.h" #include "forecast.h" #include "history.h" #include "flog.h" #include "app_settings.h" #include "net.h" #include "web_server.h" #include "state.h" 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(); g_state.absHpa = readAbsPressureHpa(); g_state.mslHpa = toSeaLevelHpa(g_state.absHpa, settings.altitudeM); g_state.tempC = readTemperatureC(); float d; g_state.haveTrend = historyTrendDelta(d); if (g_state.haveTrend) { g_state.trend = classifyTrend(d); g_state.forecast = computeForecast(g_state.mslHpa, g_state.trend, g_state.now.month); flogConsider(rtcEpoch(), g_state.forecast); // log only when the forecast changes } else { g_state.trend = TREND_STEADY; } } void setup() { Serial.begin(115200); delay(200); Serial.println(F("\n=== Weather Predictor ===")); Wire.begin(I2C_SDA, I2C_SCL); displayBegin(); displaySplash("Weather", "Predictor"); if (!sensorsBegin()) Serial.println(F("BMP180 not found!")); if (!rtcBegin()) Serial.println(F("DS3231 not found!")); if (rtcLostPower()) { Serial.println(F("RTC lost power -> temporary time set")); rtcSet(RtcTime{2026, 7, 17, 12, 0, 0}); } settingsBegin(); historyBegin(); historyLoad(); // restore prior samples (empty on first ever boot) Serial.printf("history restored: %d samples\n", historyCount()); flogBegin(); flogLoad(); // restore forecast change log Serial.printf("forecast log restored: %d entries\n", flogCount()); displaySplash("WiFi", "Connect / portal"); if (netBegin()) { Serial.printf("WiFi connected: %s\n", netIP().c_str()); if (ntpSync(settings.tzOffsetMin)) Serial.println(F("RTC synced from NTP")); else Serial.println(F("NTP sync failed")); } else { Serial.println(F("WiFi not connected - running offline")); } // Seed first sample immediately. sampleNow(); historyAdd(rtcEpoch(), g_state.mslHpa, g_state.tempC); displayRender(g_state); webBegin(); if (netConnected()) Serial.printf("Web UI: http://%s/\n", netIP().c_str()); tSample = tHistory = tFlush = millis(); } void loop() { webLoop(); unsigned long now = millis(); if (now - tSample >= SAMPLE_INTERVAL_MS) { tSample = now; sampleNow(); displayRender(g_state); } if (now - tHistory >= HISTORY_INTERVAL_MS) { 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()); } }