summaryrefslogtreecommitdiff
path: root/src/get_battery_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/get_battery_info.c')
-rw-r--r--src/get_battery_info.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/get_battery_info.c b/src/get_battery_info.c
new file mode 100644
index 0000000..b81eb8e
--- /dev/null
+++ b/src/get_battery_info.c
@@ -0,0 +1,88 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "i3status.h"
+
+/*
+ * Get battery information from /sys. Note that it uses the design capacity to
+ * calculate the percentage, not the last full capacity, so you can see how
+ * worn off your battery is.
+ *
+ */
+const char *get_battery_info(struct battery *bat) {
+ char buf[1024];
+ static char part[512];
+ char *walk, *last;
+ int full_design = -1,
+ remaining = -1,
+ present_rate = -1;
+ charging_status_t status = CS_DISCHARGING;
+
+ slurp(bat->path, buf, sizeof(buf));
+
+ for (walk = buf, last = buf; (walk-buf) < 1024; walk++) {
+ if (*walk == '\n') {
+ last = walk+1;
+ continue;
+ }
+
+ if (*walk != '=')
+ continue;
+
+ if (BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_NOW") ||
+ BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_NOW"))
+ remaining = atoi(walk+1);
+ else if (BEGINS_WITH(last, "POWER_SUPPLY_CURRENT_NOW"))
+ present_rate = atoi(walk+1);
+ else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Charging"))
+ status = CS_CHARGING;
+ else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Full"))
+ status = CS_FULL;
+ else {
+ /* The only thing left is the full capacity */
+ if (bat->use_last_full) {
+ if (!BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_FULL") &&
+ !BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_FULL"))
+ continue;
+ } else {
+ if (!BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_FULL_DESIGN") &&
+ !BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_FULL_DESIGN"))
+ continue;
+ }
+
+ full_design = atoi(walk+1);
+ }
+ }
+
+ if ((full_design == 1) || (remaining == -1))
+ return part;
+
+ if (present_rate > 0) {
+ float remaining_time;
+ int seconds, hours, minutes;
+ if (status == CS_CHARGING)
+ remaining_time = ((float)full_design - (float)remaining) / (float)present_rate;
+ else if (status == CS_DISCHARGING)
+ remaining_time = ((float)remaining / (float)present_rate);
+ else remaining_time = 0;
+
+ seconds = (int)(remaining_time * 3600.0);
+ hours = seconds / 3600;
+ seconds -= (hours * 3600);
+ minutes = seconds / 60;
+ seconds -= (minutes * 60);
+
+ (void)snprintf(part, sizeof(part), "%s %.02f%% %02d:%02d:%02d",
+ (status == CS_CHARGING ? "CHR" :
+ (status == CS_DISCHARGING ? "BAT" : "FULL")),
+ (((float)remaining / (float)full_design) * 100),
+ max(hours, 0), max(minutes, 0), max(seconds, 0));
+ } else {
+ (void)snprintf(part, sizeof(part), "%s %.02f%%",
+ (status == CS_CHARGING ? "CHR" :
+ (status == CS_DISCHARGING ? "BAT" : "FULL")),
+ (((float)remaining / (float)full_design) * 100));
+ }
+ return part;
+}