SettingsHandler now generate time window event
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user