From f0dc384d373c9ce1b20ff239773d80ac2495385a Mon Sep 17 00:00:00 2001 From: Drath Date: Mon, 11 May 2026 01:44:12 +0200 Subject: [PATCH] implemented gpu, rest of the shit, mostly works except for hass --- README.md | 5 ++--- include/utils.h | 9 ++++++--- src/main.c | 33 +++++++++++++++++++++++++++------ src/utils.c | 22 ++++++++++++++++++---- 4 files changed, 53 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 0b855d4..5b0ad25 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,8 @@ Vaguely inspired by suckless software philosophy, as in: Same as plugins. Just write in more features scrub, learn some C, damn ## TODOs (real) -- still missing gpu and hass -- and the lil gpu usage bar, should just work -- idk some formatting? we had a lot of that on c++ ver +- still missing hass +- idk some formatting? we had a lot of that on c++ ver, might be buggy - halts to wait for sensors p long on boot, ig its a minor detail but still ## TODOs diff --git a/include/utils.h b/include/utils.h index f6387b0..0c76c0e 100644 --- a/include/utils.h +++ b/include/utils.h @@ -7,11 +7,14 @@ uint64_t timespec_diff_us(const struct timespec *a, const struct timespec *b); void timespec_add_ms(struct timespec *ts, uint16_t ms); char *pretty_bytes(uint64_t bytes, int8_t start_suffix, char *buf, size_t bufsz); -void fast_read_num_u64(const char* dir, const char* file, char* buf, uint64_t* result, uint16_t divider); -void fast_read_num_u16(const char* dir, const char* file, char* buf, uint16_t* result, uint16_t divider); -void fast_read_num_i16(const char* dir, const char* file, char* buf, int16_t* result, uint16_t divider); +void fast_read_num_u64(const char* dir, const char* file, char* buf, uint64_t* result, uint32_t divider); +void fast_read_num_u16(const char* dir, const char* file, char* buf, uint16_t* result, uint32_t divider); +void fast_read_num_u8(const char* dir, const char* file, char* buf, uint8_t* result, uint32_t divider); +void fast_read_num_i16(const char* dir, const char* file, char* buf, int16_t* result, uint32_t divider); +void fast_read_num_f(const char* dir, const char* file, char* buf, float* result, uint32_t divider); bool file_exists(const char *path); +size_t read_file(const char* path, char* buffer, size_t n); int get_hwmon_dir(char *path); diff --git a/src/main.c b/src/main.c index c3affdf..f62f8e8 100644 --- a/src/main.c +++ b/src/main.c @@ -4,9 +4,11 @@ #include "log.h" #include #include +#include #include #include "lcd.h" #include "cpu.h" +#include "gpu.h" #include "sys.h" #include "utils.h" @@ -24,13 +26,13 @@ struct control_t { struct sensors_t { struct time_date_t td; - double loadavg[3]; struct memory_t ram; struct disk_t home; struct network_t net; struct syssensors_t sys; struct cpu_sensors_t cpu; - // gpu::gpuSensors gpu; + struct gpu_sensors_t gpu; + double loadavg[3]; double hass_state; }; @@ -45,6 +47,7 @@ static void *sensors_thread(void *arg) { strcpy(sensors->home.mountpoint, "/home/drath"); strcpy(sensors->net.device, "enp7s0"); cpu_detect(&sensors->cpu, "0000:00:18.3"); + gpu_detect(&sensors->gpu, "0000:0a:00.0"); sys_detect(&sensors->sys, "nct6775.656"); while (control.g_running) { // NOLINT @@ -58,6 +61,7 @@ static void *sensors_thread(void *arg) { sys_update_sensors(&sensors->sys); cpu_update(&sensors->cpu); + gpu_update(&sensors->gpu); pthread_mutex_unlock(&control.sensors_mtx); pthread_cond_signal(&control.sensors_ready); @@ -73,7 +77,6 @@ static void *sensors_thread(void *arg) { static void *display_thread(void *arg) { applog(LOG_START, "display thread started"); struct sensors_t* sensors = arg; - sensors->hass_state = 1; struct lcd_t lcd = { .port = "/dev/serial/by-id/usb-Raspberry_Pi_Pico_E6616407E37AA12F-if00", @@ -103,21 +106,39 @@ 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 + // prepare some tricky sensors 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]); + char gpudelta[5]; + const uint8_t delta = sensors->gpu.temp_hotspot - sensors->gpu.temp_edge; + snprintf(gpudelta, sizeof(gpudelta), "%c%d", 1, delta); + const uint8_t gpu_pos = delta > 10 ? 3 : 2; + + char gpuclock[16]; + snprintf(gpuclock, sizeof(gpuclock), "%d/%dMHz", sensors->gpu.clock_core, sensors->gpu.clock_mem); + + lcd_writef(&lcd, 0, 0, "%s %s%c", sensors->td.date, sensors->td.time, lcd_bar(&lcd, 5, sensors->gpu.usage_core / 100.0)); + lcd_writef(&lcd, 26, 0, "%.2f %.2f %.2f", sensors->loadavg[0], sensors->loadavg[1], sensors->loadavg[2]); // will fuck up 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); + if (sensors->hass_state) + lcd_writef(&lcd, 13, 1, "%3.0fW", sensors->hass_state); + lcd_writef(&lcd, 18, 1, "%3d%c", sensors->sys.t_sensor, 0); + lcd_writef(&lcd, 28, 1, "%4s%c", gpudelta, 0); + lcd_writef(&lcd, 25 - gpu_pos, 1, "%6s", P_BYTES(sensors->gpu.vram_used, 1)); + lcd_writef(&lcd, 34, 1, "%d/%d%c", sensors->gpu.temp_edge, sensors->gpu.temp_hotspot, 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, 26, 2, "%4dR", sensors->gpu.fan_speed); + lcd_writef(&lcd, 32, 2, "%3d/%3dW", sensors->gpu.power_avg, sensors->gpu.power_cap); 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)); + lcd_writef(&lcd, 21, 3, "%12s", gpuclock); + lcd_writef(&lcd, 34, 3, "%.3fV", sensors->gpu.vcore); pthread_mutex_unlock(&control.sensors_mtx); // unlock sensor struct diff --git a/src/utils.c b/src/utils.c index 1937f04..41cb9f3 100644 --- a/src/utils.c +++ b/src/utils.c @@ -58,7 +58,7 @@ int get_hwmon_dir(char* path) { } /* read n bytes from path into buffer */ -inline ssize_t read_file(const char* path, char* buffer, const ssize_t n) { +inline size_t read_file(const char* path, char* buffer, const size_t n) { const int fd = open(path, O_RDONLY | O_CLOEXEC); if (fd < 0) { applog(LOG_ERR, "Error reading %s", path); @@ -70,23 +70,37 @@ inline ssize_t read_file(const char* path, char* buffer, const ssize_t n) { return len; } -inline void fast_read_num_u64(const char* dir, const char* file, char* buf, uint64_t* result, const uint16_t divider) { +inline void fast_read_num_u64(const char* dir, const char* file, char* buf, uint64_t* result, const uint32_t divider) { char path[256]; MKPATH(path, dir, file); read_file(path, buf, 32); *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) { +inline void fast_read_num_u16(const char* dir, const char* file, char* buf, uint16_t* result, const uint32_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) { +inline void fast_read_num_u8(const char* dir, const char* file, char* buf, uint8_t* result, const uint32_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 uint32_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_f(const char* dir, const char* file, char* buf, float* result, const uint32_t divider) { + char path[256]; + MKPATH(path, dir, file); + read_file(path, buf, 32); + *result = (float)strtoull(buf, nullptr, 10) / (float)divider; } \ No newline at end of file