This commit is contained in:
2026-05-10 21:17:36 +02:00
parent f28cd4c31a
commit 9bd2357b96
7 changed files with 118 additions and 33 deletions

View File

@@ -14,7 +14,7 @@ void cpu_detect(struct cpu_sensors_t *t, const char *pci_dev) {
snprintf(t->hwmon, sizeof(t->hwmon), "/sys/bus/pci/devices/%s/hwmon", pci_dev);
const int ret = get_hwmon_dir(t->hwmon);
if (ret != 0) {
memset(t->hwmon, '\0', sizeof(t->hwmon));
t->hwmon[0] = '\0';
applog(LOG_WRN, "Detected %d cores, module enum #%d. Can't get hwmon path, skipping", t->num_cores, t->module);
return;
}
@@ -41,7 +41,7 @@ void cpu_update(struct cpu_sensors_t *c) {
clock_gettime(CLOCK_MONOTONIC, &curr.ts);
fast_read_num_u64("/sys/class/powercap/intel-rapl:0", "energy_uj", buf, &curr.energy, 1);
c->ptotal = (float)(curr.energy - prev.energy) / (float)((curr.ts.tv_nsec - prev.ts.tv_nsec) / 1000);
c->ptotal = (float)(curr.energy - prev.energy) / (float)timespec_diff_us(&curr.ts, &prev.ts);
prev = curr;
// lots of reads but still faster than reading /proc/cpuinfo
@@ -58,6 +58,11 @@ void cpu_update(struct cpu_sensors_t *c) {
if (c->module == unknown)
return;
if (c->module == k10temp) {
fast_read_num_i16(c->hwmon, "/temp1_input", buf, &c->tctl, 1000);
fast_read_num_i16(c->hwmon, "/temp3_input", buf, &c->tccd1, 1000);
}
// commented out unused values so its faster
if (c->module == zenpower) {
fast_read_num_i16(c->hwmon, "/temp1_input", buf, &c->tdie, 1000);
@@ -66,10 +71,4 @@ void cpu_update(struct cpu_sensors_t *c) {
// utils::fastReadNum<1000>(c->hwmon + "/in1_input", buf, c->vcore);
// utils::fastReadNum<1000>(c->hwmon + "/in2_input", buf, c->vsoc);
}
if (c->module == k10temp) {
fast_read_num_i16(c->hwmon, "/temp1_input", buf, &c->tctl, 1000);
fast_read_num_i16(c->hwmon, "/temp3_input", buf, &c->tccd1, 1000);
}
}

View File

@@ -16,15 +16,6 @@
static constexpr uint16_t refresh_interval_ms = 500;
/* move to utils */
static void timespec_add_ms(struct timespec *ts, const uint16_t ms) {
ts->tv_nsec += ms * 1000000L;
if (ts->tv_nsec >= 1000000000L) {
ts->tv_sec++;
ts->tv_nsec -= 1000000000L;
}
}
struct control_t {
pthread_mutex_t sensors_mtx;
pthread_cond_t sensors_ready;
@@ -36,8 +27,8 @@ struct sensors_t {
double loadavg[3];
struct memory_t ram;
struct disk_t home;
// sys::Network net;
// sys::sysSensors sys;
struct network_t net;
struct syssensors_t sys;
struct cpu_sensors_t cpu;
// gpu::gpuSensors gpu;
double hass_state;
@@ -52,7 +43,9 @@ static void *sensors_thread(void *arg) {
// set up paths for the sensors
strcpy(sensors->home.mountpoint, "/home/drath");
strcpy(sensors->net.device, "enp7s0");
cpu_detect(&sensors->cpu, "0000:00:18.3");
sys_detect(&sensors->sys, "nct6775.656");
while (control.g_running) { // NOLINT
pthread_mutex_lock(&control.sensors_mtx);
@@ -61,11 +54,13 @@ static void *sensors_thread(void *arg) {
sys_get_time(&sensors->td);
sys_get_ram(&sensors->ram);
sys_get_disk(&sensors->home);
sys_get_network(&sensors->net);
sys_update_sensors(&sensors->sys);
cpu_update(&sensors->cpu);
pthread_cond_signal(&control.sensors_ready);
pthread_mutex_unlock(&control.sensors_mtx);
pthread_cond_signal(&control.sensors_ready);
timespec_add_ms(&next, refresh_interval_ms);
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &next, nullptr);
@@ -108,9 +103,22 @@ static void *display_thread(void *arg) {
pthread_mutex_lock(&control.sensors_mtx); // lock sensor struct
pthread_cond_timedwait(&control.sensors_ready, &control.sensors_mtx, &ts); // wait until data ready
const uint16_t avg_fan_speed = (sensors->sys.fan_speed[0] + sensors->sys.fan_speed[1]) / 2;
lcd_writef(&lcd, 0, 0, "%s %s", sensors->td.date, sensors->td.time);
lcd_writef(&lcd, 26, 0, "%.2f %.2f %.2f", sensors->loadavg[0], sensors->loadavg[1], sensors->loadavg[2]);
lcd_writef(&lcd, 0, 1, "%d/%d%c", sensors->cpu.tctl, sensors->cpu.tccd1, 0);
lcd_writef(&lcd, 7, 1, "%s", P_BYTES(sensors->ram.used, 0));
lcd_writef(&lcd, 20, 1, "%d%c", sensors->sys.t_sensor, 0);
lcd_writef(&lcd, 0, 2, "%.0fW", sensors->cpu.ptotal);
lcd_writef(&lcd, 5, 2, "%dR", avg_fan_speed);
lcd_writef(&lcd, 12, 2, "%c%s %c%s", 3, P_BYTES(sensors->net.upload, 1), 4, P_BYTES(sensors->net.download, 1));
lcd_writef(&lcd, 0, 3, "%dMHz", sensors->cpu.avg_freq);
lcd_writef(&lcd, 14, 3, "%c%s", 2, P_BYTES(sensors->home.usage.free, 1));
pthread_mutex_unlock(&control.sensors_mtx); // unlock sensor struct
lcd_flush_buf(&lcd);

View File

@@ -1,13 +1,14 @@
#include "sys.h"
#include "utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/statvfs.h>
#include "sys.h"
#include "log.h"
#include "utils.h"
void sys_get_time(struct time_date_t *td) {
constexpr char months[][4] = {"sty", "lut", "mar", "kwi", "maj", "cze", "lip", "sie", "wrz", "paz", "lis", "gru"};
constexpr char wdays[][4] = {"Nie", "Pon", "Wto", "Sro", "Czw", "Pia", "Sob"};
@@ -61,10 +62,29 @@ void sys_get_network(struct network_t* network) {
clock_gettime(CLOCK_MONOTONIC, &current.ts);
fast_read_num_u64(path, "rx_bytes", buf, &current.rx, 1);
fast_read_num_u64(path, "tx_bytes", buf, &current.rx, 1);
const double ts_diff = (current.ts.tv_sec - prev.ts.tv_sec) + (current.ts.tv_nsec - prev.ts.tv_nsec) / 1000000000.0;
network->download = (current.rx - prev.rx) / ts_diff;
network->upload = (current.tx - prev.tx) / ts_diff;
fast_read_num_u64(path, "tx_bytes", buf, &current.tx, 1);
const double diff_s = (double)timespec_diff_us(&current.ts, &prev.ts) / 1000000.0;
network->download = (uint32_t)((double)(current.rx - prev.rx) / diff_s);
network->upload = (uint32_t)((double)(current.tx - prev.tx) / diff_s);
prev = current;
}
}
void sys_detect(struct syssensors_t* s, const char* platform) {
snprintf(s->hwmon, sizeof(s->hwmon), "/sys/devices/platform/%s/hwmon", platform);
const int ret = get_hwmon_dir(s->hwmon);
if (ret != 0) {
s->hwmon[0] = '\0';
applog(LOG_WRN, "Can't open system hwmon. Kernel params added? Module loaded? See README");
return;
}
applog(LOG_INF, "Detected system sensors in %s", s->hwmon);
}
void sys_update_sensors(struct syssensors_t* s) {
if (!s->hwmon[0])
return;
static char buf[8];
fast_read_num_u16(s->hwmon, "/fan2_input", buf, &s->fan_speed[0], 1);
fast_read_num_u16(s->hwmon, "/fan7_input", buf, &s->fan_speed[1], 1);
fast_read_num_i16(s->hwmon, "/temp5_input", buf, &s->t_sensor, 1000);
}

View File

@@ -4,12 +4,42 @@
#include <unistd.h>
#include <glob.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
#include "log.h"
#include "utils.h"
#define MKPATH(path, dir, file) do {char *nt = stpcpy(path, dir); *nt++ = '/'; stpcpy(nt, file); } while (0)
inline void timespec_add_ms(struct timespec *ts, const uint16_t ms) {
ts->tv_nsec += ms * 1000000L;
if (ts->tv_nsec >= 1000000000L) {
ts->tv_sec++;
ts->tv_nsec -= 1000000000L;
}
}
inline uint64_t timespec_diff_us(const struct timespec *a, const struct timespec *b) {
const int64_t sec = a->tv_sec - b->tv_sec;
const int64_t nsec = a->tv_nsec - b->tv_nsec;
return sec * 1000000LL + nsec / 1000LL;
}
char *pretty_bytes(const uint64_t bytes, int8_t start_suffix, char *buf, const size_t bufsz) {
constexpr char suffix_list[] = {'K', 'M', 'G', 'T', 'P', 'E', 'Z'};
start_suffix *= -1;
double bytes_d = (double)bytes;
while (bytes_d > 1024.0) {
bytes_d /= 1024.0;
start_suffix++;
}
const uint8_t decimals = (bytes_d < 10) ? 2 : (bytes_d < 100) ? 1 : 0;
snprintf(buf, bufsz, "%.*f%c", decimals, bytes_d, suffix_list[MAX(0, start_suffix)]);
return buf;
}
inline bool file_exists(const char* path) {
return access(path, F_OK) == 0;
}
@@ -17,10 +47,10 @@ inline bool file_exists(const char* path) {
/* path has to have at least 8 free chars at the end for glob */
int get_hwmon_dir(char* path) {
glob_t g;
strncat(path, "/hwmon*", 8);
strncat(path, "/hwmon*", 10);
if (glob(path, 0, nullptr, &g) == 0) {
strncpy(path, g.gl_pathv[0], 256);
strncpy(path, g.gl_pathv[0], 128); // bug prone, careful
globfree(&g);
return 0;
}
@@ -47,6 +77,13 @@ inline void fast_read_num_u64(const char* dir, const char* file, char* buf, uint
*result = strtoull(buf, nullptr, 10) / divider;
}
inline void fast_read_num_u16(const char* dir, const char* file, char* buf, uint16_t* result, const uint16_t divider) {
char path[256];
MKPATH(path, dir, file);
read_file(path, buf, 32);
*result = strtol(buf, nullptr, 10) / divider;
}
inline void fast_read_num_i16(const char* dir, const char* file, char* buf, int16_t* result, const uint16_t divider) {
char path[256];
MKPATH(path, dir, file);