aboutsummaryrefslogtreecommitdiff
path: root/lowbat.c
diff options
context:
space:
mode:
authorTim Keller <tjk@tjkeller.xyz>2024-10-17 21:06:06 -0500
committerTim Keller <tjk@tjkeller.xyz>2024-10-17 21:06:06 -0500
commit5d14a80beb1b9553df4de7ad580262a625bfadc3 (patch)
tree480d794055e6082bdc2dc3e8d39f821f52be795d /lowbat.c
parentb16a818cd0918845ea899bb913ce4320a606a510 (diff)
downloadlowbat-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
Diffstat (limited to 'lowbat.c')
-rw-r--r--lowbat.c63
1 files changed, 36 insertions, 27 deletions
diff --git a/lowbat.c b/lowbat.c
index 50651a7..bfdadf2 100644
--- a/lowbat.c
+++ b/lowbat.c
@@ -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);
}