diff options
| author | 0scar <qgt268@alumni.ku.dk> | 2024-10-31 21:49:46 +0000 |
|---|---|---|
| committer | 0scar <qgt268@alumni.ku.dk> | 2024-10-31 21:49:46 +0000 |
| commit | 1480b613be6746335335dd78b5feb3cef4c80edd (patch) | |
| tree | 2ba78560905e2c74ab531eeb1f9de91081b9b65a /status.c | |
Initial commit
Shows battery and time
Diffstat (limited to 'status.c')
| -rw-r--r-- | status.c | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/status.c b/status.c new file mode 100644 index 0000000..e3a5c44 --- /dev/null +++ b/status.c @@ -0,0 +1,162 @@ +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <stdbool.h> +#include <stdint.h> +#include <string.h> +#include <time.h> +#include <sys/time.h> +#include <errno.h> + +#define ELEMENT_SEPERATOR " " + +#define STATUS_STRBUF_SZ 512 +#define ELEMENT_STRBUF_SZ 64 + +typedef void (*element_function)(char*); + +struct element { + const element_function f; + const struct timeval fire_interval; + struct timeval fire_previous; + char buf[ELEMENT_STRBUF_SZ]; +}; + + +void date(char* buf) { + time_t now = time(NULL); + struct tm tm; + localtime_r(&now, &tm); + + strftime(buf, ELEMENT_STRBUF_SZ, "%F %R", &tm); +} + +enum battery_status_charge { + bat_unknown, + bat_not_charging, + bat_charging, + bat_discharging +}; + +struct battery_status { + enum battery_status_charge status; + float charge; +}; + +struct battery_status get_battery_status(const char* buf) { + const char path_prefix[] = "/sys/class/power_supply/"; + + char charge_path[128]; + char capacity_path[128]; + + memset(charge_path, 0, 128); + memset(capacity_path, 0, 128); + + int charge = 0; + int capacity = 0; + + char charge_str[512]; + char capacity_str[512]; + + strcat(charge_path, path_prefix); + strcat(charge_path, buf); + strcat(charge_path, "/energy_now"); + + strcat(capacity_path, path_prefix); + strcat(capacity_path, buf); + strcat(capacity_path, "/energy_full"); + + FILE* bat_charge = fopen(charge_path, "r"); + FILE* bat_capacity = fopen(capacity_path, "r"); + + if (!bat_charge) { + printf("%d: \"%s\" %s\n", errno, charge_path, strerror(errno)); + return (struct battery_status){.status = bat_unknown, .charge = -1}; + } + if (!bat_capacity) { + printf("%d: \"%s\" %s\n", errno, capacity_path, strerror(errno)); + return (struct battery_status){.status = bat_unknown, .charge = -1}; + } + + fread(charge_str, sizeof(char), 512, bat_charge); + fread(capacity_str, sizeof(char), 512, bat_capacity); + + fclose(bat_charge); + fclose(bat_capacity); + + charge = atoi(charge_str); + capacity = atoi(capacity_str); + + return (struct battery_status){.status = bat_unknown, .charge = (float)charge / capacity}; +} + +void get_battery0_status(char* buf) { + struct battery_status s = get_battery_status("BAT0"); + + snprintf(buf, ELEMENT_STRBUF_SZ, "\uf581 %.1f%%", 100.f * s.charge); +} + +static struct element statusbar[] = { + {get_battery0_status, {5,0}, 0}, + {date, {1,500000}, 0}, +}; + +int main() { + const int num_elems = sizeof(statusbar)/sizeof(statusbar[0]); + struct timeval now; + const struct timeval one_minute = {.tv_sec = 60, .tv_usec = 0}; + + + while (true) { + gettimeofday(&now, NULL); + + // Stall updating for at most 1 minute + struct timeval next_update; + timeradd(&now, &one_minute, &next_update); + + for (unsigned i = 0; i < num_elems; i++) { + struct timeval next_fire; + timeradd(&statusbar[i].fire_previous, &statusbar[i].fire_interval, &next_fire); + + if (timercmp(&next_fire, &now, >)) { + // Check if this is the next to-be-updated element + if (timercmp(&next_fire, &next_update, <)) { + next_update = next_fire; + } + continue; + } + + memset(statusbar[i].buf, 0, ELEMENT_STRBUF_SZ); + + statusbar[i].f(statusbar[i].buf); + statusbar[i].fire_previous = now; + + // Check if this element needs to be refreshed next, again + timeradd(&statusbar[i].fire_previous, &statusbar[i].fire_interval, &next_fire); + if (timercmp(&next_fire, &next_update, <)) { + next_update = next_fire; + } + + printf("[%ld.%ld] %s\n", statusbar[i].fire_interval.tv_sec, statusbar[i].fire_interval.tv_usec, (char*)statusbar[i].buf); + + } + + unsigned c = 0; + char buf[STATUS_STRBUF_SZ]; + memset(buf, 0, STATUS_STRBUF_SZ); + + for (unsigned i = 0; i < num_elems; i++) { + strcat(buf, statusbar[i].buf); + if (i != num_elems - 1) strcat(buf, ELEMENT_SEPERATOR); + } + + strcat(buf, "%"); + + puts(buf); + + timersub(&next_update, &now, &next_update); + usleep(next_update.tv_sec*1000*1000+next_update.tv_usec); + } + + return 0; +} |
