refactor utils
This commit is contained in:
@@ -2,14 +2,18 @@
|
||||
#define UTILS_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <format>
|
||||
#include <string>
|
||||
|
||||
#define FILL_CHAR ' '
|
||||
namespace utils {
|
||||
|
||||
enum JUST { RIGHT, LEFT };
|
||||
const char FILL_CHAR = ' ';
|
||||
|
||||
std::string pad(std::string s, uint8_t len, JUST j = JUST::RIGHT);
|
||||
enum just { right,
|
||||
left };
|
||||
|
||||
std::string pad(std::string s, uint8_t len, just j = just::right);
|
||||
std::string center(std::string str, uint8_t len);
|
||||
std::string pBytes(double bytes, bool isKbytes = false);
|
||||
ssize_t readFile(std::string path, char* buffer, size_t maxlen);
|
||||
@@ -22,9 +26,14 @@ inline long long fastReadNum(const std::string& path, char (&buf)[N]) {
|
||||
return std::strtoll(buf, nullptr, 10);
|
||||
}
|
||||
|
||||
// pretty prints num with given decs, 0 by default. its basically a macro so we inline it
|
||||
inline std::string pNum(auto num, uint8_t decs = 0) {
|
||||
return std::format("{:.{}f}", num, decs);
|
||||
}
|
||||
|
||||
inline bool fileExists(std::string_view path) {
|
||||
return std::filesystem::exists(path);
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
|
||||
#endif
|
||||
|
||||
40
main.cpp
40
main.cpp
@@ -108,7 +108,7 @@ void displayThread(std::stop_token st, Sensors* s) {
|
||||
lcd.setCustomChar(4, {4, 4, 4, 21, 14, 4, 0}); // down arrow
|
||||
|
||||
// welcome msg
|
||||
lcd.writeBuf(2, 0, center("Waiting for sensors...", 40));
|
||||
lcd.writeBuf(2, 0, utils::center("Waiting for sensors...", 40));
|
||||
lcd.flushBuf();
|
||||
lcd.clearBuf();
|
||||
|
||||
@@ -121,7 +121,7 @@ void displayThread(std::stop_token st, Sensors* s) {
|
||||
// prepare some tricky sensors
|
||||
std::string gpu_temps = std::to_string(s->gpu.temp_edge);
|
||||
if (s->gpu.temp_hotspot)
|
||||
gpu_temps = pad(lcd.cc(1) + std::to_string(s->gpu.temp_hotspot - s->gpu.temp_edge) + lcd.cc(0), 4) + " " + pad(gpu_temps + "/" + std::to_string(s->gpu.temp_hotspot), 5);
|
||||
gpu_temps = utils::pad(lcd.cc(1) + std::to_string(s->gpu.temp_hotspot - s->gpu.temp_edge) + lcd.cc(0), 4) + " " + utils::pad(gpu_temps + "/" + std::to_string(s->gpu.temp_hotspot), 5);
|
||||
|
||||
uint16_t cpu_fan = 0;
|
||||
for (auto& fan : s->sys.fan_speed)
|
||||
@@ -129,30 +129,30 @@ void displayThread(std::stop_token st, Sensors* s) {
|
||||
cpu_fan /= 2;
|
||||
|
||||
// write to display buffer
|
||||
lcd.writeBuf(0, 0, pad(s->td.date, 11, JUST::LEFT) + " " + s->td.time + lcd.bar(7, s->gpu.usage_core / 100.0));
|
||||
lcd.writeBuf(0, 26, pNum(s->avg[0], s->avg[0] > 10 ? 1 : 2));
|
||||
lcd.writeBuf(0, 31, pNum(s->avg[1], s->avg[1] > 10 ? 1 : 2));
|
||||
lcd.writeBuf(0, 36, pNum(s->avg[2], s->avg[2] > 10 ? 1 : 2));
|
||||
lcd.writeBuf(0, 0, utils::pad(s->td.date, 11, utils::just::left) + " " + s->td.time + lcd.bar(7, s->gpu.usage_core / 100.0));
|
||||
lcd.writeBuf(0, 26, utils::pNum(s->avg[0], s->avg[0] > 10 ? 1 : 2));
|
||||
lcd.writeBuf(0, 31, utils::pNum(s->avg[1], s->avg[1] > 10 ? 1 : 2));
|
||||
lcd.writeBuf(0, 36, utils::pNum(s->avg[2], s->avg[2] > 10 ? 1 : 2));
|
||||
|
||||
lcd.writeBuf(1, 0, pad(std::to_string(s->cpu.tctl) + "/" + std::to_string(s->cpu.tccd1) + lcd.cc(0), 8, JUST::LEFT));
|
||||
lcd.writeBuf(1, 7, pad(pBytes(s->ram.used, true), 6, JUST::LEFT));
|
||||
lcd.writeBuf(1, 13, pad(pNum(s->hass_state) + "W", 4));
|
||||
lcd.writeBuf(1, 0, utils::pad(std::to_string(s->cpu.tctl) + "/" + std::to_string(s->cpu.tccd1) + lcd.cc(0), 8, utils::just::left));
|
||||
lcd.writeBuf(1, 7, utils::pad(utils::pBytes(s->ram.used, true), 6, utils::just::left));
|
||||
lcd.writeBuf(1, 13, utils::pad(utils::pNum(s->hass_state) + "W", 4));
|
||||
lcd.writeBuf(1, 19, std::to_string(s->sys.t_sensor) + lcd.cc(0)); // t_sensor temp
|
||||
lcd.writeBuf(1, 32 - gpu_temps.size(), pad(pBytes(s->gpu.vram_used), 6));
|
||||
lcd.writeBuf(1, 32 - gpu_temps.size(), utils::pad(utils::pBytes(s->gpu.vram_used), 6));
|
||||
lcd.writeBuf(1, 39 - gpu_temps.size(), gpu_temps + lcd.cc(0));
|
||||
|
||||
lcd.writeBuf(2, 0, pad(std::to_string((int)s->cpu.ptotal) + "W", 8, JUST::LEFT));
|
||||
lcd.writeBuf(2, 0, utils::pad(std::to_string((int)s->cpu.ptotal) + "W", 8, utils::just::left));
|
||||
lcd.writeBuf(2, s->cpu.ptotal < 100 ? 4 : 5, std::to_string(cpu_fan) + "R"); // avg fan speed
|
||||
lcd.writeBuf(2, 12, lcd.cc(3) + pBytes(s->net.upload));
|
||||
lcd.writeBuf(2, 19, lcd.cc(4) + pBytes(s->net.download));
|
||||
lcd.writeBuf(2, 26, pad(std::to_string(s->gpu.fan_speed) + "R", 5));
|
||||
lcd.writeBuf(2, 31, pad(std::to_string(s->gpu.power_avg) + "/" + std::to_string(s->gpu.power_cap) + "W", 9));
|
||||
lcd.writeBuf(2, 12, lcd.cc(3) + utils::pBytes(s->net.upload));
|
||||
lcd.writeBuf(2, 19, lcd.cc(4) + utils::pBytes(s->net.download));
|
||||
lcd.writeBuf(2, 26, utils::pad(std::to_string(s->gpu.fan_speed) + "R", 5));
|
||||
lcd.writeBuf(2, 31, utils::pad(std::to_string(s->gpu.power_avg) + "/" + std::to_string(s->gpu.power_cap) + "W", 9));
|
||||
|
||||
lcd.writeBuf(3, 0, pad(pNum(s->cpu.vcore, 2) + "V", 7, JUST::LEFT));
|
||||
lcd.writeBuf(3, 0, utils::pad(utils::pNum(s->cpu.vcore, 2) + "V", 7, utils::just::left));
|
||||
lcd.writeBuf(3, 6, std::to_string(s->cpu.avg_freq) + "MHz");
|
||||
lcd.writeBuf(3, 14, pad(lcd.cc(2) + pBytes(s->home.usage.free), 6));
|
||||
lcd.writeBuf(3, 21, pad(std::to_string(s->gpu.clock_core) + "/" + std::to_string(s->gpu.clock_mem) + "MHz ", 13));
|
||||
lcd.writeBuf(3, 34, pad(pNum(s->gpu.vcore, 3) + "V", 5));
|
||||
lcd.writeBuf(3, 14, utils::pad(lcd.cc(2) + utils::pBytes(s->home.usage.free), 6));
|
||||
lcd.writeBuf(3, 21, utils::pad(std::to_string(s->gpu.clock_core) + "/" + std::to_string(s->gpu.clock_mem) + "MHz ", 13));
|
||||
lcd.writeBuf(3, 34, utils::pad(utils::pNum(s->gpu.vcore, 3) + "V", 5));
|
||||
}
|
||||
|
||||
lcd.flushBuf();
|
||||
@@ -160,7 +160,7 @@ void displayThread(std::stop_token st, Sensors* s) {
|
||||
}
|
||||
|
||||
// goodbye msg
|
||||
lcd.writeBuf(2, 0, center("linuxSmartie closed", 40));
|
||||
lcd.writeBuf(2, 0, utils::center("linuxSmartie closed", 40));
|
||||
lcd.flushBuf();
|
||||
}
|
||||
|
||||
|
||||
22
src/cpu.cpp
22
src/cpu.cpp
@@ -11,7 +11,7 @@ void detectHwmon(cpuSensors* target, const std::string& pci) {
|
||||
std::string path = "/sys/bus/pci/devices/" + pci + "/hwmon";
|
||||
|
||||
try {
|
||||
target->hwmon = getFirstDir(path);
|
||||
target->hwmon = utils::getFirstDir(path);
|
||||
} catch (...) {
|
||||
applog(LOG::ERR, "NO CPU HWMON KERNEL MODULE DETECTED");
|
||||
return;
|
||||
@@ -34,15 +34,15 @@ void update(cpuSensors* c) {
|
||||
// read power from intel-rapl? works on amd too, btop uses this trick, seems accurate
|
||||
// it tracks with "socket power" in hwinfo on windows, its actually the same thing i had in lcdsmartie
|
||||
curr.ts = std::chrono::steady_clock::now();
|
||||
// fastReadNum("/sys/class/powercap/intel-rapl:0/energy_uj", curr.energy);
|
||||
curr.energy = fastReadNum("/sys/class/powercap/intel-rapl:0/energy_uj", buf);
|
||||
// utils::fastReadNum("/sys/class/powercap/intel-rapl:0/energy_uj", curr.energy);
|
||||
curr.energy = utils::fastReadNum("/sys/class/powercap/intel-rapl:0/energy_uj", buf);
|
||||
c->ptotal = (float)(curr.energy - prev.energy) / (float)(std::chrono::duration_cast<std::chrono::microseconds>(curr.ts - prev.ts).count());
|
||||
prev = curr;
|
||||
|
||||
// lots of reads but still faster than reading /proc/cpuinfo
|
||||
c->avg_freq = 0;
|
||||
for (uint8_t i = 0; i < N_CPU; i++) {
|
||||
readFile("/sys/devices/system/cpu/cpu" + std::to_string(i) + "/cpufreq/cpuinfo_avg_freq", buf, sizeof(buf));
|
||||
utils::readFile("/sys/devices/system/cpu/cpu" + std::to_string(i) + "/cpufreq/cpuinfo_avg_freq", buf, sizeof(buf));
|
||||
c->avg_freq += strtol(buf, NULL, 10) / 1000;
|
||||
}
|
||||
c->avg_freq /= N_CPU;
|
||||
@@ -51,14 +51,14 @@ void update(cpuSensors* c) {
|
||||
|
||||
// commented out unused values so its faster
|
||||
if (c->zenpower) {
|
||||
c->tdie = fastReadNum(c->hwmon + "/temp1_input", buf) / 1000;
|
||||
c->tctl = fastReadNum(c->hwmon + "/temp2_input", buf) / 1000;
|
||||
c->tccd1 = fastReadNum(c->hwmon + "/temp3_input", buf) / 1000;
|
||||
c->vcore = fastReadNum(c->hwmon + "/in1_input", buf) / 1000.0;
|
||||
c->vsoc = fastReadNum(c->hwmon + "/in2_input", buf) / 1000.0;
|
||||
c->tdie = utils::fastReadNum(c->hwmon + "/temp1_input", buf) / 1000;
|
||||
c->tctl = utils::fastReadNum(c->hwmon + "/temp2_input", buf) / 1000;
|
||||
c->tccd1 = utils::fastReadNum(c->hwmon + "/temp3_input", buf) / 1000;
|
||||
c->vcore = utils::fastReadNum(c->hwmon + "/in1_input", buf) / 1000.0;
|
||||
c->vsoc = utils::fastReadNum(c->hwmon + "/in2_input", buf) / 1000.0;
|
||||
} else {
|
||||
c->tctl = fastReadNum(c->hwmon + "/temp1_input", buf) / 1000;
|
||||
c->tccd1 = fastReadNum(c->hwmon + "/temp3_input", buf) / 1000;
|
||||
c->tctl = utils::fastReadNum(c->hwmon + "/temp1_input", buf) / 1000;
|
||||
c->tccd1 = utils::fastReadNum(c->hwmon + "/temp3_input", buf) / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
29
src/gpu.cpp
29
src/gpu.cpp
@@ -11,11 +11,10 @@ namespace gpu {
|
||||
|
||||
/* takes pointer to a target gpu::sensors struct and updates its hwmon path and detects gpu_metrics */
|
||||
void detectHwmon(gpuSensors* target, const std::string& pci) {
|
||||
target->hwmon = getFirstDir("/sys/bus/pci/devices/" + pci + "/hwmon");
|
||||
target->hwmon = utils::getFirstDir("/sys/bus/pci/devices/" + pci + "/hwmon");
|
||||
applog(LOG::INF, "Detected path \"{}\"", target->hwmon);
|
||||
|
||||
if (FILE* file = fopen((target->hwmon + REL_METRICS_PATH).c_str(), "r")) {
|
||||
fclose(file);
|
||||
if(utils::fileExists(target->hwmon + REL_METRICS_PATH)) {
|
||||
applog(LOG::INF, "found gpu_metrics");
|
||||
target->hasGpuMetrics = true;
|
||||
}
|
||||
@@ -24,29 +23,29 @@ void detectHwmon(gpuSensors* target, const std::string& pci) {
|
||||
/* some metrics are missing in gpu_metrics, we always fill them from fs, unused metrics are commented out */
|
||||
void fillMissingMetrics(gpuSensors* g) {
|
||||
static char buf[32];
|
||||
g->vcore = fastReadNum(g->hwmon + "/in0_input", buf) / 1000.0;
|
||||
g->vcore = utils::fastReadNum(g->hwmon + "/in0_input", buf) / 1000.0;
|
||||
// g->fan_pwm = std::stoi(readFile(g->hwmon + "/pwm1", 4)) * 100 / 256;
|
||||
g->fan_speed = fastReadNum(g->hwmon + "/fan1_input", buf);
|
||||
g->power_cap = fastReadNum(g->hwmon + "/power1_cap", buf) / 1000000;
|
||||
// fastReadNum(g->hwmon + "/power1_cap_max", g->power_cap_max) / 1000000;
|
||||
g->vram_used = fastReadNum(g->hwmon + "/../../mem_info_vram_used", buf);
|
||||
// fastReadNum(g->hwmon + "/../../mem_info_vram_total", g->vram_total);
|
||||
g->fan_speed = utils::fastReadNum(g->hwmon + "/fan1_input", buf);
|
||||
g->power_cap = utils::fastReadNum(g->hwmon + "/power1_cap", buf) / 1000000;
|
||||
// utils::fastReadNum(g->hwmon + "/power1_cap_max", g->power_cap_max) / 1000000;
|
||||
g->vram_used = utils::fastReadNum(g->hwmon + "/../../mem_info_vram_used", buf);
|
||||
// utils::fastReadNum(g->hwmon + "/../../mem_info_vram_total", g->vram_total);
|
||||
}
|
||||
|
||||
/* get sensors for pre-vega cards (rx480/580) */
|
||||
void updateFromFs(gpuSensors* g) {
|
||||
static char buf[32];
|
||||
g->clock_core = fastReadNum(g->hwmon + "/freq1_input", buf) / 1000000;
|
||||
g->clock_mem = fastReadNum(g->hwmon + "/freq2_input", buf) / 1000000;
|
||||
g->power_avg = fastReadNum(g->hwmon + "/power1_input", buf) / 1000000;
|
||||
g->temp_edge = fastReadNum(g->hwmon + "/temp1_input", buf) / 1000;
|
||||
g->usage_core = fastReadNum(g->hwmon + "/../../gpu_busy_percent", buf);
|
||||
g->clock_core = utils::fastReadNum(g->hwmon + "/freq1_input", buf) / 1000000;
|
||||
g->clock_mem = utils::fastReadNum(g->hwmon + "/freq2_input", buf) / 1000000;
|
||||
g->power_avg = utils::fastReadNum(g->hwmon + "/power1_input", buf) / 1000000;
|
||||
g->temp_edge = utils::fastReadNum(g->hwmon + "/temp1_input", buf) / 1000;
|
||||
g->usage_core = utils::fastReadNum(g->hwmon + "/../../gpu_busy_percent", buf);
|
||||
}
|
||||
|
||||
/* get sensors for vega and newer (rx5700xt, rx7800xt [*]) */
|
||||
void updateFromMetrics(gpuSensors* g) {
|
||||
char raw_metrics[MAX_METRICS_LENGTH];
|
||||
if (!readFile(g->hwmon + REL_METRICS_PATH, raw_metrics, sizeof(raw_metrics))) return;
|
||||
if (!utils::readFile(g->hwmon + REL_METRICS_PATH, raw_metrics, sizeof(raw_metrics))) return;
|
||||
|
||||
auto header = reinterpret_cast<metrics::metrics_table_header*>(raw_metrics);
|
||||
switch (header->format_revision * 10 + header->content_revision) {
|
||||
|
||||
14
src/sys.cpp
14
src/sys.cpp
@@ -29,7 +29,7 @@ void sys::getTimeDate(TimeDate* td) {
|
||||
|
||||
void sys::getRam(Memory* mem) {
|
||||
static char buf[128]; // file is longer but we only need first 128 chars
|
||||
readFile("/proc/meminfo", buf, sizeof(buf));
|
||||
utils::readFile("/proc/meminfo", buf, sizeof(buf));
|
||||
mem->free = getVal("MemAvailable:", std::string_view(buf));
|
||||
mem->total = getVal("MemTotal:", std::string_view(buf));
|
||||
mem->used = mem->total - mem->free;
|
||||
@@ -55,8 +55,8 @@ void sys::getNetwork(Network* net, const std::string& device) {
|
||||
_net current;
|
||||
|
||||
current.ts = std::chrono::steady_clock::now();
|
||||
current.rx = fastReadNum("/sys/class/net/" + device + "/statistics/rx_bytes", buf);
|
||||
current.tx = fastReadNum("/sys/class/net/" + device + "/statistics/tx_bytes", buf);
|
||||
current.rx = utils::fastReadNum("/sys/class/net/" + device + "/statistics/rx_bytes", buf);
|
||||
current.tx = utils::fastReadNum("/sys/class/net/" + device + "/statistics/tx_bytes", buf);
|
||||
float ts_diff = std::chrono::duration_cast<std::chrono::microseconds>(current.ts - prev.ts).count() / 1000000.0f;
|
||||
net->download = (current.rx - prev.rx) / ts_diff;
|
||||
net->upload = (current.tx - prev.tx) / ts_diff;
|
||||
@@ -66,7 +66,7 @@ void sys::getNetwork(Network* net, const std::string& device) {
|
||||
void sys::detectHwmon(sysSensors* s, const std::string& platform) {
|
||||
// we dont really need getFirstDir since its a static folder, but its useful for try/catch
|
||||
try {
|
||||
s->hwmon = getFirstDir("/sys/devices/platform/" + platform + "/hwmon");
|
||||
s->hwmon = utils::getFirstDir("/sys/devices/platform/" + platform + "/hwmon");
|
||||
} catch (...) {
|
||||
applog(LOG::ERR, "Can't open sys hwmon. Module loaded? Kernel params added?");
|
||||
return;
|
||||
@@ -77,7 +77,7 @@ void sys::updateSensors(sysSensors* s) {
|
||||
if (s->hwmon.length() < 1)
|
||||
return;
|
||||
static char buf[8];
|
||||
s->fan_speed[0] = fastReadNum(s->hwmon + "/fan2_input", buf);
|
||||
s->fan_speed[1] = fastReadNum(s->hwmon + "/fan7_input", buf);
|
||||
s->t_sensor = fastReadNum(s->hwmon + "/temp5_input", buf) / 1000;
|
||||
s->fan_speed[0] = utils::fastReadNum(s->hwmon + "/fan2_input", buf);
|
||||
s->fan_speed[1] = utils::fastReadNum(s->hwmon + "/fan7_input", buf);
|
||||
s->t_sensor = utils::fastReadNum(s->hwmon + "/temp5_input", buf) / 1000;
|
||||
}
|
||||
|
||||
@@ -11,10 +11,12 @@
|
||||
#include <string_view>
|
||||
#include <utils.hpp>
|
||||
|
||||
namespace utils {
|
||||
|
||||
/* pads given string to length */
|
||||
std::string pad(std::string s, uint8_t len, JUST j) {
|
||||
std::string pad(std::string s, uint8_t len, just j) {
|
||||
if (len > s.size())
|
||||
s.insert(j == JUST::LEFT ? s.end() : s.begin(), len - s.size(), FILL_CHAR);
|
||||
s.insert(j == just::left ? s.end() : s.begin(), len - s.size(), FILL_CHAR);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -65,3 +67,5 @@ std::string getFirstDir(std::string_view path) {
|
||||
return entry.path();
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user