diff --git a/include/LCDDisplay.hpp b/include/LCDDisplay.hpp index 7c7937d..89af818 100644 --- a/include/LCDDisplay.hpp +++ b/include/LCDDisplay.hpp @@ -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 diff --git a/include/cpu.hpp b/include/cpu.hpp index bf8f5fd..3bd4abc 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -9,7 +9,7 @@ namespace cpu { struct cpuSensors { - std::string hwmon = ""; + std::string hwmon; bool zenpower = false; int tdie = 0; diff --git a/include/gpu.hpp b/include/gpu.hpp index 58e7e6e..0d29e1e 100644 --- a/include/gpu.hpp +++ b/include/gpu.hpp @@ -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; diff --git a/include/log.hpp b/include/log.hpp index 7ac76af..b244573 100644 --- a/include/log.hpp +++ b/include/log.hpp @@ -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 -inline void _log(LOG level, const std::source_location& loc, std::format_string str, Args&&... args) { +void log(LOG level, const std::source_location& loc, std::format_string 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 diff --git a/include/utils.hpp b/include/utils.hpp index 5ba6945..926333d 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -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 -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); } diff --git a/src/app.cpp b/src/app.cpp index 513db28..263cf8e 100644 --- a/src/app.cpp +++ b/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(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); diff --git a/src/cpu.cpp b/src/cpu.cpp index e15a1a9..32d903d 100644 --- a/src/cpu.cpp +++ b/src/cpu.cpp @@ -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(curr.ts - prev.ts).count()); + c->ptotal = static_cast(curr.energy - prev.energy) / static_cast(std::chrono::duration_cast(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) { diff --git a/src/gpu.cpp b/src/gpu.cpp index cc06bcf..c389813 100644 --- a/src/gpu.cpp +++ b/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(raw_metrics); - switch (header->format_revision * 10 + header->content_revision) { + switch (const auto header = reinterpret_cast(raw_metrics); header->format_revision * 10 + header->content_revision) { /* rx5700xt, rx7800xt */ case 13: { - auto metrics = reinterpret_cast(raw_metrics); + const auto metrics = reinterpret_cast(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(raw_metrics); + const auto metrics = reinterpret_cast(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 } diff --git a/src/utils.cpp b/src/utils.cpp index 70de193..396f5b4 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -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 "";