From 78b2a626434b3f3f70ab15bfc60e0b4662857b2f Mon Sep 17 00:00:00 2001 From: Tabascl Date: Sun, 7 Jul 2024 22:19:27 +0200 Subject: [PATCH] Remove aggregator, fix changing HWMON paths Add logic to use actual device paths for the PWM sensors instead of their standart HWMON paths. This was done after noticing that due to the load order of kernel modules, the index of HWMON paths could change. --- app/include/fan/FanCurve.h | 1 - app/include/pwm/PWMControl.h | 4 +++- app/src/FanGenerator.cxx | 2 +- app/src/Serializer.cxx | 4 ++-- app/src/fan/FanCurve.cxx | 8 ++------ app/src/pwm/PWMControl.cxx | 26 +++++++++++++++++++------- app/src/pwm/PWMControlFacade.cxx | 13 ++++++++++--- 7 files changed, 37 insertions(+), 21 deletions(-) diff --git a/app/include/fan/FanCurve.h b/app/include/fan/FanCurve.h index 6d5ca6b..6445371 100644 --- a/app/include/fan/FanCurve.h +++ b/app/include/fan/FanCurve.h @@ -23,7 +23,6 @@ public: void DoFanControl(); private: - int AggregateTemperature(); void PrintInfo(); bool ExceedsHysteresis(int temperature); void ApplyFanPower(std::shared_ptr fan, int targetFanPower); diff --git a/app/include/pwm/PWMControl.h b/app/include/pwm/PWMControl.h index b8c8c48..12a5ecd 100644 --- a/app/include/pwm/PWMControl.h +++ b/app/include/pwm/PWMControl.h @@ -12,7 +12,7 @@ enum class PWM_MODE { DC = 0, PWM }; class PWMControl : public Printable, public Serializable { public: - PWMControl(std::string controlPath); + PWMControl(std::string controlPath, int deviceIndex); ~PWMControl(); void SetPower(int percent); @@ -26,9 +26,11 @@ public: json toJson() const override; private: + std::string mConfigPath; std::string mControlPath; std::string mEnablePath; std::string mModePath; + int mDeviceIndex; std::string mInitialEnable; std::string mInitialMode; diff --git a/app/src/FanGenerator.cxx b/app/src/FanGenerator.cxx index 91a153a..8018c59 100644 --- a/app/src/FanGenerator.cxx +++ b/app/src/FanGenerator.cxx @@ -8,7 +8,7 @@ #include #include -#define SETTLE_TIMEOUT 10 +#define SETTLE_TIMEOUT 30 using namespace std; diff --git a/app/src/Serializer.cxx b/app/src/Serializer.cxx index d666ac0..31e763a 100644 --- a/app/src/Serializer.cxx +++ b/app/src/Serializer.cxx @@ -37,7 +37,7 @@ Serializer::DeserializeFans(vector> availableSensors) { vector> fans; - // Create a for the sensors first, then searching becomes cheaper + // Create a map for the sensors first, then searching becomes cheaper map> sensorMap; for (auto s : availableSensors) { sensorMap[s->toString()] = s; @@ -46,7 +46,7 @@ Serializer::DeserializeFans(vector> availableSensors) { auto data = ReadJson(); try { for (auto &el : data["fans"].items()) { - auto pwmControl = make_shared(el.value()["PWMControl"]); + auto pwmControl = make_shared(el.value()["PWMControl"]["Path"], el.value()["PWMControl"]["Index"]); auto rpmSensor = sensorMap[el.value()["LMSensor"]]; int minPWM = el.value()["MinPWM"]; diff --git a/app/src/fan/FanCurve.cxx b/app/src/fan/FanCurve.cxx index 16e95b0..f1e9766 100644 --- a/app/src/fan/FanCurve.cxx +++ b/app/src/fan/FanCurve.cxx @@ -29,7 +29,7 @@ void FanCurve::DoFanControl() { for (auto s : mTempSensors) BOOST_LOG_TRIVIAL(trace) << s->toString(); - int temp = AggregateTemperature(); + int temp = mAggregator->aggregate(mTempSensors); int t0 = 0, t1 = 0, p0 = 0, p1 = 0; int targetFanPower; @@ -71,10 +71,6 @@ void FanCurve::DoFanControl() { } } -int FanCurve::AggregateTemperature() { - return mAggregator->aggregate(mTempSensors); -} - void FanCurve::PrintInfo() { BOOST_LOG_FUNCTION() @@ -123,7 +119,7 @@ void FanCurve::ApplyFanPower(std::shared_ptr fan, int targetFanPower) { BOOST_LOG_FUNCTION(); if (!fan->ZeroFanModeSupported() && fan->RPM() <= 0) { - BOOST_LOG_TRIVIAL(warning) << "Fan stopped completely!"; + BOOST_LOG_TRIVIAL(warning) << "Fan " << fan->toString() << " stopped completely!"; fan->PWM(fan->StartPWM()); fan->AdjustPWMLimits(); } else { diff --git a/app/src/pwm/PWMControl.cxx b/app/src/pwm/PWMControl.cxx index 66e4b2e..3921140 100644 --- a/app/src/pwm/PWMControl.cxx +++ b/app/src/pwm/PWMControl.cxx @@ -1,8 +1,8 @@ -#include #include #include #include +#include #include #include @@ -15,12 +15,24 @@ using namespace std; namespace fs = filesystem; -PWMControl::PWMControl(string controlPath) : mControlPath(controlPath) { - fs::path pathEnable(mControlPath + PWM_POSTFIX_ENABLE); - fs::path pathMode(mControlPath + PWM_POSTFIX_MODE); +PWMControl::PWMControl(string controlPath, int deviceIndex) + : mConfigPath(controlPath), mDeviceIndex(deviceIndex) { + auto path = fs::path{controlPath}; - mEnablePath = pathEnable; - mModePath = pathMode; + int fileCount = + distance(fs::directory_iterator(path), fs::directory_iterator{}); + if (fileCount != 1) + throw runtime_error("More than one HWMON device present, unsupported"); + + for (auto de : fs::directory_iterator(path)) { + auto testPath = de.path(); + mControlPath = + fs::path{de.path() / (string("pwm").append(to_string(deviceIndex)))} + .string(); + } + + mEnablePath = fs::path{mControlPath + PWM_POSTFIX_ENABLE}.string(); + mModePath = fs::path{mControlPath + PWM_POSTFIX_MODE}.string(); ifstream istrm; @@ -85,6 +97,6 @@ void PWMControl::Reset() { const string PWMControl::toString() const { return fs::path(mControlPath); } json PWMControl::toJson() const { - json obj = {"PWMControl", mControlPath}; + json obj = {"PWMControl", {{"Path", mConfigPath}, {"Index", mDeviceIndex}}}; return obj; } diff --git a/app/src/pwm/PWMControlFacade.cxx b/app/src/pwm/PWMControlFacade.cxx index 26a2456..68c2a99 100644 --- a/app/src/pwm/PWMControlFacade.cxx +++ b/app/src/pwm/PWMControlFacade.cxx @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -20,14 +21,20 @@ vector> PWMControlFacade::PWMControls() { for (const fs::directory_entry &hwmon_device : fs::directory_iterator{HWMON_BASE_PATH}) { + // Resolve symlink to get device path instead of hwmon path, the latter of + // which can change + fs::path actual_path = + fs::canonical(HWMON_BASE_PATH / fs::read_symlink(hwmon_device)); + for (const fs::directory_entry &control : - fs::directory_iterator{hwmon_device}) { + fs::directory_iterator{actual_path}) { auto filename = control.path().filename().string(); if (regex_match(filename, re_ctrl)) { - auto controlPath = control.path().string(); + auto controlIndex = filename.back() - '0'; + auto controlPath = actual_path.parent_path(); - controls.push_back(make_shared(controlPath)); + controls.push_back(make_shared(controlPath, controlIndex)); } } }