Created
August 14, 2022 17:47
-
-
Save felipemanga/4a5abd64760dde6312964755a2bc387a to your computer and use it in GitHub Desktop.
A06 Automatic Gearbox
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Compile like this: g++ fullauto.cpp --std=c++17 -o fullauto | |
// Run like this: sudo fullauto & | |
#include <thread> | |
#include <chrono> | |
#include <iostream> | |
#include <fstream> | |
#include <sstream> | |
#include <vector> | |
using namespace std; | |
using namespace chrono; | |
using namespace chrono_literals; | |
ifstream stat{"/proc/stat"}; | |
ifstream ac{"/sys/class/power_supply/axp22x-ac/present"}; | |
ifstream cpuTemp{"/sys/class/thermal/thermal_zone0/temp"}; | |
milliseconds batteryPollRate = 500ms, acPollRate = 175ms; | |
constexpr const int acBit = 2, | |
hotBit = 1, | |
busyBit = 0; | |
constexpr const int profiles[] = { | |
// 000 - battery, cool, idle | |
1, | |
// 001 - battery, cool, busy | |
3, | |
// 010 - battery, hot, idle | |
1, | |
// 011 - battery, hot, busy | |
2, | |
// 100 - mains, cool, idle | |
3, | |
// 101 - mains, cool, busy | |
6, | |
// 110 - mains, hot, idle | |
5, | |
// 111 - mains, hot, busy | |
5 | |
}; | |
const string& read(ifstream& stream) { | |
static stringstream buf; | |
static string out; | |
buf.str(""); | |
stream.seekg(0); | |
buf << stream.rdbuf(); | |
out = buf.str(); | |
return out; | |
} | |
bool hasACPower() { | |
return read(ac)[0] == '1'; | |
} | |
float getCPUTemp() { | |
return atof(read(cpuTemp).c_str()) * 0.001f; | |
} | |
int getCPUContention() { | |
static vector<int> prev; | |
static vector<int> columns; | |
auto& str = read(stat); | |
auto len = str.size(); | |
columns.clear(); | |
bool in = false; | |
for (auto i = str.find("cpu "); i < len && str[i] != '\n'; ++i) { | |
auto c = str[i]; | |
bool isNum = c >= '0' && c <= '9'; | |
if (isNum == in) | |
continue; | |
in = isNum; | |
if (isNum) { | |
columns.push_back(atoi(str.c_str() + i)); | |
} | |
} | |
int cont = 0; | |
if (!prev.empty()) { | |
cont = columns[0] - prev[0]; | |
} | |
prev = columns; | |
return cont; | |
} | |
void run() { | |
int currentProfile = -1; | |
bool busy = false; | |
bool hot = false; | |
while (1) { | |
auto isAC = hasACPower(); | |
auto rate = isAC ? acPollRate : batteryPollRate; | |
auto cont = getCPUContention(); | |
this_thread::sleep_for(rate); | |
cont = getCPUContention(); | |
auto n = (cont * 100) / rate.count(); | |
bool isHot = getCPUTemp() > (hot ? 70 : 80); | |
hot = isHot; | |
bool isBusy = n > ( | |
isAC ? (busy ? 8 : 14) : (busy ? 4 : 8) | |
); | |
busy = isBusy; | |
int profile = profiles | |
[ (isAC << acBit) | |
| (isHot << hotBit) | |
| (isBusy << busyBit) | |
]; | |
if (profile == currentProfile) | |
continue; | |
currentProfile = profile; | |
auto cmd = "devterm-a06-gearbox -s " | |
+ std::to_string(profile) | |
+ " > /dev/null"; | |
system(cmd.c_str()); | |
this_thread::sleep_for(rate); | |
} | |
} | |
int main() { | |
if (!stat || !ac || !cpuTemp) { | |
cout << "Could not read file" << endl; | |
return 1; | |
} | |
run(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment