From 39ec9eec5e15af37bdb45352b72245e871e9d63a Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Wed, 29 Jul 2026 08:54:29 +0200 Subject: [PATCH] SettingsHandler now generate time window event --- CMakeLists.txt | 1 - src/device/handlers/Average.cpp | 70 --------------------- src/device/handlers/Average.h | 49 --------------- src/device/handlers/PressureCalculator.cpp | 71 +++++++++++++++++++++- src/device/handlers/PressureCalculator.h | 41 ++++++++++++- src/device/handlers/SettingsHandler.cpp | 14 +++++ src/device/handlers/SettingsHandler.h | 14 +++-- 7 files changed, 132 insertions(+), 128 deletions(-) delete mode 100644 src/device/handlers/Average.cpp delete mode 100644 src/device/handlers/Average.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3da4b68..f2e32f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,6 @@ add_library( src/device/handlers/PressureCalculator.cpp src/device/handlers/FeedbackHandler.cpp src/device/handlers/OutputHandler.cpp - src/device/handlers/Average.cpp ) set_property( diff --git a/src/device/handlers/Average.cpp b/src/device/handlers/Average.cpp deleted file mode 100644 index 434d04e..0000000 --- a/src/device/handlers/Average.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include - -#include "Average.h" - -void Average::setWindowSize(double seconds) { - windowSize = Duration(seconds); - cleanupAndUpdate(Clock::now()); -} - -void Average::addValue(double value) { - TimePoint now = Clock::now(); - currentValue = value; - - // add a new value - history.push_back({now, currentValue}); - - cleanupAndUpdate(now); -} - -double Average::getAverage() { - TimePoint now = Clock::now(); - cleanupAndUpdate(now); - - if (history.empty()) { - return currentValue; - } - - double totalWeightedValue = 0.0; - double totalDurationSeconds = 0.0; - - TimePoint windowStart = - now - std::chrono::duration_cast(windowSize); - - for (size_t i = 0; i < history.size(); ++i) { - TimePoint segmentStart = (i == 0) ? windowStart : history[i].timestamp; - TimePoint segmentEnd = - (i < history.size() - 1) ? history[i + 1].timestamp : now; - - // remove time before the window - if (segmentEnd < windowStart) - continue; - if (segmentStart < windowStart) - segmentStart = windowStart; - - Duration duration = segmentEnd - segmentStart; - double seconds = duration.count(); - - if (seconds > 0.0) { - totalWeightedValue += history[i].value * seconds; - totalDurationSeconds += seconds; - } - } - - if (totalDurationSeconds <= 0.0) { - return history.back().value; - } - - return totalWeightedValue / totalDurationSeconds; -} - -void Average::cleanupAndUpdate(TimePoint now) { - TimePoint windowStart = - now - std::chrono::duration_cast(windowSize); - - // Remove all elements completely outside of the window - while (history.size() > 1 && history[1].timestamp <= windowStart) { - history.pop_front(); - } -} \ No newline at end of file diff --git a/src/device/handlers/Average.h b/src/device/handlers/Average.h deleted file mode 100644 index c995ff8..0000000 --- a/src/device/handlers/Average.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef AVERAGE_H -#define AVERAGE_H - -#include -#include - -/* - This class allows you to compute the average value inside a given time window. - It computes the average using continuous time. -*/ -class Average { - private: - using Clock = std::chrono::steady_clock; - using TimePoint = Clock::time_point; - using Duration = std::chrono::duration; - - struct TimeValue { - TimePoint timestamp; - double value; - }; - - std::deque history; - Duration windowSize; - double currentValue = 0.0; - - void cleanupAndUpdate(TimePoint now); - - public: - Average(double windowSizeSeconds) - : windowSize(Duration(windowSizeSeconds)) {}; - - /* - @brief Modify the time window size - @param seconds time window duration - */ - void setWindowSize(double seconds); - /* - @brief Add another value with the current timestamp to the average. - */ - void addValue(double value); - /* - @brief Get the current average of all the values from [now - timewindow, - now]. - @return The average value - */ - double getAverage(); -}; - -#endif \ No newline at end of file diff --git a/src/device/handlers/PressureCalculator.cpp b/src/device/handlers/PressureCalculator.cpp index d06e8e9..fae384a 100644 --- a/src/device/handlers/PressureCalculator.cpp +++ b/src/device/handlers/PressureCalculator.cpp @@ -1,6 +1,5 @@ #include "PressureCalculator.h" #include "../itc_pressure_optimizer.h" -#include "Average.h" #include "DemandHandler.h" #include "InputHandler.h" #include "tmfe.h" @@ -118,3 +117,73 @@ void PressureCalculator::updateConstant2(float value) { cachedConstant2 = value; update(); } + +// ######################################## +// Average inner class +// ######################################## + +void PressureCalculator::Average::setWindowSize(double seconds) { + windowSize = Duration(seconds); + cleanupAndUpdate(Clock::now()); +} + +void PressureCalculator::Average::addValue(double value) { + TimePoint now = Clock::now(); + currentValue = value; + + // add a new value + history.push_back({now, currentValue}); + + cleanupAndUpdate(now); +} + +double PressureCalculator::Average::getAverage() { + TimePoint now = Clock::now(); + cleanupAndUpdate(now); + + if (history.empty()) { + return currentValue; + } + + double totalWeightedValue = 0.0; + double totalDurationSeconds = 0.0; + + TimePoint windowStart = + now - std::chrono::duration_cast(windowSize); + + for (size_t i = 0; i < history.size(); ++i) { + TimePoint segmentStart = (i == 0) ? windowStart : history[i].timestamp; + TimePoint segmentEnd = + (i < history.size() - 1) ? history[i + 1].timestamp : now; + + // remove time before the window + if (segmentEnd < windowStart) + continue; + if (segmentStart < windowStart) + segmentStart = windowStart; + + Duration duration = segmentEnd - segmentStart; + double seconds = duration.count(); + + if (seconds > 0.0) { + totalWeightedValue += history[i].value * seconds; + totalDurationSeconds += seconds; + } + } + + if (totalDurationSeconds <= 0.0) { + return history.back().value; + } + + return totalWeightedValue / totalDurationSeconds; +} + +void PressureCalculator::Average::cleanupAndUpdate(TimePoint now) { + TimePoint windowStart = + now - std::chrono::duration_cast(windowSize); + + // Remove all elements completely outside of the window + while (history.size() > 1 && history[1].timestamp <= windowStart) { + history.pop_front(); + } +} \ No newline at end of file diff --git a/src/device/handlers/PressureCalculator.h b/src/device/handlers/PressureCalculator.h index 3a4e835..d144be3 100644 --- a/src/device/handlers/PressureCalculator.h +++ b/src/device/handlers/PressureCalculator.h @@ -2,7 +2,8 @@ #define PRESSURE_CALCULATOR_H #include "../EventBus.h" -#include "Average.h" +#include +#include class PressureCalculator { public: @@ -17,6 +18,44 @@ class PressureCalculator { }; private: + class Average { + private: + using Clock = std::chrono::steady_clock; + using TimePoint = Clock::time_point; + using Duration = std::chrono::duration; + + struct TimeValue { + TimePoint timestamp; + double value; + }; + + std::deque history; + Duration windowSize; + double currentValue = 0.0; + + void cleanupAndUpdate(TimePoint now); + + public: + Average(double windowSizeSeconds) + : windowSize(Duration(windowSizeSeconds)) {}; + + /* + @brief Modify the time window size + @param seconds time window duration + */ + void setWindowSize(double seconds); + /* + @brief Add another value with the current timestamp to the average. + */ + void addValue(double value); + /* + @brief Get the current average of all the values from [now - + timewindow, now]. + @return The average value + */ + double getAverage(); + }; + Average average; EventBus &eventBus; diff --git a/src/device/handlers/SettingsHandler.cpp b/src/device/handlers/SettingsHandler.cpp index 3312478..79daada 100644 --- a/src/device/handlers/SettingsHandler.cpp +++ b/src/device/handlers/SettingsHandler.cpp @@ -41,6 +41,13 @@ void SettingsHandler::pullInputPowerIndex() { eventBus.publish(event); } +void SettingsHandler::pullAverageTimeWindow() { + midas::odb o(this->path); + float average_time_window = o[SettingsHandlerConfig::TIME_WINDOW]; + Event event = {EventType::AVERAGE_TIME_WINDOW, average_time_window}; + eventBus.publish(event); +} + SettingsHandler::SettingsHandler(EventBus &eventBusReference, std::string equipmentName) : path(SettingsHandlerConfig::PATH_PREFIX + equipmentName + @@ -89,6 +96,12 @@ bool SettingsHandler::init() { SettingsHandlerConfig::INPUT_POWER_INDEX.c_str()); areKeysValids = false; } + if (!midas::odb::exists(path + SettingsHandlerConfig::TIME_WINDOW)) { + TMFE::Instance()->Msg(MERROR, __FUNCTION__, + "Key at %s%s doesn't exists", path.c_str(), + SettingsHandlerConfig::TIME_WINDOW.c_str()); + areKeysValids = false; + } if (!areKeysValids) { midas::odb o = { @@ -120,5 +133,6 @@ bool SettingsHandler::init() { this->pullInputSPIndex(); this->pullInputTemperatureIndex(); this->pullInputPowerIndex(); + pullAverageTimeWindow(); return true; } diff --git a/src/device/handlers/SettingsHandler.h b/src/device/handlers/SettingsHandler.h index 4733802..17dafe3 100644 --- a/src/device/handlers/SettingsHandler.h +++ b/src/device/handlers/SettingsHandler.h @@ -11,16 +11,17 @@ class SettingsHandler { SettingsHandler(EventBus &eventBusReference, std::string equipmentName); enum class EventType { - EQUIPMENT_NAME, - OUTPUT_PRESSURE_SP_INDEX, - INPUT_SP_INDEX, - INPUT_TEMPERATURE_INDEX, - INPUT_POWER_INDEX + EQUIPMENT_NAME, // type string + OUTPUT_PRESSURE_SP_INDEX, // type int + INPUT_SP_INDEX, // type int + INPUT_TEMPERATURE_INDEX, // type int + INPUT_POWER_INDEX, // type int + AVERAGE_TIME_WINDOW // type float }; struct Event { EventType type; - std::variant value; + std::variant value; }; private: @@ -40,6 +41,7 @@ class SettingsHandler { void pullInputSPIndex(); void pullInputTemperatureIndex(); void pullInputPowerIndex(); + void pullAverageTimeWindow(); }; #endif \ No newline at end of file