battery.c
2.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
// maximum number of batteries supported
#define MAXBAT 2
typedef enum {
CHARGED = 0,
DISCHARGING = 1,
CHARGING = 2,
DISCONNECTED = 7,
UNKNOWN = -1
} State;
const char *icon[] = {
"\uf58d", /* 0% */
"\uf579", "\uf57a", "\uf57b", "\uf57c", "\uf57d", /* 50% */
"\uf57e", "\uf57f", "\uf580", "\uf581", "\uf578", /* 100% */
};
const char separator[] = " "; // space between battery indicators
void battery_state(int *nbats, int bat[], State state[]) {
#if defined(__linux__)
FILE *fd;
int i;
for (i = 0; i < MAXBAT; i++) {
char filename[50], status[50];
// get current capacity
sprintf(filename, "/sys/class/power_supply/BAT%d/capacity", i);
fd = fopen(filename, "rb");
if (fd == NULL)
break;
fscanf(fd, "%d", &bat[i]);
fclose(fd);
// battery status (charging...)
sprintf(filename, "/sys/class/power_supply/BAT%d/status", i);
fd = fopen(filename, "rb");
fgets(status, 50, fd);
// puts(status);
fclose(fd);
if (!strcmp(status, "Not charging\n"))
state[i] = CHARGED;
else if (!strcmp(status, "Discharging\n"))
state[i] = DISCHARGING;
else if (!strcmp(status, "Charging\n"))
state[i] = CHARGING;
else
state[i] = UNKNOWN;
}
*nbats = i;
#elif defined(__FreeBSD__)
size_t len = sizeof(int);
int status, life = 0;
*nbats = 1; // FIXME: deal with multiple batteries
if (sysctlbyname("hw.acpi.battery.state", &status, &len, NULL, 0) ||
sysctlbyname("hw.acpi.battery.life", &life, &len, NULL, 0)) {
state[0] = UNKNOWN;
bat[0] = 0;
} else {
bat[0] = life;
state[0] = status;
}
#else
#error "Unsupported"
#endif
}
int main() {
char *color;
int life[2], nbats;
State state[2];
battery_state(&nbats, life, state);
for (int i = 0; i < nbats; i++) {
if (i > 0)
printf("%s", separator);
switch (state[i]) {
case CHARGED: /* fully charged */
printf("%s %d%%", icon[life[i] / 10], life[i]);
break;
case DISCHARGING: /* discharging */
if (life[i] >= 50)
color = "colour028"; /* green */
else if (life[i] >= 25)
color = "colour172"; /* yellow */
else
color = "colour196"; /* red */
printf("#[fg=%s]%s#[fg=default] %d%%", color, icon[life[i] / 10],
life[i]);
break;
case CHARGING: /* charging */
printf("#[fg=yellow]\uf583#[fg=default] %d%%", life[i]);
break;
case DISCONNECTED: /* disconnected */
printf("\uf492");
break;
default: /* unknown code */
printf("\uf590");
}
}
return EXIT_SUCCESS;
}