Implement remaining stuff
Basic functionality milestone reached!!
This commit is contained in:
@@ -22,6 +22,8 @@ add_executable(app
|
|||||||
src/FanGenerator.cxx
|
src/FanGenerator.cxx
|
||||||
src/Serializer.cxx
|
src/Serializer.cxx
|
||||||
src/sensor/SensorManager.cxx
|
src/sensor/SensorManager.cxx
|
||||||
|
src/Controller.cxx
|
||||||
|
src/App.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(TARGET app PROPERTY CXX_STANDARD 20)
|
set_property(TARGET app PROPERTY CXX_STANDARD 20)
|
||||||
|
|||||||
32
app/include/App.h
Normal file
32
app/include/App.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef APP_H_
|
||||||
|
#define APP_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <Controller.h>
|
||||||
|
#include <FanGenerator.h>
|
||||||
|
#include <Serializer.h>
|
||||||
|
#include <fan/FanLabeler.h>
|
||||||
|
#include <pwm/PWMControlFacade.h>
|
||||||
|
#include <sensor/SensorManager.h>
|
||||||
|
|
||||||
|
class App {
|
||||||
|
public:
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
void InitialSetup();
|
||||||
|
void NormalOperation();
|
||||||
|
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SensorManager mSensorManager;
|
||||||
|
Serializer mSerializer;
|
||||||
|
PWMControlFacade mPWMControlFacade;
|
||||||
|
FanLabeler mFanLabeler;
|
||||||
|
FanGenerator mFanGenerator;
|
||||||
|
|
||||||
|
std::unique_ptr<Controller> mController;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // APP_H_
|
||||||
27
app/include/Controller.h
Normal file
27
app/include/Controller.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef CONTROLLER_H_
|
||||||
|
#define CONTROLLER_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <fan/FanCurve.h>
|
||||||
|
|
||||||
|
class Controller {
|
||||||
|
public:
|
||||||
|
Controller(std::vector<std::shared_ptr<FanCurve>> curves);
|
||||||
|
~Controller();
|
||||||
|
|
||||||
|
void StartFanControlLoop();
|
||||||
|
void StopFanControlLoop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Loop();
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<FanCurve>> mFanCurves;
|
||||||
|
std::atomic<bool> mRun;
|
||||||
|
|
||||||
|
std::unique_ptr<std::thread> mWorker;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CONTROLLER_H_
|
||||||
@@ -22,6 +22,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int AggregateTemperature();
|
int AggregateTemperature();
|
||||||
|
void PrintInfo();
|
||||||
|
|
||||||
std::vector<FanStep> mSteps;
|
std::vector<FanStep> mSteps;
|
||||||
std::vector<std::shared_ptr<Sensor>> mTempSensors;
|
std::vector<std::shared_ptr<Sensor>> mTempSensors;
|
||||||
|
|||||||
33
app/src/App.cxx
Normal file
33
app/src/App.cxx
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#include <execution>
|
||||||
|
|
||||||
|
#include <App.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void App::Init() {
|
||||||
|
auto fans = mSerializer.DeserializeFans(mSensorManager.RPMSensors());
|
||||||
|
|
||||||
|
auto fanCurves = mSerializer.DeserializeFanCurves(
|
||||||
|
mSensorManager.TemperatureSensors(), fans);
|
||||||
|
|
||||||
|
mController = make_unique<Controller>(fanCurves);
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::InitialSetup() {
|
||||||
|
auto fans = mFanGenerator.FindFans(mSensorManager.RPMSensors(),
|
||||||
|
mPWMControlFacade.PWMControls());
|
||||||
|
|
||||||
|
std::for_each(std::execution::par, std::begin(fans), std::end(fans),
|
||||||
|
[](auto &&fan) { fan->FindMinPWM(); });
|
||||||
|
|
||||||
|
mFanLabeler.RunFanLabelInteraction(fans);
|
||||||
|
|
||||||
|
mSerializer.SerializeFans(fans);
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::NormalOperation() {
|
||||||
|
if (mController)
|
||||||
|
mController->StartFanControlLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::Shutdown() { mController.reset(); }
|
||||||
37
app/src/Controller.cxx
Normal file
37
app/src/Controller.cxx
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#include <chrono>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <Controller.h>
|
||||||
|
#include <fan/FanCurve.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#define TIMEOUT 500
|
||||||
|
|
||||||
|
Controller::Controller(vector<shared_ptr<FanCurve>> curves)
|
||||||
|
: mFanCurves(curves), mRun(false) {}
|
||||||
|
|
||||||
|
Controller::~Controller() { StopFanControlLoop(); }
|
||||||
|
|
||||||
|
void Controller::StartFanControlLoop() {
|
||||||
|
mRun = true;
|
||||||
|
Loop();
|
||||||
|
// mWorker = make_unique<thread>(&Controller::Loop, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::StopFanControlLoop() {
|
||||||
|
mRun = false;
|
||||||
|
// if (mWorker->joinable())
|
||||||
|
// mWorker->join();
|
||||||
|
// mWorker.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::Loop() {
|
||||||
|
while (mRun) {
|
||||||
|
for (auto c : mFanCurves) {
|
||||||
|
c->DoFanControl();
|
||||||
|
}
|
||||||
|
|
||||||
|
this_thread::sleep_for(chrono::milliseconds(TIMEOUT));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#ifndef CONTROLLER_H_
|
|
||||||
#define CONTROLLER_H_
|
|
||||||
|
|
||||||
class Controller {
|
|
||||||
public:
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CONTROLLER_H_
|
|
||||||
@@ -32,7 +32,7 @@ void Serializer::SerializeFans(vector<shared_ptr<Fan>> fans) {
|
|||||||
|
|
||||||
vector<shared_ptr<Fan>>
|
vector<shared_ptr<Fan>>
|
||||||
Serializer::DeserializeFans(vector<shared_ptr<Sensor>> availableSensors) {
|
Serializer::DeserializeFans(vector<shared_ptr<Sensor>> availableSensors) {
|
||||||
vector<shared_ptr<Fan>> mapping;
|
vector<shared_ptr<Fan>> fans;
|
||||||
|
|
||||||
// Create a for the sensors first, then searching becomes cheaper
|
// Create a for the sensors first, then searching becomes cheaper
|
||||||
map<string, shared_ptr<Sensor>> sensorMap;
|
map<string, shared_ptr<Sensor>> sensorMap;
|
||||||
@@ -49,12 +49,16 @@ Serializer::DeserializeFans(vector<shared_ptr<Sensor>> availableSensors) {
|
|||||||
int minPWM = el.value()["MinPWM"];
|
int minPWM = el.value()["MinPWM"];
|
||||||
string label = el.value()["Label"];
|
string label = el.value()["Label"];
|
||||||
|
|
||||||
mapping.push_back(make_shared<HwmonFan>(pwmControl, rpmSensor));
|
auto fan = make_shared<HwmonFan>(pwmControl, rpmSensor);
|
||||||
|
fan->MinPWM(minPWM);
|
||||||
|
fan->Label(label);
|
||||||
|
|
||||||
|
fans.push_back(fan);
|
||||||
}
|
}
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
std::cout << "Deserialization error! Message: " << e.what() << std::endl;
|
std::cout << "Deserialization error! Message: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
return mapping;
|
return fans;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Serializer::WriteJson(json o) {
|
void Serializer::WriteJson(json o) {
|
||||||
@@ -100,14 +104,16 @@ vector<shared_ptr<FanCurve>> Serializer::DeserializeFanCurves(
|
|||||||
vector<shared_ptr<Fan>> fans;
|
vector<shared_ptr<Fan>> fans;
|
||||||
|
|
||||||
for (auto &step : el.value()["FanSteps"].items()) {
|
for (auto &step : el.value()["FanSteps"].items()) {
|
||||||
FanStep fanStep{step.value()[0], step.value()[1]};
|
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()]);
|
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()]);
|
fans.push_back(fanMap[fan.value()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,28 @@
|
|||||||
#include <fan/FanCurve.h>
|
#include <iostream>
|
||||||
|
|
||||||
#include <array>
|
#include <fan/FanCurve.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
FanCurve::FanCurve(std::vector<FanStep> steps,
|
FanCurve::FanCurve(std::vector<FanStep> steps,
|
||||||
std::vector<std::shared_ptr<Sensor>> sensors,
|
std::vector<std::shared_ptr<Sensor>> sensors,
|
||||||
std::vector<std::shared_ptr<Fan>> fans)
|
std::vector<std::shared_ptr<Fan>> fans)
|
||||||
: mSteps(steps), mTempSensors(sensors), mFans(fans) {}
|
: mSteps(steps), mTempSensors(sensors), mFans(fans) {
|
||||||
|
cout << "Initialized Fan Curve:" << endl;
|
||||||
|
PrintInfo();
|
||||||
|
}
|
||||||
|
|
||||||
void FanCurve::DoFanControl() {
|
void FanCurve::DoFanControl() {
|
||||||
int temp = AggregateTemperature();
|
int temp = AggregateTemperature();
|
||||||
|
cout << "Temp: " << temp << "C" << endl;
|
||||||
|
|
||||||
int t0, t1, p0, p1;
|
int t0, t1, p0, p1;
|
||||||
|
int targetFanSpeed;
|
||||||
|
|
||||||
if (temp <= mSteps[0].Temp) {
|
if (temp <= mSteps[0].Temp) {
|
||||||
t0 = t1 = mSteps[0].Temp;
|
targetFanSpeed = mSteps[0].Percent;
|
||||||
p0 = p1 = mSteps[0].Percent;
|
|
||||||
} else if (temp > mSteps[mSteps.size() - 1].Temp) {
|
} else if (temp > mSteps[mSteps.size() - 1].Temp) {
|
||||||
t0 = t1 = mSteps[mSteps.size() - 1].Temp;
|
targetFanSpeed = mSteps[mSteps.size() - 1].Percent;
|
||||||
p0 = p1 = mSteps[mSteps.size() - 1].Percent;
|
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < mSteps.size(); i++) {
|
for (int i = 0; i < mSteps.size(); i++) {
|
||||||
if (temp > mSteps[i].Temp) {
|
if (temp > mSteps[i].Temp) {
|
||||||
@@ -30,9 +33,11 @@ void FanCurve::DoFanControl() {
|
|||||||
p1 = mSteps[i + 1].Percent;
|
p1 = mSteps[i + 1].Percent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
targetFanSpeed = p0 + ((p1 - p0) / (t1 - t0)) * (temp - t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int targetFanSpeed = p0 + ((p1 - p0) / (t1 - t0)) * (temp - t0);
|
cout << "Power: " << targetFanSpeed << "%" << endl;
|
||||||
|
|
||||||
for (auto f : mFans) {
|
for (auto f : mFans) {
|
||||||
f->PWM(targetFanSpeed);
|
f->PWM(targetFanSpeed);
|
||||||
@@ -41,10 +46,37 @@ void FanCurve::DoFanControl() {
|
|||||||
|
|
||||||
// Dummy Implementation using AVG
|
// Dummy Implementation using AVG
|
||||||
int FanCurve::AggregateTemperature() {
|
int FanCurve::AggregateTemperature() {
|
||||||
int sum;
|
int sum = 0;
|
||||||
for (auto s : mTempSensors) {
|
for (auto s : mTempSensors) {
|
||||||
sum += s->value();
|
sum += s->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
return sum / mTempSensors.size();
|
return sum / mTempSensors.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FanCurve::PrintInfo() {
|
||||||
|
stringstream sStream;
|
||||||
|
cout << "Steps: ";
|
||||||
|
for (auto s : mSteps) {
|
||||||
|
sStream << "[ " << s.Temp << "C, " << s.Percent << "% ] ";
|
||||||
|
}
|
||||||
|
cout << sStream.str() << endl;
|
||||||
|
|
||||||
|
sStream.str(string());
|
||||||
|
|
||||||
|
cout << "Sensors: ";
|
||||||
|
for (auto s : mTempSensors) {
|
||||||
|
sStream << s->toString() << ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << sStream.str() << endl;
|
||||||
|
|
||||||
|
sStream.str(string());
|
||||||
|
|
||||||
|
cout << "Fans: ";
|
||||||
|
for (auto s : mFans) {
|
||||||
|
sStream << s->toString() << ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << sStream.str() << endl;
|
||||||
|
}
|
||||||
|
|||||||
@@ -70,6 +70,9 @@ json HwmonFan::toJson() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const string HwmonFan::toString() const {
|
const string HwmonFan::toString() const {
|
||||||
return "Fan!\nPWMControl: " + mPWMControl->toString() +
|
if (!mLabel.empty()) {
|
||||||
"\nRpmSensor: " + mRpmSensor->toString();
|
return mLabel;
|
||||||
|
} else {
|
||||||
|
return "fan:" + mPWMControl->toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +1,22 @@
|
|||||||
#include <execution>
|
#include <csignal>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <FanGenerator.h>
|
#include <App.h>
|
||||||
#include <Serializer.h>
|
|
||||||
#include <fan/Fan.h>
|
App app;
|
||||||
#include <fan/FanLabeler.h>
|
|
||||||
#include <memory>
|
void signal_handler(int s) { app.Shutdown(); }
|
||||||
#include <pstl/glue_execution_defs.h>
|
|
||||||
#include <pwm/PWMControlFacade.h>
|
|
||||||
#include <sensor/SensorManager.h>
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
SensorManager sensorManager;
|
signal(SIGINT, signal_handler);
|
||||||
auto pwmSensors = sensorManager.RPMSensors();
|
|
||||||
auto tempSensors = sensorManager.TemperatureSensors();
|
|
||||||
|
|
||||||
PWMControlFacade pwmControlFacade;
|
try {
|
||||||
auto controls = pwmControlFacade.PWMControls();
|
app.Init();
|
||||||
|
app.NormalOperation();
|
||||||
FanGenerator m;
|
} catch (const std::exception &e) {
|
||||||
Serializer s;
|
std::cout << "An exception was caught: " << e.what() << std::endl;
|
||||||
|
}
|
||||||
std::vector<std::shared_ptr<Fan>> fans;
|
|
||||||
|
|
||||||
// fans = m.FindFans(pwmSensors, controls);
|
|
||||||
// s.SerializeFans(fans);
|
|
||||||
fans = s.DeserializeFans(pwmSensors);
|
|
||||||
|
|
||||||
std::for_each(std::execution::par, std::begin(fans), std::end(fans),
|
|
||||||
[](auto &&f) { f->FindMinPWM(); });
|
|
||||||
|
|
||||||
// auto curves = s.DeserializeFanCurves(tempSensors, fans);
|
|
||||||
FanLabeler labeler;
|
|
||||||
labeler.RunFanLabelInteraction(fans);
|
|
||||||
|
|
||||||
s.SerializeFans(fans);
|
|
||||||
|
|
||||||
|
app.Shutdown();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ int NvidiaSensor::value() {
|
|||||||
return static_cast<int>(temp);
|
return static_cast<int>(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string NvidiaSensor::toString() const { return "Nvidia GPU"; }
|
const std::string NvidiaSensor::toString() const { return "NvidiaGPU"; }
|
||||||
|
|
||||||
json NvidiaSensor::toJson() const {
|
json NvidiaSensor::toJson() const {
|
||||||
json obj = {"NvidiaSensor", toString()};
|
json obj = {"NvidiaSensor", toString()};
|
||||||
|
|||||||
Reference in New Issue
Block a user