diff options
author | Tim Keller <tjk@tjkeller.xyz> | 2024-10-17 21:06:06 -0500 |
---|---|---|
committer | Tim Keller <tjk@tjkeller.xyz> | 2024-10-17 21:06:06 -0500 |
commit | 5d14a80beb1b9553df4de7ad580262a625bfadc3 (patch) | |
tree | 480d794055e6082bdc2dc3e8d39f821f52be795d | |
parent | b16a818cd0918845ea899bb913ce4320a606a510 (diff) | |
download | lowbat-5d14a80beb1b9553df4de7ad580262a625bfadc3.tar.xz lowbat-5d14a80beb1b9553df4de7ad580262a625bfadc3.zip |
change charging/discharging to +/- and clean up compiler errors. also clean up todos and optimize a bit. no batteries installed will now output 0% instead of exit. if battery is removed, lowbat will no longer crash
-rw-r--r-- | lowbat.c | 63 |
1 files changed, 36 insertions, 27 deletions
@@ -1,5 +1,5 @@ /* LINUX DOCS: https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-power - * (C) 2024 Tim Keller <tjkeller.xyz> + * (C) 2024 Tim Keller <tjk@tjkeller.xyz> * MIT License */ @@ -9,10 +9,11 @@ #include <unistd.h> #include <dirent.h> -#define PERIOD 3 // number of seconds before each check -#define PSUPATH "/sys/class/power_supply" // number of seconds before each check +#define PSUPATH "/sys/class/power_supply" +#define PERIOD 3 // number of seconds before each check #define MAX_BATTERIES 8 #define MAX_PSU_NAME_LEN 8 +#define MAX_MSG_LEN 32 #define MAX_PROP_PATH_LEN 64 // variables @@ -28,25 +29,25 @@ void load_installed_batteries() { struct dirent *entry, *subentry; if ((dir = opendir(PSUPATH)) == NULL) { - fprintf(stderr, "failed to see power supplies"); // TODO + fprintf(stderr, "failed to open power supplies filesystem: %s\n", PSUPATH); exit(EXIT_FAILURE); } // power supplies TODO warn user if max batteries exceeded num_batteries = 0; - while ((entry = readdir(dir)) != NULL && num_batteries < MAX_BATTERIES) { + while ((entry = readdir(dir)) != NULL) { if (entry->d_name[0] == '.') continue; // skip . and .. if (strlen(entry->d_name) > MAX_PSU_NAME_LEN) { - fprintf(stderr, "the power supply name was too long: %s", entry->d_name); + fprintf(stderr, "the power supply's name was too long: %s\n", entry->d_name); exit(EXIT_FAILURE); } // power supplies will always be a directory, no need to check beforehand :) - snprintf(prop_path, MAX_PROP_PATH_LEN, PSUPATH "/%s", entry->d_name); + snprintf(prop_path, MAX_PROP_PATH_LEN, PSUPATH "/%.8s", entry->d_name); // 8 is equal to MAX_PSU_NAME_LEN, prevent compiler warning if ((subdir = opendir(prop_path)) == NULL) { - fprintf(stderr, "failed to see power supplies sub\n"); // TODO + fprintf(stderr, "failed to open power supply: %s\n", prop_path); exit(EXIT_FAILURE); } @@ -54,6 +55,10 @@ void load_installed_batteries() { while ((subentry = readdir(subdir)) != NULL) { // add to list of batteries if it has the status property if (strcmp(subentry->d_name, "status") == 0) { + if(num_batteries >= MAX_BATTERIES) { + fprintf(stderr, "maximum number of batteries (8) exceeded\n"); + exit(EXIT_FAILURE); + } strncpy(batteries[num_batteries], entry->d_name, MAX_PSU_NAME_LEN); num_batteries++; break; @@ -84,7 +89,7 @@ void read_prop(char *psu, char *prop, char *fmt, void *out) { fclose(fp); } else { - printf("failed to read fmt '%s' from property %s\n", fmt, prop_path); // TODO fprintf me plz + fprintf(stderr, "failed to read fmt '%s' from property %s\n", fmt, prop_path); exit(EXIT_FAILURE); } } @@ -93,6 +98,9 @@ int get_total_capacity() { unsigned long int energy_full = 0, energy_now = 0, x; int i; + if (!num_batteries) + return 0; + for (i = 0; i < num_batteries; i++) { read_prop(batteries[i], "energy_full", "%ld", &x); energy_full += x; @@ -107,6 +115,9 @@ int is_discharging() { char status[12]; // valid values: "Unknown", "Charging", "Discharging", "Not charging", "Full" int i; + if (!num_batteries) + return 0; + for (i = 0; i < num_batteries; i++) { read_prop(batteries[i], "status", "%s", &status); if (strcmp(status, "Discharging") != 0) @@ -117,15 +128,9 @@ int is_discharging() { } int main() { - int discharging, capacity; - int w_lowbat = 0, w_lowbat_crit = 0; // 1 if warned already - char msg[32]; - - load_installed_batteries(); - if (!num_batteries) { - fprintf(stderr, "no batteries installed in system. exiting...\n"); // TODO - exit(EXIT_FAILURE); - } + int discharging, capacity, old_discharging = -1, old_capacity = -1; + int warning_level = 0; // 1 if warned already, 2 if warned with critical warning + char msg[MAX_MSG_LEN]; while (1) { load_installed_batteries(); @@ -133,23 +138,27 @@ int main() { capacity = get_total_capacity(); if (discharging) { - if (capacity <= 5 && !w_lowbat_crit) { - sprintf(msg, "%d%% remains", capacity); // TODO snprintf me plz + if (capacity <= 5 && warning_level < 2) { + snprintf(msg, MAX_MSG_LEN, "%d%% remains", capacity); notifysend("Critical Low Battery Warning", msg, NOTIFY_URGENCY_CRITICAL); - w_lowbat_crit = w_lowbat = 1; - } else if (capacity <= 20 && !w_lowbat) { - sprintf(msg, "%d%% remains", capacity); + warning_level = 2; + } else if (capacity <= 20 && warning_level < 1) { + snprintf(msg, MAX_MSG_LEN, "%d%% remains", capacity); notifysend("Low Battery Warning", msg, NOTIFY_URGENCY_NORMAL); - w_lowbat = 1; + warning_level = 1; } } else { - w_lowbat_crit = w_lowbat = 0; // clear conditions + warning_level = 0; // clear conditions } - printf("\r%s %d%%", discharging ? "Discharging" : "Charging", capacity); - fflush(stdout); + if (discharging != old_discharging || capacity != old_capacity) { + printf("\r%s%d%%", discharging ? "-" : "+", capacity); + fflush(stdout); + } + old_discharging = discharging; + old_capacity = capacity; sleep(PERIOD); } |