From ff72f8d2ead0e068da58ff6f1d08e9fb605b6242 Mon Sep 17 00:00:00 2001 From: Tabascl Date: Mon, 24 Jul 2023 13:55:53 +0200 Subject: [PATCH] Add support for zero-fan mode, fix sensor identifiers --- app/include/fan/Fan.h | 3 ++ app/include/fan/HwmonFan.h | 8 ++++-- app/src/Serializer.cxx | 55 +++++++++++++++---------------------- app/src/fan/FanCurve.cxx | 25 ++++++----------- app/src/fan/HwmonFan.cxx | 14 ++++++---- app/src/sensor/LMSensor.cxx | 6 +++- 6 files changed, 53 insertions(+), 58 deletions(-) diff --git a/app/include/fan/Fan.h b/app/include/fan/Fan.h index 15611e3..aada056 100644 --- a/app/include/fan/Fan.h +++ b/app/include/fan/Fan.h @@ -17,6 +17,9 @@ public: virtual void StartPWM(int value) = 0; virtual int StartPWM() = 0; + virtual void ZeroFanModeSupported(bool value) = 0; + virtual bool ZeroFanModeSupported() = 0; + virtual void FindPWMLimits() = 0; virtual void AdjustPWMLimits() = 0; }; diff --git a/app/include/fan/HwmonFan.h b/app/include/fan/HwmonFan.h index db85b9a..94f125e 100644 --- a/app/include/fan/HwmonFan.h +++ b/app/include/fan/HwmonFan.h @@ -24,6 +24,9 @@ public: void StartPWM(int value) override; int StartPWM() override; + void ZeroFanModeSupported(bool value) override; + bool ZeroFanModeSupported() override; + void FindPWMLimits() override; void AdjustPWMLimits() override; @@ -36,8 +39,9 @@ private: std::shared_ptr mRpmSensor; std::string mLabel; - int mMinPWM; - int mStartPWM; + int mMinPWM = 0; + int mStartPWM = 0; + bool mZeroFanModeSupported = false; std::chrono::time_point mLastAdjustmentTime; }; diff --git a/app/src/Serializer.cxx b/app/src/Serializer.cxx index 9c18384..7904ad7 100644 --- a/app/src/Serializer.cxx +++ b/app/src/Serializer.cxx @@ -13,16 +13,13 @@ using namespace std; namespace fs = filesystem; -Serializer::Serializer() -{ +Serializer::Serializer() { if (!fs::exists(SERIALIZATION_DIR)) { fs::create_directory(SERIALIZATION_DIR); } } -void -Serializer::SerializeFans(vector> fans) -{ +void Serializer::SerializeFans(vector> fans) { json obj; for (auto f : fans) { @@ -33,8 +30,7 @@ Serializer::SerializeFans(vector> fans) } vector> -Serializer::DeserializeFans(vector> availableSensors) -{ +Serializer::DeserializeFans(vector> availableSensors) { vector> fans; // Create a for the sensors first, then searching becomes cheaper @@ -45,37 +41,37 @@ Serializer::DeserializeFans(vector> availableSensors) auto data = ReadJson(); try { - for (auto& el : data["fans"].items()) { + for (auto &el : data["fans"].items()) { auto pwmControl = make_shared(el.value()["PWMControl"]); auto rpmSensor = sensorMap[el.value()["LMSensor"]]; int minPWM = el.value()["MinPWM"]; int startPWM = el.value()["StartPWM"]; string label = el.value()["Label"]; + bool zeroFan = el.value()["ZeroFan"]; auto fan = make_shared(pwmControl, rpmSensor); fan->MinPWM(minPWM); fan->StartPWM(startPWM); fan->Label(label); + fan->ZeroFanModeSupported(zeroFan); fans.push_back(fan); } - } catch (const std::exception& e) { + } catch (const std::exception &e) { std::cout << "Deserialization error! Message: " << e.what() << std::endl; } return fans; } -void -Serializer::WriteJson(json o) -{ +void Serializer::WriteJson(json o) { json obj; if (fs::exists(fs::path(SERIALIZATION_DIR) / FANS_JSON_FILENAME)) { obj = ReadJson(); } - for (auto& [key, value] : o.items()) { + for (auto &[key, value] : o.items()) { obj[key] = value; } @@ -83,18 +79,14 @@ Serializer::WriteJson(json o) ostrm << obj.dump(2) << "\n"; } -json -Serializer::ReadJson() -{ +json Serializer::ReadJson() { ifstream istrm(fs::path(SERIALIZATION_DIR) / FANS_JSON_FILENAME); return json::parse(istrm); } -vector> -Serializer::DeserializeFanCurves( - std::vector> availableSensors, - std::vector> availableFans) -{ +vector> Serializer::DeserializeFanCurves( + std::vector> availableSensors, + std::vector> availableFans) { auto data = ReadJson(); map> sensorMap; @@ -109,47 +101,44 @@ Serializer::DeserializeFanCurves( vector> curves; - for (auto& el : data["fancurves"].items()) { + for (auto &el : data["fancurves"].items()) { vector steps; vector> sensors; vector> fans; - for (auto& step : el.value()["FanSteps"].items()) { - steps.push_back(FanStep{ step.value()[0], step.value()[1] }); + for (auto &step : el.value()["FanSteps"].items()) { + steps.push_back(FanStep{step.value()[0], step.value()[1]}); } - for (auto& sensor : el.value()["Sensors"].items()) { + for (auto &sensor : el.value()["Sensors"].items()) { if (sensorMap.contains(sensor.value())) sensors.push_back(sensorMap[sensor.value()]); } - for (auto& fan : el.value()["Fans"].items()) { + for (auto &fan : el.value()["Fans"].items()) { if (fanMap.contains(fan.value())) fans.push_back(fanMap[fan.value()]); } std::unique_ptr aggregator = - aggregatorFromString(el.value()["AggregateFunction"]); + aggregatorFromString(el.value()["AggregateFunction"]); curves.push_back( - make_shared(steps, sensors, fans, std::move(aggregator))); + make_shared(steps, sensors, fans, std::move(aggregator))); } return curves; } std::unique_ptr -Serializer::aggregatorFromString(std::string str) const -{ +Serializer::aggregatorFromString(std::string str) const { if (str == "max") return std::make_unique(); else return std::make_unique(); } -shared_ptr -Serializer::DeserializeSettings() -{ +shared_ptr Serializer::DeserializeSettings() { int frequency = FREQUENCY_DEFAULT; auto data = ReadJson(); diff --git a/app/src/fan/FanCurve.cxx b/app/src/fan/FanCurve.cxx index 70ad8f2..54a6a96 100644 --- a/app/src/fan/FanCurve.cxx +++ b/app/src/fan/FanCurve.cxx @@ -12,22 +12,17 @@ FanCurve::FanCurve(std::vector steps, std::vector> sensors, std::vector> fans, std::unique_ptr aggregator) - : mSteps(steps) - , mTempSensors(sensors) - , mFans(fans) - , mAggregator(std::move(aggregator)) -{ + : mSteps(steps), mTempSensors(sensors), mFans(fans), + mAggregator(std::move(aggregator)) { PrintInfo(); } -void -FanCurve::DoFanControl() -{ +void FanCurve::DoFanControl() { BOOST_LOG_FUNCTION(); int temp = AggregateTemperature(); - int t0, t1, p0, p1; + int t0 = 0, t1 = 0, p0 = 0, p1 = 0; int targetFanPower; if (temp <= mSteps[0].Temp) { @@ -35,7 +30,7 @@ FanCurve::DoFanControl() } else if (temp > mSteps[mSteps.size() - 1].Temp) { targetFanPower = mSteps[mSteps.size() - 1].Percent; } else { - for (int i = 0; i < mSteps.size(); i++) { + for (int i = 0; i < (int)mSteps.size(); i++) { if (temp > mSteps[i].Temp) { t0 = mSteps[i].Temp; p0 = mSteps[i].Percent; @@ -49,7 +44,7 @@ FanCurve::DoFanControl() } for (auto f : mFans) { - if (f->RPM() <= 0) { + if (!f->ZeroFanModeSupported() && f->RPM() <= 0) { BOOST_LOG_TRIVIAL(warning) << "Fan stopped completely!"; f->PWM(f->StartPWM()); f->AdjustPWMLimits(); @@ -59,15 +54,11 @@ FanCurve::DoFanControl() } } -int -FanCurve::AggregateTemperature() -{ +int FanCurve::AggregateTemperature() { return mAggregator->aggregate(mTempSensors); } -void -FanCurve::PrintInfo() -{ +void FanCurve::PrintInfo() { BOOST_LOG_FUNCTION() BOOST_LOG_TRIVIAL(info) << "### Fan curve:"; diff --git a/app/src/fan/HwmonFan.cxx b/app/src/fan/HwmonFan.cxx index 254aa7a..402e818 100644 --- a/app/src/fan/HwmonFan.cxx +++ b/app/src/fan/HwmonFan.cxx @@ -39,6 +39,12 @@ void HwmonFan::StartPWM(int value) { mStartPWM = value; } int HwmonFan::StartPWM() { return mStartPWM; } +void HwmonFan::ZeroFanModeSupported(bool value) { + mZeroFanModeSupported = value; +} + +bool HwmonFan::ZeroFanModeSupported() { return mZeroFanModeSupported; } + void HwmonFan::FindPWMLimits() { cout << "Looking for minimal PWM" << endl; int minPWM = 0; @@ -95,11 +101,9 @@ void HwmonFan::AdjustPWMLimits() { json HwmonFan::toJson() const { json obj; - obj = {mPWMControl->toJson(), - mRpmSensor->toJson(), - {"Label", mLabel}, - {"MinPWM", mMinPWM}, - {"StartPWM", mStartPWM}}; + obj = {mPWMControl->toJson(), mRpmSensor->toJson(), + {"Label", mLabel}, {"MinPWM", mMinPWM}, + {"StartPWM", mStartPWM}, {"ZeroFan", mZeroFanModeSupported}}; return obj; } diff --git a/app/src/sensor/LMSensor.cxx b/app/src/sensor/LMSensor.cxx index c336cf3..c7e1de1 100644 --- a/app/src/sensor/LMSensor.cxx +++ b/app/src/sensor/LMSensor.cxx @@ -1,3 +1,5 @@ +#include + #include #include #include @@ -17,7 +19,9 @@ int LMSensor::value() { } const string LMSensor::toString() const { - return sensors_get_label(mChipName, mFeature); + ostringstream os; + os << mChipName->prefix << "." << sensors_get_label(mChipName, mFeature); + return os.str(); } json LMSensor::toJson() const {