Files
linuxSmartie/src/sys.cpp
2026-02-27 23:16:49 +01:00

88 lines
3.5 KiB
C++

#include <sys/statvfs.h>
#include <charconv>
#include <chrono>
#include <format>
#include <log.hpp>
#include <string>
#include <sys.hpp>
#include <utils.hpp>
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<std::chrono::days>(local)};
const std::chrono::weekday wd{floor<std::chrono::days>(local)};
td->time = std::format("{:%H:%M:%S}", floor<std::chrono::seconds>(local));
td->date = std::format("{}, {} {}", wdays[wd.c_encoding()], ymd.day(), months[static_cast<unsigned>(ymd.month()) - 1]);
}
void sys::getRam(Memory* mem) {
static std::array<char, 128> 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<std::chrono::steady_clock> ts;
uint64_t rx = 0;
uint64_t tx = 0;
};
static std::array<char, 32> 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<double>(std::chrono::duration_cast<std::chrono::microseconds>(current.ts - prev.ts).count()) / 1000000.0f;
net->download = static_cast<uint32_t>(static_cast<double>(current.rx - prev.rx) / ts_diff);
net->upload = static_cast<uint32_t>(static_cast<double>(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<char, 8> 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);
}