diff --git a/README.md b/README.md index b8e36e1..e9a1f7b 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,10 @@ Vaguely inspired by suckless software philosophy, as in: ## The config is the source code Same as plugins. Just write in more features scrub, learn some C, damn +## TODOs (real) +- 1st line is done +- do the fast file read func, we'll need a lot of that + ## TODOs - Extra screens support perhaps? just halt sensors monitoring thread and print another struct on display if needed, have a semaphore or sth - Maybe not even screens, keep the 1st line and change lines 2-4 diff --git a/distrobox.ini b/distrobox.ini index 0007b82..d174455 100644 --- a/distrobox.ini +++ b/distrobox.ini @@ -1,6 +1,6 @@ [linuxsmartie] additional_packages="build-essential cmake" -additional_packages="libwebsockets-dev nlohmann-json3-dev" +additional_packages="libwebsockets-dev libcjson-dev" image=debian-toolbox:13 init=false replace=true diff --git a/src/main.c b/src/main.c index 2ebff32..53caf83 100644 --- a/src/main.c +++ b/src/main.c @@ -8,6 +8,9 @@ #include "lcd.h" #include "sys.h" +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) { @@ -16,13 +19,10 @@ static void timespec_add_ms(struct timespec *ts, const uint16_t ms) { } } -static constexpr uint16_t refresh_interval_ms = 500; - -atomic_bool g_running; // if using c11, you need atomic_store() and atomic_load(); - struct control_t { pthread_mutex_t sensors_mtx; pthread_cond_t sensors_ready; + atomic_bool g_running; // if using c11, you need atomic_store() and atomic_load(); } control; struct sensors_t { @@ -50,19 +50,19 @@ static void *display_thread(void *arg) { lcd_init(&lcd); // basic lcd setup - lcd_set_contrast(&lcd, 215); lcd_set_backlight(&lcd, true); + lcd_set_contrast(&lcd, 206); lcd_set_custom_char(&lcd, 0, &(lcd_glyph_t){16, 6, 9, 8, 8, 9, 6, 0}); // celcius lcd_set_custom_char(&lcd, 1, &(lcd_glyph_t){0, 0, 4, 10, 10, 17, 31, 0}); // delta lcd_set_custom_char(&lcd, 2, &(lcd_glyph_t){0, 0, 8, 21, 21, 2, 0, 0}); // home (tilde) lcd_set_custom_char(&lcd, 3, &(lcd_glyph_t){4, 14, 21, 4, 4, 4, 0}); // up arrow lcd_set_custom_char(&lcd, 4, &(lcd_glyph_t){4, 4, 4, 21, 14, 4, 0}); // down arrow - lcd_write_buf(&lcd, 2, 0, "Waiting for sensors..."); // need to center this still + lcd_write_buf(&lcd, 1, 9, "Waiting for sensors..."); // need to center this still lcd_flush_buf(&lcd); lcd_clear_buf(&lcd); - while (g_running) { // NOLINT its updated globally bud + while (control.g_running) { // NOLINT its updated globally bud struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); timespec_add_ms(&ts, (uint16_t)(refresh_interval_ms * 1.25)); @@ -70,28 +70,30 @@ 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 - lcd_clear_buf(&lcd); 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_flush_buf(&lcd); pthread_mutex_unlock(&control.sensors_mtx); // unlock sensor struct + + lcd_flush_buf(&lcd); + lcd_clear_buf(&lcd); } + lcd_write_buf(&lcd, 2, 16, "Goodbye"); // center + lcd_flush_buf(&lcd); lcd_close(&lcd); applog(LOG_WRN, "display thread stopped"); return nullptr; } static void *sensors_thread(void *arg) { - applog(LOG_START, "sensors thread started"); + applog(LOG_START, "sensors thread started, refresh interval is %dms", refresh_interval_ms); struct sensors_t* sensors = arg; struct timespec next; clock_gettime(CLOCK_REALTIME, &next); - while (g_running) { // NOLINT - timespec_add_ms(&next, refresh_interval_ms); + while (control.g_running) { // NOLINT pthread_mutex_lock(&control.sensors_mtx); sys_get_load_avg(sensors->loadavg); @@ -100,6 +102,7 @@ static void *sensors_thread(void *arg) { pthread_cond_signal(&control.sensors_ready); pthread_mutex_unlock(&control.sensors_mtx); + timespec_add_ms(&next, refresh_interval_ms); clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &next, nullptr); } @@ -109,7 +112,7 @@ static void *sensors_thread(void *arg) { } int main(void) { - g_running = true; + control.g_running = true; applog(LOG_START, "linuxSmartie started"); /* signal setup */ @@ -122,10 +125,11 @@ int main(void) { struct signalfd_siginfo info; const int sfd = signalfd(-1, &sigset, SFD_CLOEXEC); - /* init control struct */ + /* control vars setup */ pthread_mutex_init(&control.sensors_mtx, nullptr); pthread_cond_init(&control.sensors_ready, nullptr); + /* allocate mem for the main struct */ struct sensors_t *sensors = malloc(sizeof(struct sensors_t)); if (sensors == nullptr) { @@ -135,24 +139,22 @@ int main(void) { } applog(LOG_INF, "sensor struct allocated, size is %lu bytes", sizeof(struct sensors_t)); - applog(LOG_INF, "sensors is %.1f", sensors->hass_state); - + /* thread setup */ pthread_t display_pthread; pthread_t sensors_pthread; + + /* actually start the threads */ pthread_create(&display_pthread, nullptr, display_thread, sensors); pthread_create(&sensors_pthread, nullptr, sensors_thread, sensors); read(sfd, &info, sizeof(info)); // halts on this until SIGTERM - g_running = false; - close(sfd); - applog(LOG_WRN, "got stop signal, shutting down..."); + /* cleanup on exit signal */ + applog(LOG_WRN, "got stop signal, shutting down..."); + close(sfd); + control.g_running = false; pthread_join(display_pthread, nullptr); pthread_join(sensors_pthread, nullptr); - - applog(LOG_INF, "sensors is %.1f", sensors->hass_state); - free(sensors); - applog(LOG_INF, "freed memory"); return 0; } \ No newline at end of file