diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index d810f4a..d49f58e 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -9,11 +9,11 @@ find_package(Boost 1.79.0 COMPONENTS json) add_executable(app src/main.cxx - src/sensor/NvidiaTemperatureSensor.cxx + src/sensor/NvidiaSensor.cxx src/fan/Pwm.cxx src/fan/PwmControl.cxx src/SensorsWrapper.cxx - src/sensor/HwmonTemperatureSensor.cxx + src/sensor/HwmonSensor.cxx ) set_property(TARGET app PROPERTY CXX_STANDARD 17) diff --git a/app/doc/ApplicationStart.plantuml b/app/doc/ApplicationStart.plantuml new file mode 100644 index 0000000..b3a261e --- /dev/null +++ b/app/doc/ApplicationStart.plantuml @@ -0,0 +1,17 @@ +@startuml + +start +:Initialization; + +if (Mapping exists) then (yes) + :Load mapping; +else (no) + :Generate mapping; +endif + +:Enter fan control loop; +:Load Fan Curves; + +stop + +@enduml diff --git a/app/doc/Class.plantuml b/app/doc/Class.plantuml new file mode 100644 index 0000000..962531c --- /dev/null +++ b/app/doc/Class.plantuml @@ -0,0 +1,25 @@ +@startuml +interface Fan { + {abstract} void PWM(int percent) + {abstract} int RPM() +} + +interface Sensor { + {abstract} int value() + {abstract} string name() +} + +class HwmonFan { + +} + +Fan <|-- HwmonFan + +Sensor <|-- HwmonSensor +Sensor <|-- NvidiaSensor + +HwmonFan - Sensor +HwmonFan -- PwmControl + + +@enduml diff --git a/app/doc/InteractiveMapping.plantuml b/app/doc/InteractiveMapping.plantuml new file mode 100644 index 0000000..46cc927 --- /dev/null +++ b/app/doc/InteractiveMapping.plantuml @@ -0,0 +1,7 @@ +@startuml +actor User as usr +participant Interface as if + + + +@enduml diff --git a/app/include/fan/HwmonFan.h b/app/include/fan/HwmonFan.h index 0309ab4..7601940 100644 --- a/app/include/fan/HwmonFan.h +++ b/app/include/fan/HwmonFan.h @@ -1,17 +1,23 @@ #ifndef HWMONFAN_H_ #define HWMONFAN_H_ +#include + #include #include +#include class HwmonFan : public Fan { public: + HwmonFan(std::unique_ptr pwmControl, + std::unique_ptr rpmSensor); + void PWM(int percent) override; int RPM() override; private: - PwmControl mPwmControl; - // PwmSensor mPwmSensor; + std::unique_ptr mPwmControl; + std::unique_ptr mRpmSensor; }; #endif // HWMONFAN_H_ diff --git a/app/include/sensor/HwmonSensor.h b/app/include/sensor/HwmonSensor.h new file mode 100644 index 0000000..94af1f6 --- /dev/null +++ b/app/include/sensor/HwmonSensor.h @@ -0,0 +1,22 @@ +#ifndef HWMONSENSOR_H_ +#define HWMONSENSOR_H_ + +#include + +#include + +class HwmonSensor : public Sensor { +public: + HwmonSensor(const sensors_chip_name *chipName, const sensors_feature *feature, + const sensors_subfeature *subfeature); + + int value() override; + std::string name() override; + +private: + const sensors_chip_name *mChipName; + const sensors_feature *mFeature; + const sensors_subfeature *mSubFeature; +}; + +#endif // HWMONSENSOR_H_ diff --git a/app/include/sensor/HwmonTemperatureSensor.h b/app/include/sensor/HwmonTemperatureSensor.h deleted file mode 100644 index de7ecdf..0000000 --- a/app/include/sensor/HwmonTemperatureSensor.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef HWMONTEMPERATURESENSOR_H_ -#define HWMONTEMPERATURESENSOR_H_ - -#include - -#include - -class HwmonTemperatureSensor : public TemperatureSensor { -public: - HwmonTemperatureSensor(const sensors_chip_name *chipName, - const sensors_feature *feature, - const sensors_subfeature *subfeature); - - int temperature() override; - std::string name() override; - -private: - const sensors_chip_name *mChipName; - const sensors_feature *mFeature; - const sensors_subfeature *mSubFeature; -}; - -#endif // HWMONTEMPERATURESENSOR_H_ diff --git a/app/include/sensor/NvidiaSensor.h b/app/include/sensor/NvidiaSensor.h new file mode 100644 index 0000000..2c5836b --- /dev/null +++ b/app/include/sensor/NvidiaSensor.h @@ -0,0 +1,15 @@ +#ifndef NVIDIASENSOR_H_ +#define NVIDIASENSOR_H_ + +#include + +class NvidiaSensor : public Sensor { +public: + NvidiaSensor(); + ~NvidiaSensor(); + + int value() override; + std::string name() override; +}; + +#endif // NVIDIASENSOR_H_ diff --git a/app/include/sensor/NvidiaTemperatureSensor.h b/app/include/sensor/NvidiaTemperatureSensor.h deleted file mode 100644 index b408ce4..0000000 --- a/app/include/sensor/NvidiaTemperatureSensor.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef NVIDIA_H_ -#define NVIDIA_H_ - -#include - -class NvidiaTemperatureSensor : public TemperatureSensor { -public: - NvidiaTemperatureSensor(); - ~NvidiaTemperatureSensor(); - - int temperature() override; - std::string name() override; -}; - -#endif // NVIDIA_H_ diff --git a/app/include/sensor/Sensor.h b/app/include/sensor/Sensor.h new file mode 100644 index 0000000..f4e969f --- /dev/null +++ b/app/include/sensor/Sensor.h @@ -0,0 +1,15 @@ +#ifndef SENSOR_H_ +#define SENSOR_H_ + +#include + +class Sensor { +public: + // Read the current value + virtual int value() = 0; + // Name for displaying. Should be descriptive, e.g. "GPU" or the label from + // libsensors. + virtual std::string name() = 0; +}; + +#endif // SENSOR_H_ diff --git a/app/include/sensor/TemperatureSensor.h b/app/include/sensor/TemperatureSensor.h deleted file mode 100644 index 6e93a8e..0000000 --- a/app/include/sensor/TemperatureSensor.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef TEMPERATURESENSOR_H_ -#define TEMPERATURESENSOR_H_ - -#include - -class TemperatureSensor { -public: - virtual int temperature() = 0; - virtual std::string name() = 0; -}; - -#endif // TEMPERATURESENSOR_H_ diff --git a/app/src/fan/PwmControl.cxx b/app/src/fan/PwmControl.cxx index d972939..814bf2f 100644 --- a/app/src/fan/PwmControl.cxx +++ b/app/src/fan/PwmControl.cxx @@ -55,6 +55,12 @@ void PwmControl::enableManualControl() { void PwmControl::reset() { ofstream ostrm(mEnablePath, ios::trunc); + ostrm << mInitialEnable; ostrm.close(); + + ostrm.open(mModePath, ios::trunc); + ostrm << mInitialMode; + + ostrm.close(); } diff --git a/app/src/main.cxx b/app/src/main.cxx index ad1ab0c..63538ea 100644 --- a/app/src/main.cxx +++ b/app/src/main.cxx @@ -1,23 +1,24 @@ #include +#include #include #include +#include #include #include -#include -#include -#include +#include +#include +#include #define CONFIG_FILE "/etc/conf.d/sensors" +#define HWMON_BASE_PATH "/sys/class/hwmon" -std::vector> sensors() { - std::vector> sensors; +namespace fs = std::filesystem; - auto config = fopen(CONFIG_FILE, "r"); - if (sensors_init(config) != 0) { - throw std::runtime_error("Config file doesn't exist"); - } +template +std::vector> sensors() { + std::vector> sensors; int c = 0; for (const sensors_chip_name *chipName; @@ -26,32 +27,64 @@ std::vector> sensors() { int d = 0; for (const sensors_feature *feature; (feature = sensors_get_features(chipName, &d)) != NULL;) { - auto tempFeature = sensors_get_subfeature(chipName, feature, - SENSORS_SUBFEATURE_TEMP_INPUT); - if (tempFeature) - sensors.push_back(std::make_shared( - chipName, feature, tempFeature)); + auto subFeature = sensors_get_subfeature(chipName, feature, T); + if (subFeature) { + sensors.push_back( + std::make_shared(chipName, feature, subFeature)); + } } } - sensors.push_back(std::make_shared()); - return sensors; } +std::vector> pwmControls() { + std::vector> controls; + + const std::regex re_ctrl_enable("pwm[0-9]_enable"); + const std::regex re_ctrl_mode("pwm[0-9]_mode"); + const std::regex re_ctrl("pwm[0-9]"); + + if (!fs::exists(HWMON_BASE_PATH)) { + std::cout << HWMON_BASE_PATH << " doesn't exist" << std::endl; + } else { + for (const fs::directory_entry &hwmon_device : + fs::directory_iterator{HWMON_BASE_PATH}) { + + for (const fs::directory_entry &control : + fs::directory_iterator{hwmon_device}) { + auto filename = control.path().filename().string(); + + if (regex_match(filename, re_ctrl)) { + auto controlPath = control.path().string(); + + controls.push_back(std::make_shared(controlPath)); + } + } + } + } + + return controls; +} + int main() { - class PWM pwm; - std::cout << '\n'; - pwm.dumpValues(); + auto config = fopen(CONFIG_FILE, "r"); + if (sensors_init(config) != 0) { + throw std::runtime_error("Config file doesn't exist"); + } - auto controls = pwm.getControls(); - std::cout << pwm.readValue(controls[0], PWM_CONTROL_PROPERTY::ENABLE) - << std::endl; - - auto tempSensors = sensors(); + auto tempSensors = sensors(); + tempSensors.push_back(std::make_shared()); for (auto s : tempSensors) { - std::cout << s->name() << ": " << s->temperature() << std::endl; + std::cout << s->name() << ": " << s->value() << std::endl; + } + + std::cout << "pwm" << std::endl; + + auto pwmSensors = sensors(); + for (auto s : pwmSensors) { + std::cout << s->name() << ": " << s->value() << std::endl; } return 0; diff --git a/app/src/sensor/HwmonSensor.cxx b/app/src/sensor/HwmonSensor.cxx new file mode 100644 index 0000000..87796d1 --- /dev/null +++ b/app/src/sensor/HwmonSensor.cxx @@ -0,0 +1,19 @@ +#include + +#include + +using namespace std; + +HwmonSensor::HwmonSensor(const sensors_chip_name *chipName, + const sensors_feature *feature, + const sensors_subfeature *subfeature) + : mChipName(chipName), mFeature(feature), mSubFeature(subfeature) {} + +int HwmonSensor::value() { + double *value; + sensors_get_value(mChipName, mSubFeature->number, value); + + return static_cast(*value); +} + +string HwmonSensor::name() { return sensors_get_label(mChipName, mFeature); } diff --git a/app/src/sensor/HwmonTemperatureSensor.cxx b/app/src/sensor/HwmonTemperatureSensor.cxx deleted file mode 100644 index 3fd1ab6..0000000 --- a/app/src/sensor/HwmonTemperatureSensor.cxx +++ /dev/null @@ -1,21 +0,0 @@ -#include - -#include - -using namespace std; - -HwmonTemperatureSensor::HwmonTemperatureSensor( - const sensors_chip_name *chipName, const sensors_feature *feature, - const sensors_subfeature *subfeature) - : mChipName(chipName), mFeature(feature), mSubFeature(subfeature) {} - -int HwmonTemperatureSensor::temperature() { - double *value; - sensors_get_value(mChipName, mSubFeature->number, value); - - return static_cast(*value); -} - -string HwmonTemperatureSensor::name() { - return sensors_get_label(mChipName, mFeature); -} diff --git a/app/src/sensor/NvidiaSensor.cxx b/app/src/sensor/NvidiaSensor.cxx new file mode 100644 index 0000000..99c913e --- /dev/null +++ b/app/src/sensor/NvidiaSensor.cxx @@ -0,0 +1,21 @@ +#include + +#include + +using namespace std; + +NvidiaSensor::NvidiaSensor() { nvmlInit_v2(); } +NvidiaSensor::~NvidiaSensor() { nvmlShutdown(); } + +int NvidiaSensor::value() { + nvmlDevice_t device; + + nvmlDeviceGetHandleByIndex_v2(0, &device); + + unsigned int temp; + nvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &temp); + + return static_cast(temp); +} + +string NvidiaSensor::name() { return "GPU"; } diff --git a/app/src/sensor/NvidiaTemperatureSensor.cxx b/app/src/sensor/NvidiaTemperatureSensor.cxx deleted file mode 100644 index cf5dfab..0000000 --- a/app/src/sensor/NvidiaTemperatureSensor.cxx +++ /dev/null @@ -1,21 +0,0 @@ -#include - -#include - -using namespace std; - -NvidiaTemperatureSensor::NvidiaTemperatureSensor() { nvmlInit_v2(); } -NvidiaTemperatureSensor::~NvidiaTemperatureSensor() { nvmlShutdown(); } - -int NvidiaTemperatureSensor::temperature() { - nvmlDevice_t device; - - nvmlDeviceGetHandleByIndex_v2(0, &device); - - unsigned int temp; - nvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &temp); - - return static_cast(temp); -} - -string NvidiaTemperatureSensor::name() { return "GPU"; }