Add support to evaluate battery capacity from energy
authorHugo Villeneuve <hugo@hugovil.com>
Fri, 6 Mar 2015 19:34:26 +0000 (14:34 -0500)
committerHugo Villeneuve <hugo@hugovil.com>
Sun, 2 Jan 2022 22:43:17 +0000 (17:43 -0500)
src/batmon.c

index d4aa03a..d1e502c 100644 (file)
@@ -64,69 +64,98 @@ static const char ac[] = "AC0";
 static const char ac_acpi_dir_base[] = "/sys/class/power_supply";
 static const char battery_acpi_dir_base[] = "/sys/class/power_supply";
 
-static void read_ac_status(void)
+static int
+read_int_from_file(const char *path)
 {
-       FILE *ac_file;
-       char ac_file_path[256], ac_file_line[40];
-
-       sprintf(ac_file_path, "%s/%s/online", ac_acpi_dir_base,
-               ac);
+       FILE *fp;
+       int value;
 
-       ac_file = fopen(ac_file_path, "r");
+       if (access(path, F_OK ) < 0) {
+               /* File not found, abort. */
+               fprintf(stderr, "Missing file.\n");
+               exit(EXIT_FAILURE);
+       }
 
-       if (ac_file == NULL) {
-               perror(ac_file_path);
-               fprintf(stderr,
-                       "Unable to find power supply AC online status.\n");
+       fp = fopen(path, "r");
+       if (fp == NULL) {
+               /* File could not be read, abort. */
+               perror(path);
+               fprintf(stderr, "Unable to read file.\n");
                exit(EXIT_FAILURE);
        } else {
-               while (!feof(ac_file)) {
-                       memset(ac_file_line, 0, 40);
-                       fgets(ac_file_line, 40, ac_file);
-
-                       sscanf(ac_file_line, "%d", &ac_online);
+               char buf[40];
 
-                       break;
-               }
+               memset(buf, 0, sizeof(buf));
+               fgets(buf, sizeof(buf), fp);
+               sscanf(buf, "%d", &value);
 
 #ifdef DEBUG_ACPI
-               printf("ac online = %d\n", ac_online);
+               printf("value = %d\n", value);
 #endif /* DEBUG_ACPI */
        }
 
-       fclose(ac_file);
+       fclose(fp);
+
+       return value;
 }
 
-static void read_battery_status(void)
+static void read_ac_status(void)
 {
-       FILE *batt_file;
-       char batt_file_path[256], batt_file_line[40];
+       char path[256];
 
-       sprintf(batt_file_path, "%s/%s/capacity", battery_acpi_dir_base,
-               battery);
+       sprintf(path, "%s/%s/online", ac_acpi_dir_base, ac);
 
-       batt_file = fopen(batt_file_path, "r");
-
-       if (batt_file == NULL) {
-               perror(batt_file_path);
+       if (access(path, F_OK ) < 0) {
+               perror(path);
                fprintf(stderr,
-                       "Unable to determine battery capacity.\n");
+                       "Unable to find power supply AC online status.\n");
                exit(EXIT_FAILURE);
-       } else {
-               while (!feof(batt_file)) {
-                       memset(batt_file_line, 0, 40);
-                       fgets(batt_file_line, 40, batt_file);
+       }
 
-                       sscanf(batt_file_line, "%d", &capacity);
-                       break;
-               }
+       ac_online = read_int_from_file(path);
 
 #ifdef DEBUG_ACPI
-               printf("capacity = %d%%\n", capacity);
+       printf("ac online = %d\n", ac_online);
 #endif /* DEBUG_ACPI */
-       }
+}
+
+static void
+compute_battery_capacity_from_energy(void)
+{
+       char path[256];
+       int64_t full, now;
 
-       fclose(batt_file);
+       sprintf(path, "%s/%s/energy_full", battery_acpi_dir_base, battery);
+#ifdef DEBUG_ACPI
+       printf("Energy full: ");
+#endif /* DEBUG_ACPI */
+       full = read_int_from_file(path);
+
+       sprintf(path, "%s/%s/energy_now", battery_acpi_dir_base, battery);
+#ifdef DEBUG_ACPI
+       printf("Energy now:  ");
+#endif /* DEBUG_ACPI */
+       now = read_int_from_file(path);
+
+       capacity = (now * 100) / full;
+
+#ifdef DEBUG_ACPI
+       printf("capacity = %d%%\n", capacity);
+#endif /* DEBUG_ACPI */
+}
+
+static void read_battery_capacity(void)
+{
+       char path[256];
+
+       sprintf(path, "%s/%s/capacity", battery_acpi_dir_base, battery);
+
+       if (access(path, F_OK ) < 0) {
+               /* Capacity file doesn't exist, try reading energy... */
+               compute_battery_capacity_from_energy();
+       } else {
+               capacity = read_int_from_file(path);
+       }
 }
 
 static void
@@ -233,7 +262,7 @@ draw_background(cairo_t *cr)
        int height;
 
        read_ac_status();
-       read_battery_status();
+       read_battery_capacity();
 
        cairo_save(cr);