diff --git a/src/RainGauge.cpp b/src/RainGauge.cpp index 43e3b514..b7ad831d 100644 --- a/src/RainGauge.cpp +++ b/src/RainGauge.cpp @@ -37,6 +37,7 @@ // History: // // 20220830 Created +// 20230716 Implemented sensor startup handling // // ToDo: // - @@ -71,6 +72,10 @@ typedef struct { uint8_t head; uint8_t tail; + /* Sensor startup handling */ + bool startupPrev; // previous state of startup + float rainStartup; // rain gauge before startup + /* Rainfall of current day (can start anytime, but will reset on begin of new day) */ uint8_t tsDayBegin; // day of week float rainDayBegin; // rain gauge @ begin of day @@ -94,6 +99,8 @@ RTC_DATA_ATTR nvData_t nvData = { .rainBuf = {0}, .head = 0, .tail = 0, + .startupPrev = false, + .rainStartup = 0, .tsDayBegin = 0xFF, .rainDayBegin = 0, .tsWeekBegin = 0xFF, @@ -172,6 +179,8 @@ RainGauge::printCircularBuffer(void) void RainGauge::reset(void) { + nvData.startupPrev = false; + nvData.rainStartup = 0; nvData.tsDayBegin = 0xFF; nvData.rainDayBegin = 0; nvData.tsWeekBegin = 0xFF; @@ -222,19 +231,27 @@ RainGauge::timeStamp(tm t) } void -RainGauge::update(tm t, float rain, float raingaugeMax) +RainGauge::update(tm t, float rain, bool startup, float raingaugeMax) { uint8_t head_tmp; // circular buffer; temporary head index // Seconds since Midnight uint32_t ts = timeStamp(t); - + if (rain < nvData.rainPrev) { - nvData.rainOvf++; + // Startup change 0->1 detected + if (!nvData.startupPrev && startup) { + // Save last rain value before startup + nvData.rainStartup = nvData.rainPrev; + } else { + nvData.rainOvf++; + } } + + nvData.startupPrev = startup; nvData.rainPrev = rain; - rainCurr = (nvData.rainOvf * raingaugeMax) + rain; + rainCurr = (nvData.rainOvf * raingaugeMax) + nvData.rainStartup + rain; // Check if no saved data is available yet if (nvData.wdayPrev == 0xFF) { diff --git a/src/RainGauge.h b/src/RainGauge.h index 5318779d..f92bf532 100644 --- a/src/RainGauge.h +++ b/src/RainGauge.h @@ -38,6 +38,7 @@ // // 20220830 Created // 20230330 Added changes for Adafruit Feather 32u4 LoRa Radio +// 20230716 Implemented sensor startup handling // // ToDo: // - @@ -111,9 +112,11 @@ class RainGauge { * * \param rain rain gauge raw value * + * \param startup sensor startup flag + * * \param rainGaugeMax overflow value; when reached, the rain gauge is reset to zero */ - void update(tm timeinfo, float rain, float raingaugeMax = RAINGAUGE_MAX_VALUE); + void update(tm timeinfo, float rain, bool startup = false, float raingaugeMax = RAINGAUGE_MAX_VALUE); /** diff --git a/test/makefiles/Makefile_Tests.mk b/test/makefiles/Makefile_Tests.mk index d537e1ae..89b62761 100644 --- a/test/makefiles/Makefile_Tests.mk +++ b/test/makefiles/Makefile_Tests.mk @@ -4,7 +4,8 @@ SRC_FILES = \ $(PROJECT_SRC_DIR)/RainGauge.cpp \ TEST_SRC_FILES = \ - $(UNITTEST_SRC_DIR)/TestRainGaugeReal.c #\ + $(UNITTEST_SRC_DIR)/TestRainGauge.c + #$(UNITTEST_SRC_DIR)/TestRainGaugeReal.c #\ #$(UNITTEST_SRC_DIR)/TestRainGauge.c include $(CPPUTEST_MAKFILE_INFRA) diff --git a/test/src/TestRainGauge.cpp b/test/src/TestRainGauge.cpp index 5beb5c1e..269070a4 100644 --- a/test/src/TestRainGauge.cpp +++ b/test/src/TestRainGauge.cpp @@ -183,6 +183,14 @@ TEST_GROUP(TestRainGaugeMonthlyOv) { } }; +TEST_GROUP(TestRainGaugeStartup) { + void setup() { + rainGauge.reset(); + } + + void teardown() { + } +}; /* * Test rainfall during past hour (no rain gauge overflow) @@ -1075,3 +1083,38 @@ TEST(TestRainGaugeMonthlyOv, Test_RainMonthlyOv) { } + +/* + * Test that rain gauge values are preserved after sensor startup, + * i.e. sensor reset or battery change + */ +TEST(TestRainGaugeStartup, TestRainStartup) { + tm tm; + time_t ts; + float rainSensor; + + printf("< RainStartup >\n"); + + setTime("2023-07-16 8:00:00", tm, ts); + DOUBLES_EQUAL(0, rainGauge.pastHour(), TOLERANCE); + DOUBLES_EQUAL(0, rainGauge.currentDay(), TOLERANCE); + DOUBLES_EQUAL(0, rainGauge.currentWeek(), TOLERANCE); + + setTime("2023-07-16 8:05:00", tm, ts); + rainGauge.update(tm, rainSensor = 10.0); + DOUBLES_EQUAL(0, rainGauge.pastHour(), TOLERANCE); + DOUBLES_EQUAL(0, rainGauge.currentDay(), TOLERANCE); + DOUBLES_EQUAL(0, rainGauge.currentWeek(), TOLERANCE); + + setTime("2023-07-16 8:10:00", tm, ts); + rainGauge.update(tm, rainSensor = 15.0); + DOUBLES_EQUAL(5, rainGauge.pastHour(), TOLERANCE); + DOUBLES_EQUAL(5, rainGauge.currentDay(), TOLERANCE); + DOUBLES_EQUAL(5, rainGauge.currentWeek(), TOLERANCE); + + setTime("2023-07-16 8:15:00", tm, ts); + rainGauge.update(tm, rainSensor = 0, true); + DOUBLES_EQUAL(5, rainGauge.pastHour(), TOLERANCE); + DOUBLES_EQUAL(5, rainGauge.currentDay(), TOLERANCE); + DOUBLES_EQUAL(5, rainGauge.currentWeek(), TOLERANCE); +}