bunch of shit clang-tidy and clion made me do
This commit is contained in:
@@ -12,7 +12,7 @@ class LCDDisplay {
|
||||
private:
|
||||
int _lcd = -1;
|
||||
std::string _dev;
|
||||
char writebuf[LCD_LINES * LCD_COLS + 8]; // 4x40 chars + 2x4 setcursor commands
|
||||
char writebuf[LCD_LINES * LCD_COLS + 8]{}; // 4x40 chars + 2x4 setcursor commands
|
||||
static constexpr bool dualDisp = (LCD_LINES * LCD_COLS > 80); // is it dual display device or not, evauluated from the size at compile time
|
||||
|
||||
void open(bool reopen = false);
|
||||
@@ -24,7 +24,7 @@ class LCDDisplay {
|
||||
void writeStr(uint8_t row, uint8_t col, std::string str);
|
||||
|
||||
public:
|
||||
LCDDisplay(std::string dev, uint32_t baud = 0010002); // from termios-baud.h, B115200
|
||||
explicit LCDDisplay(std::string dev, uint32_t baud = 0010002); // from termios-baud.h, B115200
|
||||
~LCDDisplay();
|
||||
|
||||
void clear();
|
||||
@@ -40,7 +40,7 @@ class LCDDisplay {
|
||||
char bar(uint8_t char_id, double value);
|
||||
|
||||
// returns custom char no. c, small enough to define in header
|
||||
constexpr char cc(uint8_t c) { return c % 8; }
|
||||
static constexpr char cc(const uint8_t c) { return c % 8; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
namespace cpu {
|
||||
|
||||
struct cpuSensors {
|
||||
std::string hwmon = "";
|
||||
std::string hwmon;
|
||||
bool zenpower = false;
|
||||
|
||||
int tdie = 0;
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
namespace gpu {
|
||||
|
||||
struct gpuSensors {
|
||||
std::string hwmon = "";
|
||||
std::string hwmon;
|
||||
bool hasGpuMetrics = false;
|
||||
|
||||
float vcore = 0.0f;
|
||||
double vcore = 0.0f;
|
||||
|
||||
uint16_t clock_core = 0;
|
||||
uint16_t clock_mem = 0;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define LOG_HPP
|
||||
|
||||
// comment out to disable logging in general
|
||||
#define applog(level, fmt, ...) _log(level, std::source_location::current(), fmt, ##__VA_ARGS__)
|
||||
#define applog(level, fmt, ...) utils::log(level, std::source_location::current(), fmt, ##__VA_ARGS__)
|
||||
// comment out to disable logging to file
|
||||
// #define LOG_FILE_LOCATION "linuxSmartie.log.gz"
|
||||
|
||||
@@ -19,24 +19,26 @@
|
||||
inline std::mutex fmtx; // file logging mutex
|
||||
#endif
|
||||
|
||||
inline std::mutex cmtx; // console logging mutex
|
||||
enum class LOG { INF, WRN, ERR, DBG, START };
|
||||
|
||||
constexpr std::string_view pFname(std::string_view full) {
|
||||
if (auto pos = full.find(' '); pos != std::string_view::npos)
|
||||
namespace utils {
|
||||
inline std::mutex cmtx; // console logging mutex
|
||||
|
||||
constexpr std::string pFname(std::string_view full) {
|
||||
if (const auto pos = full.find(' '); pos != std::string_view::npos)
|
||||
full.remove_prefix(pos + 1);
|
||||
|
||||
if (auto pos = full.rfind('('); pos != std::string_view::npos)
|
||||
if (const auto pos = full.rfind('('); pos != std::string_view::npos)
|
||||
full.remove_suffix(full.size() - pos);
|
||||
|
||||
return full;
|
||||
return std::string(full);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void _log(LOG level, const std::source_location& loc, std::format_string<Args...> str, Args&&... args) {
|
||||
void log(LOG level, const std::source_location& loc, std::format_string<Args...> str, Args&&... args) {
|
||||
constexpr std::string_view reset = "\033[0m";
|
||||
constexpr std::string_view pattern = "[{}{}{}] ";
|
||||
std::string_view color = "";
|
||||
std::string_view color;
|
||||
|
||||
switch (level) {
|
||||
case LOG::INF:
|
||||
@@ -80,6 +82,7 @@ inline void _log(LOG level, const std::source_location& loc, std::format_string<
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace utils {
|
||||
|
||||
const char FILL_CHAR = ' ';
|
||||
constexpr char fill_char = ' ';
|
||||
|
||||
enum just { right,
|
||||
left };
|
||||
@@ -16,21 +16,23 @@ enum just { right,
|
||||
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);
|
||||
ssize_t readFile(const std::string& path, char* buffer, size_t maxlen);
|
||||
ssize_t readFile(const char* path, char* buffer, size_t maxlen);
|
||||
std::string getFirstDir(std::string_view path);
|
||||
std::string getFirstDir(const std::string_view& path);
|
||||
|
||||
template <size_t N>
|
||||
inline long long fastReadNum(const std::string& path, char (&buf)[N]) {
|
||||
inline int fastReadNum(const std::string& path, char (&buf)[N]) {
|
||||
readFile(path, buf, N);
|
||||
return std::strtoll(buf, nullptr, 10);
|
||||
int ret = 0;
|
||||
std::from_chars(buf, buf + N, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline std::string pNum(auto num, uint8_t decs = 0) {
|
||||
return std::format("{:.{}f}", num, decs);
|
||||
}
|
||||
|
||||
inline bool fileExists(std::string_view path) {
|
||||
inline bool fileExists(const std::string_view& path) {
|
||||
return std::filesystem::exists(path);
|
||||
}
|
||||
|
||||
|
||||
18
src/app.cpp
18
src/app.cpp
@@ -19,14 +19,14 @@
|
||||
namespace app {
|
||||
|
||||
const std::string lcd_port = "/dev/serial/by-id/usb-Raspberry_Pi_Pico_E6616407E37AA12F-if00"; // tis a symlink, can also be just /dev/ttyACM0
|
||||
const uint16_t lcd_interval_ms = 500;
|
||||
const uint8_t lcd_contrast = 215;
|
||||
constexpr uint16_t lcd_interval_ms = 500;
|
||||
constexpr uint8_t lcd_contrast = 215;
|
||||
|
||||
const std::string cpu_pciaddr = "0000:00:18.3";
|
||||
const std::string gpu_pciaddr = "0000:0b:00.0";
|
||||
const std::string sys_sensor = "nct6775.656";
|
||||
const std::string sys_ifname = "enp4s0f0";
|
||||
const std::string home_dir = "/home/drath";
|
||||
constexpr std::string home_dir = "/home/drath";
|
||||
|
||||
namespace semaphores {
|
||||
std::binary_semaphore display{0};
|
||||
@@ -39,7 +39,7 @@ void signalHandler(int) {
|
||||
app::semaphores::display.release();
|
||||
}
|
||||
|
||||
void hassThread(std::stop_token st, app::sensors& s) {
|
||||
void hassThread(const std::stop_token& st, app::sensors& s) {
|
||||
applog(LOG::START, "Thread started");
|
||||
HomeAssistant pc_power("home.drath.win", "sensor.gniazdko_komputer_moc");
|
||||
|
||||
@@ -54,7 +54,7 @@ void hassThread(std::stop_token st, app::sensors& s) {
|
||||
}
|
||||
}
|
||||
|
||||
void sensorsThread(std::stop_token st, app::sensors& s) {
|
||||
void sensorsThread(const std::stop_token& st, app::sensors& s) {
|
||||
applog(LOG::START, "Thread started, poll interval {} ms", lcd_interval_ms);
|
||||
cpu::detectHwmon(&s.cpu, cpu_pciaddr);
|
||||
gpu::detectHwmon(&s.gpu, gpu_pciaddr);
|
||||
@@ -82,7 +82,7 @@ void sensorsThread(std::stop_token st, app::sensors& s) {
|
||||
}
|
||||
}
|
||||
|
||||
void displayThread(std::stop_token st, app::sensors& s) {
|
||||
void displayThread(const std::stop_token& st, app::sensors& s) {
|
||||
applog(LOG::START, "Thread started");
|
||||
// init internal variables of LCDDisplay class
|
||||
LCDDisplay lcd(lcd_port);
|
||||
@@ -113,7 +113,7 @@ void displayThread(std::stop_token st, app::sensors& s) {
|
||||
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)
|
||||
for (const auto& fan : s.sys.fan_speed)
|
||||
cpu_fan += fan;
|
||||
cpu_fan /= 2;
|
||||
|
||||
@@ -130,7 +130,7 @@ void displayThread(std::stop_token st, app::sensors& s) {
|
||||
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, utils::pad(std::to_string((int)s.cpu.ptotal) + "W", 8, utils::just::left));
|
||||
lcd.writeBuf(2, 0, utils::pad(std::to_string(static_cast<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) + utils::pBytes(s.net.upload));
|
||||
lcd.writeBuf(2, 19, lcd.cc(4) + utils::pBytes(s.net.download));
|
||||
@@ -152,7 +152,7 @@ void displayThread(std::stop_token st, app::sensors& s) {
|
||||
lcd.flushBuf();
|
||||
}
|
||||
|
||||
void start(void) {
|
||||
void start() {
|
||||
applog(LOG::START, "Application started");
|
||||
std::signal(SIGINT, app::signalHandler);
|
||||
std::signal(SIGTERM, app::signalHandler);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
namespace cpu {
|
||||
|
||||
void detectHwmon(cpuSensors* target, const std::string& pci) {
|
||||
std::string path = "/sys/bus/pci/devices/" + pci + "/hwmon";
|
||||
const std::string path = "/sys/bus/pci/devices/" + pci + "/hwmon";
|
||||
|
||||
try {
|
||||
target->hwmon = utils::getFirstDir(path);
|
||||
@@ -36,18 +36,18 @@ void update(cpuSensors* c) {
|
||||
curr.ts = std::chrono::steady_clock::now();
|
||||
// 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());
|
||||
c->ptotal = static_cast<float>(curr.energy - prev.energy) / static_cast<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++) {
|
||||
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 += strtol(buf, nullptr, 10) / 1000;
|
||||
}
|
||||
c->avg_freq /= N_CPU;
|
||||
|
||||
if (c->hwmon == "") return; // break if no module
|
||||
if (c->hwmon.empty()) return; // break if no module
|
||||
|
||||
// commented out unused values so its faster
|
||||
if (c->zenpower) {
|
||||
|
||||
11
src/gpu.cpp
11
src/gpu.cpp
@@ -50,11 +50,10 @@ void updateFromMetrics(gpuSensors* g) {
|
||||
char raw_metrics[max_metrics_length];
|
||||
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) {
|
||||
switch (const auto header = reinterpret_cast<metrics::metrics_table_header*>(raw_metrics); header->format_revision * 10 + header->content_revision) {
|
||||
/* rx5700xt, rx7800xt */
|
||||
case 13: {
|
||||
auto metrics = reinterpret_cast<metrics::gpu_metrics_v1_3*>(raw_metrics);
|
||||
const auto metrics = reinterpret_cast<metrics::gpu_metrics_v1_3*>(raw_metrics);
|
||||
g->usage_core = metrics->average_gfx_activity;
|
||||
g->usage_umc = metrics->average_umc_activity;
|
||||
g->usage_media = metrics->average_mm_activity;
|
||||
@@ -81,7 +80,7 @@ void updateFromMetrics(gpuSensors* g) {
|
||||
|
||||
/* ryzen 5 5600g */
|
||||
case 22: {
|
||||
auto metrics = reinterpret_cast<metrics::gpu_metrics_v2_2*>(raw_metrics);
|
||||
const auto metrics = reinterpret_cast<metrics::gpu_metrics_v2_2*>(raw_metrics);
|
||||
g->temp_edge = metrics->temperature_gfx / 100;
|
||||
break;
|
||||
}
|
||||
@@ -99,9 +98,9 @@ void update(gpuSensors* g) {
|
||||
fillMissingMetrics(g);
|
||||
|
||||
if (g->hasGpuMetrics)
|
||||
gpu::updateFromMetrics(g);
|
||||
updateFromMetrics(g);
|
||||
else
|
||||
gpu::updateFromFs(g);
|
||||
updateFromFs(g);
|
||||
|
||||
if (g->fan_speed > 9999) g->fan_speed = 9999; // sanity check fan speed
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
||||
#include <format>
|
||||
#include <log.hpp>
|
||||
@@ -14,24 +13,23 @@
|
||||
namespace utils {
|
||||
|
||||
/* pads given string to length */
|
||||
std::string pad(std::string s, uint8_t len, just j) {
|
||||
std::string pad(std::string s, const 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 == left ? s.end() : s.begin(), len - s.size(), fill_char);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* returns the string centered within given length */
|
||||
std::string center(std::string str, uint8_t len) {
|
||||
uint8_t padding = len - str.size();
|
||||
str.insert(str.begin(), padding / 2, FILL_CHAR);
|
||||
str.insert(str.end(), padding / 2, FILL_CHAR);
|
||||
std::string center(std::string str, const uint8_t len) {
|
||||
const uint8_t padding = len - str.size();
|
||||
str.insert(str.begin(), padding / 2, fill_char);
|
||||
str.insert(str.end(), padding / 2, fill_char);
|
||||
return str;
|
||||
}
|
||||
|
||||
/* converts large number in (k)bytes to human readable numer with suffix and sane decimal */
|
||||
std::string pBytes(double bytes, bool isKbytes) {
|
||||
std::array suffix_list = {'K', 'M', 'G', 'T', 'P', 'E', 'Z'};
|
||||
for (auto& suffix : suffix_list) {
|
||||
/* converts large number in (k)bytes to human-readable numer with suffix and sane decimal */
|
||||
std::string pBytes(double bytes, const bool isKbytes) {
|
||||
for (constexpr std::array suffix_list = {'K', 'M', 'G', 'T', 'P', 'E', 'Z'}; const auto& suffix : suffix_list) {
|
||||
if (suffix == 'K' && isKbytes) continue; // skip first loop if already in Kbytes
|
||||
bytes /= 1024.0;
|
||||
if (bytes < 1024) {
|
||||
@@ -45,24 +43,24 @@ std::string pBytes(double bytes, bool isKbytes) {
|
||||
|
||||
/* reads maxlen of chars of the file in path into buffer */
|
||||
ssize_t readFile(const char* path, char* buffer, size_t maxlen) {
|
||||
int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
const int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
applog(LOG::ERR, "Error reading {}", path);
|
||||
return 0;
|
||||
}
|
||||
ssize_t len = read(fd, buffer, maxlen - 1);
|
||||
const ssize_t len = read(fd, buffer, maxlen - 1);
|
||||
if (len >= 0) buffer[len] = '\0';
|
||||
close(fd);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* overload so it takes std::string as path */
|
||||
ssize_t readFile(const std::string path, char* buffer, size_t maxlen) {
|
||||
ssize_t readFile(const std::string& path, char* buffer, size_t maxlen) {
|
||||
return readFile(path.c_str(), buffer, maxlen);
|
||||
}
|
||||
|
||||
/* finds first dir in path and returns it. dont refactor, you dont understand it, its fast enough and you only use it on init */
|
||||
std::string getFirstDir(std::string_view path) {
|
||||
/* finds first dir in path and returns it. don't refactor, you don't understand it, its fast enough, and you only use it on init */
|
||||
std::string getFirstDir(const std::string_view& path) {
|
||||
for (const auto& entry : std::filesystem::directory_iterator(path))
|
||||
return entry.path();
|
||||
return "";
|
||||
|
||||
Reference in New Issue
Block a user