feat: in-RAM pressure history ring buffer with 3h trend
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
#include "sensors.h"
|
#include "sensors.h"
|
||||||
#include "rtc_time.h"
|
#include "rtc_time.h"
|
||||||
#include "forecast.h"
|
#include "forecast.h"
|
||||||
|
#include "history.h"
|
||||||
|
|
||||||
static void i2cScan() {
|
static void i2cScan() {
|
||||||
Serial.println(F("I2C scan:"));
|
Serial.println(F("I2C scan:"));
|
||||||
@@ -46,6 +47,18 @@ void setup() {
|
|||||||
Serial.printf("p=%.0f trend=%d -> %c [%s] (%s)\n",
|
Serial.printf("p=%.0f trend=%d -> %c [%s] (%s)\n",
|
||||||
c.p, c.tr, f.letter, f.text, categoryShort(f.category));
|
c.p, c.tr, f.letter, f.text, categoryShort(f.category));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- history self-test (remove after Task 8) ---
|
||||||
|
historyBegin();
|
||||||
|
uint32_t base = 1000000000UL;
|
||||||
|
for (int i = 0; i < 40; i++) // 40 samples @ 5 min = 3h20m, pressure falling
|
||||||
|
historyAdd(base + (uint32_t)i * 300, 1015.0f - i * 0.2f, 20.0f);
|
||||||
|
float d;
|
||||||
|
if (historyTrendDelta(d))
|
||||||
|
Serial.printf("history count=%d 3h delta=%.2f hPa trend=%d\n",
|
||||||
|
historyCount(), d, classifyTrend(d));
|
||||||
|
else
|
||||||
|
Serial.println(F("history: not enough data for trend"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#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();
|
||||||
|
uint32_t target = latest.epoch - 10800UL; // 3 h earlier
|
||||||
|
int idx = -1;
|
||||||
|
for (int i = 0; i < s_count; i++) {
|
||||||
|
if (historyGet(i).epoch <= target) idx = i; else break;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
struct Sample {
|
||||||
|
uint32_t epoch;
|
||||||
|
float mslHpa;
|
||||||
|
float tempC;
|
||||||
|
};
|
||||||
|
|
||||||
|
void historyBegin();
|
||||||
|
void historyAdd(uint32_t epoch, float mslHpa, float tempC);
|
||||||
|
int historyCount();
|
||||||
|
Sample historyGet(int i); // 0 = oldest
|
||||||
|
Sample historyLatest();
|
||||||
|
bool historyTrendDelta(float& outDeltaHpa);
|
||||||
Reference in New Issue
Block a user