Skip to content

Commit fb0534a

Browse files
committed
Enhance display of BatteryMeter with extra information
1 parent 4a496d5 commit fb0534a

1 file changed

Lines changed: 116 additions & 13 deletions

File tree

BatteryMeter.c

Lines changed: 116 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,124 @@ static void BatteryMeter_updateValues(Meter* this) {
4343

4444
this->values[0] = info.percent;
4545

46-
const char* text;
47-
switch (info.ac) {
48-
case AC_PRESENT:
49-
text = this->mode == TEXT_METERMODE ? " (Running on A/C)" : "(A/C)";
50-
break;
51-
case AC_ABSENT:
52-
text = this->mode == TEXT_METERMODE ? " (Running on battery)" : "(bat)";
53-
break;
54-
case AC_ERROR:
55-
default:
56-
text = "";
57-
break;
46+
bool haveEnergy = isNonnegative(info.energyCurr) && isNonnegative(info.energyFull);
47+
48+
/* Without energy data there is nothing useful to show beyond the percent. */
49+
if (!haveEnergy) {
50+
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%.1f%%", info.percent);
51+
return;
52+
}
53+
54+
bool havePower = isfinite(info.powerCurr);
55+
56+
/* stable: power unknown or |power| < 5 W – time estimate would be unreliable */
57+
bool isDischarging = havePower && info.powerCurr <= -5.0;
58+
bool isCharging = havePower && info.powerCurr >= 5.0;
59+
60+
/* time estimate in whole minutes; -1 means not available */
61+
int timeMinutes = -1;
62+
if (isDischarging && isPositive(info.energyCurr)) {
63+
/* floor for discharge; powerCurr is negative, use negative scaling when dividing */
64+
timeMinutes = (int)floor(info.energyCurr / info.powerCurr * -60.0);
65+
} else if (isCharging && 0.95 * info.energyFull > info.energyCurr) {
66+
/* ceil for charge */
67+
timeMinutes = (int)ceil((0.95 * info.energyFull - info.energyCurr) / info.powerCurr * 60.0);
68+
}
69+
70+
char* buf = this->txtBuffer;
71+
size_t len = sizeof(this->txtBuffer);
72+
int ret = 0;
73+
74+
if (this->mode == TEXT_METERMODE) {
75+
if (info.ac == AC_PRESENT) {
76+
ret = xSnprintf(buf, len, "Using %s", isDischarging ? "AC+bat" : "AC");
77+
buf += ret; len -= ret;
78+
} else if (info.ac == AC_ABSENT) {
79+
ret = xSnprintf(buf, len, "Using bat");
80+
buf += ret; len -= ret;
81+
}
82+
83+
if (ret && len > 2) {
84+
*buf++ = ',';
85+
*buf++ = ' ';
86+
*buf = 0;
87+
len -= 2;
88+
}
89+
90+
if (isDischarging) {
91+
ret = xSnprintf(
92+
buf, len, "discharging at %.1fW, %.1f/%.1fWh (%.1f%%)",
93+
-info.powerCurr, info.energyCurr, info.energyFull, info.percent
94+
);
95+
buf += ret; len -= ret;
96+
if (timeMinutes >= 0) {
97+
ret = xSnprintf(buf, len, ", time remaining: %dh%02dm", timeMinutes / 60, timeMinutes % 60);
98+
buf += ret; len -= ret;
99+
}
100+
} else if (isCharging) {
101+
ret = xSnprintf(
102+
buf, len, "charging at %.1fW, %.1f/%.1fWh (%.1f%%)",
103+
info.powerCurr, info.energyCurr, info.energyFull, info.percent
104+
);
105+
buf += ret; len -= ret;
106+
107+
if (timeMinutes >= 0) {
108+
ret = xSnprintf(
109+
buf, len, ", time to full: %dh%02dm",
110+
timeMinutes / 60, timeMinutes % 60
111+
);
112+
buf += ret; len -= ret;
113+
}
114+
} else {
115+
ret = xSnprintf(
116+
buf, len, "stable at %.1f/%.1fWh (%.1f%%)",
117+
info.energyCurr, info.energyFull, info.percent
118+
);
119+
buf += ret; len -= ret;
120+
}
121+
} else {
122+
/* compact label for bar / graph modes */
123+
if (info.ac == AC_PRESENT) {
124+
ret = xSnprintf(buf, len, "%s", isDischarging ? "AC+bat" : "AC");
125+
buf += ret; len -= ret;
126+
} else if (info.ac == AC_ABSENT) {
127+
ret = xSnprintf(buf, len, "bat");
128+
buf += ret; len -= ret;
129+
}
130+
131+
if (ret && len > 1) {
132+
*buf++ = ' ';
133+
*buf = 0;
134+
len--;
135+
}
136+
137+
if (isCharging || isDischarging) {
138+
ret = xSnprintf(
139+
buf, len, "%+.1fW @ %.1f/%.1fWh",
140+
info.powerCurr, info.energyCurr, info.energyFull
141+
);
142+
buf += ret; len -= ret;
143+
144+
if (timeMinutes >= 0) {
145+
ret = xSnprintf(
146+
buf, len, ", %dh%02dm",
147+
timeMinutes / 60, timeMinutes % 60
148+
);
149+
buf += ret; len -= ret;
150+
}
151+
} else {
152+
ret = xSnprintf(
153+
buf, len, "stable @ %.1f/%.1fWh",
154+
info.energyCurr, info.energyFull
155+
);
156+
buf += ret; len -= ret;
157+
}
58158
}
59159

60-
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%.1f%%%s", info.percent, text);
160+
// Simplify the pattern to always use "buf += ret; len -= ret;" for all cases
161+
(void)ret;
162+
(void)buf;
163+
(void)len;
61164
}
62165

63166
const MeterClass BatteryMeter_class = {

0 commit comments

Comments
 (0)