SettingsHandler now generate time window event

This commit is contained in:
2026-07-29 08:54:29 +02:00
parent 93807ade1d
commit 39ec9eec5e
7 changed files with 132 additions and 128 deletions
-1
View File
@@ -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(
-70
View File
@@ -1,70 +0,0 @@
#include <chrono>
#include <deque>
#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<Clock::duration>(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<Clock::duration>(windowSize);
// Remove all elements completely outside of the window
while (history.size() > 1 && history[1].timestamp <= windowStart) {
history.pop_front();
}
}
-49
View File
@@ -1,49 +0,0 @@
#ifndef AVERAGE_H
#define AVERAGE_H
#include <chrono>
#include <deque>
/*
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<double>;
struct TimeValue {
TimePoint timestamp;
double value;
};
std::deque<TimeValue> 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
+70 -1
View File
@@ -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<Clock::duration>(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<Clock::duration>(windowSize);
// Remove all elements completely outside of the window
while (history.size() > 1 && history[1].timestamp <= windowStart) {
history.pop_front();
}
}
+40 -1
View File
@@ -2,7 +2,8 @@
#define PRESSURE_CALCULATOR_H
#include "../EventBus.h"
#include "Average.h"
#include <chrono>
#include <deque>
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<double>;
struct TimeValue {
TimePoint timestamp;
double value;
};
std::deque<TimeValue> 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;
+14
View File
@@ -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;
}
+8 -6
View File
@@ -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<int, std::string> value;
std::variant<int, std::string, float> value;
};
private:
@@ -40,6 +41,7 @@ class SettingsHandler {
void pullInputSPIndex();
void pullInputTemperatureIndex();
void pullInputPowerIndex();
void pullAverageTimeWindow();
};
#endif