Implement remaining stuff

Basic functionality milestone reached!!
This commit is contained in:
2022-10-01 15:55:49 +02:00
parent 2ef9d979b0
commit b74f0e87cd
12 changed files with 205 additions and 58 deletions

View File

@@ -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
View 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
View 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_

View File

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

View File

@@ -1,8 +0,0 @@
#ifndef CONTROLLER_H_
#define CONTROLLER_H_
class Controller {
public:
};
#endif // CONTROLLER_H_

View File

@@ -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,15 +104,17 @@ 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()) {
sensors.push_back(sensorMap[sensor.value()]);
if (sensorMap.contains(sensor.value()))
sensors.push_back(sensorMap[sensor.value()]);
}
for (auto &fan : el.value()["Fans"].items()) {
fans.push_back(fanMap[fan.value()]);
if (fanMap.contains(fan.value()))
fans.push_back(fanMap[fan.value()]);
}
curves.push_back(make_shared<FanCurve>(steps, sensors, fans));

View File

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

View File

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

View File

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

View File

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