battery.c (1803B)
1 /* See LICENSE for license details. */ 2 #include <limits.h> 3 4 struct bat_arg { 5 char *bat; /* BAT name (ex. BAT0) */ 6 char *pre; /* prefix for percentages less than thres */ 7 char *suf; /* suffix for percentages less than thres */ 8 int thres; /* % threshold to consider low (-1 to disable) */ 9 }; 10 11 static size_t 12 batinfo(struct Block *b) 13 { 14 struct bat_arg *ba = b->arg; 15 char *pre = ba->pre ? ba->pre : ""; 16 char *suf = ba->suf ? ba->suf : ""; 17 char path[PATH_MAX], state[12]; 18 int s, perc, h, m; 19 long power_now, energy_now, energy_full; 20 double timeleft; 21 22 snprintf(path, sizeof(path), "/sys/class/power_supply/%s/energy_full", ba->bat); 23 if (pscanf(path, "%ld", &energy_full) != 1) 24 energy_full = 1; 25 26 snprintf(path, sizeof(path), "/sys/class/power_supply/%s/energy_now", ba->bat); 27 if (pscanf(path, "%ld", &energy_now) != 1) 28 energy_now = 0; 29 30 perc = (100 * energy_now / (double)energy_full); 31 s = perc < ba->thres; 32 33 snprintf(path, sizeof(path), "/sys/class/power_supply/%s/status", ba->bat); 34 if (pscanf(path, "%12s", &state) != 1) 35 snprintf(state, sizeof(state), "Unknown"); 36 37 /* NOTE(rnp): proper devices use negative power to indicate discharging but that 38 * is not always the case. The status string can mostly be trusted */ 39 if (!strcmp(state, "Discharging")) { 40 snprintf(path, sizeof(path), "/sys/class/power_supply/%s/power_now", ba->bat); 41 if (pscanf(path, "%ld", &power_now) != 1) 42 power_now = 1; 43 44 timeleft = (double)energy_now / (double)ABS(power_now); 45 h = timeleft; 46 m = (timeleft - (double)h) * 60; 47 48 snprintf(buf, sizeof(buf), "%s%d%% (%d:%02d)%s", s ? pre : "", 49 perc, h, m, s ? suf : ""); 50 } else { 51 snprintf(buf, sizeof(buf), "%s%d%% (%s)%s", s ? pre : "", perc, 52 state, s ? suf : ""); 53 } 54 55 return snprintf(b->curstr, LEN(b->curstr), b->fmt, buf); 56 }