chore: make repo an Arduino collection with WeatherPredictor project
Flatten so the repo root is the Arduino sketchbook; the project lives in WeatherPredictor/. Add a collection index README at the root and move the detailed project README into WeatherPredictor/. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
#include <LittleFS.h>
|
||||
#include "config.h"
|
||||
#include "history.h"
|
||||
|
||||
static Sample s_buf[HISTORY_SIZE];
|
||||
static int s_head = 0; // next write position
|
||||
static int s_count = 0;
|
||||
|
||||
void historyBegin() { s_head = 0; s_count = 0; }
|
||||
|
||||
void historyAdd(uint32_t epoch, float mslHpa, float tempC) {
|
||||
s_buf[s_head] = Sample{ epoch, mslHpa, tempC };
|
||||
s_head = (s_head + 1) % HISTORY_SIZE;
|
||||
if (s_count < HISTORY_SIZE) s_count++;
|
||||
}
|
||||
|
||||
int historyCount() { return s_count; }
|
||||
|
||||
Sample historyGet(int i) {
|
||||
int start = (s_head - s_count + HISTORY_SIZE) % HISTORY_SIZE;
|
||||
return s_buf[(start + i) % HISTORY_SIZE];
|
||||
}
|
||||
|
||||
Sample historyLatest() { return historyGet(s_count - 1); }
|
||||
|
||||
bool historyTrendDelta(float& outDelta) {
|
||||
if (s_count < 2) return false;
|
||||
Sample latest = historyLatest();
|
||||
if (latest.epoch < 10800UL) return false;
|
||||
uint32_t target = latest.epoch - 10800UL; // 3 h earlier
|
||||
// Pick the newest sample at or before `target`. Scan all samples (do not
|
||||
// assume epochs are strictly increasing: an NTP correction can shift them).
|
||||
int idx = -1;
|
||||
uint32_t bestEpoch = 0;
|
||||
for (int i = 0; i < s_count; i++) {
|
||||
Sample s = historyGet(i);
|
||||
if (s.epoch <= target && s.epoch >= bestEpoch) { bestEpoch = s.epoch; idx = i; }
|
||||
}
|
||||
if (idx < 0) return false;
|
||||
Sample past = historyGet(idx);
|
||||
if (latest.epoch - past.epoch < 9000UL) return false; // need >= 2.5 h span
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user