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)); } } }