Implement remaining stuff
Basic functionality milestone reached!!
This commit is contained in:
@@ -22,6 +22,8 @@ add_executable(app
|
||||
src/FanGenerator.cxx
|
||||
src/Serializer.cxx
|
||||
src/sensor/SensorManager.cxx
|
||||
src/Controller.cxx
|
||||
src/App.cxx
|
||||
)
|
||||
|
||||
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:
|
||||
int AggregateTemperature();
|
||||
void PrintInfo();
|
||||
|
||||
std::vector<FanStep> mSteps;
|
||||
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>>
|
||||
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
|
||||
map<string, shared_ptr<Sensor>> sensorMap;
|
||||
@@ -49,12 +49,16 @@ Serializer::DeserializeFans(vector<shared_ptr<Sensor>> availableSensors) {
|
||||
int minPWM = el.value()["MinPWM"];
|
||||
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) {
|
||||
std::cout << "Deserialization error! Message: " << e.what() << std::endl;
|
||||
}
|
||||
return mapping;
|
||||
return fans;
|
||||
}
|
||||
|
||||
void Serializer::WriteJson(json o) {
|
||||
@@ -100,14 +104,16 @@ vector<shared_ptr<FanCurve>> Serializer::DeserializeFanCurves(
|
||||
vector<shared_ptr<Fan>> fans;
|
||||
|
||||
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()) {
|
||||
if (sensorMap.contains(sensor.value()))
|
||||
sensors.push_back(sensorMap[sensor.value()]);
|
||||
}
|
||||
|
||||
for (auto &fan : el.value()["Fans"].items()) {
|
||||
if (fanMap.contains(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;
|
||||
|
||||
FanCurve::FanCurve(std::vector<FanStep> steps,
|
||||
std::vector<std::shared_ptr<Sensor>> sensors,
|
||||
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() {
|
||||
int temp = AggregateTemperature();
|
||||
cout << "Temp: " << temp << "C" << endl;
|
||||
|
||||
int t0, t1, p0, p1;
|
||||
int targetFanSpeed;
|
||||
|
||||
if (temp <= mSteps[0].Temp) {
|
||||
t0 = t1 = mSteps[0].Temp;
|
||||
p0 = p1 = mSteps[0].Percent;
|
||||
targetFanSpeed = mSteps[0].Percent;
|
||||
} else if (temp > mSteps[mSteps.size() - 1].Temp) {
|
||||
t0 = t1 = mSteps[mSteps.size() - 1].Temp;
|
||||
p0 = p1 = mSteps[mSteps.size() - 1].Percent;
|
||||
targetFanSpeed = mSteps[mSteps.size() - 1].Percent;
|
||||
} else {
|
||||
for (int i = 0; i < mSteps.size(); i++) {
|
||||
if (temp > mSteps[i].Temp) {
|
||||
@@ -30,9 +33,11 @@ void FanCurve::DoFanControl() {
|
||||
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) {
|
||||
f->PWM(targetFanSpeed);
|
||||
@@ -41,10 +46,37 @@ void FanCurve::DoFanControl() {
|
||||
|
||||
// Dummy Implementation using AVG
|
||||
int FanCurve::AggregateTemperature() {
|
||||
int sum;
|
||||
int sum = 0;
|
||||
for (auto s : mTempSensors) {
|
||||
sum += s->value();
|
||||
}
|
||||
|
||||
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 {
|
||||
return "Fan!\nPWMControl: " + mPWMControl->toString() +
|
||||
"\nRpmSensor: " + mRpmSensor->toString();
|
||||
if (!mLabel.empty()) {
|
||||
return mLabel;
|
||||
} else {
|
||||
return "fan:" + mPWMControl->toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +1,22 @@
|
||||
#include <execution>
|
||||
#include <csignal>
|
||||
#include <iostream>
|
||||
|
||||
#include <FanGenerator.h>
|
||||
#include <Serializer.h>
|
||||
#include <fan/Fan.h>
|
||||
#include <fan/FanLabeler.h>
|
||||
#include <memory>
|
||||
#include <pstl/glue_execution_defs.h>
|
||||
#include <pwm/PWMControlFacade.h>
|
||||
#include <sensor/SensorManager.h>
|
||||
#include <App.h>
|
||||
|
||||
App app;
|
||||
|
||||
void signal_handler(int s) { app.Shutdown(); }
|
||||
|
||||
int main() {
|
||||
SensorManager sensorManager;
|
||||
auto pwmSensors = sensorManager.RPMSensors();
|
||||
auto tempSensors = sensorManager.TemperatureSensors();
|
||||
signal(SIGINT, signal_handler);
|
||||
|
||||
PWMControlFacade pwmControlFacade;
|
||||
auto controls = pwmControlFacade.PWMControls();
|
||||
|
||||
FanGenerator m;
|
||||
Serializer s;
|
||||
|
||||
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);
|
||||
try {
|
||||
app.Init();
|
||||
app.NormalOperation();
|
||||
} catch (const std::exception &e) {
|
||||
std::cout << "An exception was caught: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
app.Shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ int NvidiaSensor::value() {
|
||||
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 obj = {"NvidiaSensor", toString()};
|
||||
|
||||
Reference in New Issue
Block a user