Hysteresis, Inhibit-Stop Timeframe

This commit is contained in:
2023-08-28 14:55:07 +02:00
parent d1649b7de1
commit 0a6bab36be
17 changed files with 198 additions and 73 deletions

View File

@@ -1,6 +1,6 @@
#include <boost/log/attributes/named_scope.hpp>
#include <iostream>
#include <boost/log/attributes/named_scope.hpp>
#include <boost/log/trivial.hpp>
#include <fan/FanCurve.h>
@@ -11,14 +11,23 @@ using namespace std;
FanCurve::FanCurve(std::vector<FanStep> steps,
std::vector<std::shared_ptr<Sensor>> sensors,
std::vector<std::shared_ptr<Fan>> fans,
std::unique_ptr<Aggregator> aggregator)
std::unique_ptr<Aggregator> aggregator, int hysteresis)
: mSteps(steps), mTempSensors(sensors), mFans(fans),
mAggregator(std::move(aggregator)) {
mAggregator(std::move(aggregator)), mHystersis(hysteresis),
mLastTemperature(INT_MIN) {
PrintInfo();
}
void FanCurve::DoFanControl() {
BOOST_LOG_FUNCTION();
BOOST_LOG_FUNCTION()
BOOST_LOG_TRIVIAL(trace) << "## Fans in curve";
for (auto f : mFans)
BOOST_LOG_TRIVIAL(trace) << f->toString();
BOOST_LOG_TRIVIAL(trace) << "## Sensors in curve";
for (auto s : mTempSensors)
BOOST_LOG_TRIVIAL(trace) << s->toString();
int temp = AggregateTemperature();
@@ -43,14 +52,22 @@ void FanCurve::DoFanControl() {
targetFanPower = p0 + ((p1 - p0) / (t1 - t0)) * (temp - t0);
}
for (auto f : mFans) {
if (!f->ZeroFanModeSupported() && f->RPM() <= 0) {
BOOST_LOG_TRIVIAL(warning) << "Fan stopped completely!";
f->PWM(f->StartPWM());
f->AdjustPWMLimits();
} else {
f->PWM(targetFanPower);
BOOST_LOG_TRIVIAL(trace) << "Current temp: " << temp;
BOOST_LOG_TRIVIAL(trace) << "Last temp: " << mLastTemperature;
BOOST_LOG_TRIVIAL(trace) << "# Hysteresis check";
if (ExceedsHysteresis(temp)) {
BOOST_LOG_TRIVIAL(trace) << "passed";
for (auto f : mFans) {
ApplyFanPower(f, targetFanPower);
mLastTemperature = temp;
}
} else {
for (auto f : mFans)
f->EnforceSetValue();
BOOST_LOG_TRIVIAL(trace) << "not passed";
}
}
@@ -94,3 +111,22 @@ void FanCurve::PrintInfo() {
BOOST_LOG_TRIVIAL(info) << sStream.str();
}
bool FanCurve::ExceedsHysteresis(int temperature) {
int lowThreshold = mLastTemperature - mHystersis;
int highThreshold = mLastTemperature + mHystersis;
return temperature <= lowThreshold || temperature >= highThreshold;
}
void FanCurve::ApplyFanPower(std::shared_ptr<Fan> fan, int targetFanPower) {
BOOST_LOG_FUNCTION();
if (!fan->ZeroFanModeSupported() && fan->RPM() <= 0) {
BOOST_LOG_TRIVIAL(warning) << "Fan stopped completely!";
fan->PWM(fan->StartPWM());
fan->AdjustPWMLimits();
} else {
fan->PWM(targetFanPower);
}
}

View File

@@ -16,7 +16,7 @@ void FanLabeler::RunFanLabelInteraction(
cout << endl;
for (auto f : fans) {
cout << "Setting fan to max power" << endl;
cout << "Setting fan " << f->toString() << " to max power" << endl;
f->PWM(100);

View File

@@ -1,3 +1,4 @@
#include <chrono>
#include <iostream>
#include <ostream>
#include <thread>
@@ -9,6 +10,7 @@
#include <pwm/PWMControl.h>
#define TIMEOUT 10
#define INHIBIT_STOP_PERIOD 120
#define STEP 2
using namespace std;
@@ -21,12 +23,40 @@ HwmonFan::HwmonFan(std::shared_ptr<PWMControl> pwmControl,
void HwmonFan::PWM(int percent) {
if (percent < mMinPWM) {
mPWMControl->Power(mMinPWM);
if (mZeroFanModeSupported && InhibitStopPeriodExpired()) {
SetPower(percent);
mWasStopped = true;
} else {
SetPower(mMinPWM);
}
} else {
mPWMControl->Power(percent);
if (mWasStopped) {
mWasStopped = false;
mLastStartTime = chrono::steady_clock::now();
SetPower(mStartPWM);
} else {
SetPower(percent);
}
}
}
bool HwmonFan::InhibitStopPeriodExpired() {
BOOST_LOG_FUNCTION();
auto result = chrono::steady_clock::now() - mLastStartTime >
chrono::duration(chrono::seconds(INHIBIT_STOP_PERIOD));
BOOST_LOG_TRIVIAL(trace) << "Inhibit-Stop period expired:"
<< (result ? "true" : "false");
return result;
}
void HwmonFan::SetPower(int percent) {
mPWMControl->Power(percent);
mSetValue = percent;
}
int HwmonFan::RPM() { return mRpmSensor->value(); }
void HwmonFan::Label(std::string label) { mLabel = label; }
@@ -99,6 +129,8 @@ void HwmonFan::AdjustPWMLimits() {
}
}
void HwmonFan::EnforceSetValue() { mPWMControl->Power(mSetValue); }
json HwmonFan::toJson() const {
json obj;
obj = {mPWMControl->toJson(), mRpmSensor->toJson(),
@@ -111,6 +143,6 @@ const string HwmonFan::toString() const {
if (!mLabel.empty()) {
return mLabel;
} else {
return "fan:" + mPWMControl->toString();
return mPWMControl->toString();
}
}