#include #include #include #include #include #include #include #include int getVal(const std::string_view target, std::string_view content) { int result = -1; if (const std::size_t start = content.find(target); start != std::string::npos) { content.remove_prefix(start + target.length()); const std::size_t end = content.find(" kB"); while (std::isspace(content.front())) content.remove_prefix(1); std::from_chars(content.data(), content.data() + end, result); } return result; } void sys::getTimeDate(TimeDate* td) { const auto now = std::chrono::system_clock::now(); const auto local = std::chrono::current_zone()->to_local(now); const std::chrono::year_month_day ymd{floor(local)}; const std::chrono::weekday wd{floor(local)}; td->time = std::format("{:%H:%M:%S}", floor(local)); td->date = std::format("{}, {} {}", wdays[wd.c_encoding()], ymd.day(), months[static_cast(ymd.month()) - 1]); } void sys::getRam(Memory* mem) { static std::array buf; // file is longer but we only need first 128 chars utils::readFile("/proc/meminfo", buf); mem->free = getVal("MemAvailable:", std::string_view(buf)); mem->total = getVal("MemTotal:", std::string_view(buf)); // shouldn't really update this on each loop mem->used = mem->total - mem->free; } void sys::getDisk(Disk* disk) { struct statvfs diskData{}; statvfs(disk->mountpoint.c_str(), &diskData); disk->usage.free = diskData.f_bfree * diskData.f_frsize; disk->usage.used = (diskData.f_blocks - diskData.f_bfree) * diskData.f_frsize; disk->usage.total = diskData.f_blocks * diskData.f_frsize; } void sys::getNetwork(Network* net, const std::string& device) { struct Network { std::chrono::time_point ts; uint64_t rx = 0; uint64_t tx = 0; }; static std::array buf; static Network prev; Network current; current.ts = std::chrono::steady_clock::now(); utils::fastReadNum("/sys/class/net/" + device + "/statistics/rx_bytes", buf, current.rx); utils::fastReadNum("/sys/class/net/" + device + "/statistics/tx_bytes", buf, current.tx); const double ts_diff = static_cast(std::chrono::duration_cast(current.ts - prev.ts).count()) / 1000000.0f; net->download = static_cast(static_cast(current.rx - prev.rx) / ts_diff); net->upload = static_cast(static_cast(current.tx - prev.tx) / ts_diff); prev = current; } int sys::detect(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 = utils::getFirstDir("/sys/devices/platform/" + platform + "/hwmon"); } catch (...) { applog(LOG::ERR, "Can't open \"/sys/devices/platform/{}/hwmon\". Kernel params added? Module loaded?", platform); return -1; } applog(LOG::INF, "Found system sensors"); return 0; } void sys::updateSensors(sysSensors* s) { if (s->hwmon.empty()) return; static std::array buf; utils::fastReadNum(s->hwmon + "/fan2_input", buf, s->fan_speed[0]); utils::fastReadNum(s->hwmon + "/fan7_input", buf, s->fan_speed[1]); utils::fastReadNum<1000>(s->hwmon + "/temp5_input", buf, s->t_sensor); }