Overall remaining battery power is currently the average of the remaining power (in percents) of each battery. This is misleading if your laptop uses a large external battery which drains out first, and a smaller internal battery (common scheme on eg thinkpad machines). Overall battery power decreases much faster when you switch to the smaller battery. This odd behavior was reported by a friend a few weeks ago.
The diff below attempts to fix this: compute the sum of the remaining power and capacity, *then* compute the overall remaining percentage. No regression on my thinkpad x270 with two batteries of similar capacity. I don't know whether the original reporter will be able to test this soon. The code touches the acpisbs(4) bits, hopefully without changing the current behavior. acpisbs(4) currently doesn't support multiple batteries. Test reports, feedback, oks welcome. Index: acpi.c =================================================================== RCS file: /d/cvs/src/sys/dev/acpi/acpi.c,v retrieving revision 1.383 diff -u -p -p -u -r1.383 acpi.c --- acpi.c 8 May 2020 11:18:01 -0000 1.383 +++ acpi.c 8 May 2020 15:04:50 -0000 @@ -3503,7 +3503,7 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t struct acpi_sbs *sbs; struct apm_power_info *pi = (struct apm_power_info *)data; int bats; - unsigned int remaining, rem, minutes, rate; + unsigned int capacity, remaining, minutes, rate; int s; if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || @@ -3554,7 +3554,8 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t pi->battery_life = 0; pi->minutes_left = 0; bats = 0; - remaining = rem = 0; + capacity = 0; + remaining = 0; minutes = 0; rate = 0; SLIST_FOREACH(bat, &sc->sc_bat, aba_link) { @@ -3565,11 +3566,9 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t continue; bats++; - rem = (bat->aba_softc->sc_bst.bst_capacity * 100) / - bat->aba_softc->sc_bix.bix_last_capacity; - if (rem > 100) - rem = 100; - remaining += rem; + capacity += bat->aba_softc->sc_bix.bix_last_capacity; + remaining += min(bat->aba_softc->sc_bst.bst_capacity, + bat->aba_softc->sc_bix.bix_last_capacity); if (bat->aba_softc->sc_bst.bst_rate == BST_UNKNOWN) continue; @@ -3587,10 +3586,9 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t continue; bats++; - rem = sbs->asbs_softc->sc_battery.rel_charge; - if (rem > 100) - rem = 100; - remaining += rem; + capacity += 100; + remaining += min(100, + sbs->asbs_softc->sc_battery.rel_charge); if (sbs->asbs_softc->sc_battery.run_time == ACPISBS_VALUE_UNKNOWN) @@ -3613,7 +3611,7 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t pi->minutes_left = 60 * minutes / rate; /* running on battery */ - pi->battery_life = remaining / bats; + pi->battery_life = remaining * 100 / capacity; if (pi->battery_life > 50) pi->battery_state = APM_BATT_HIGH; else if (pi->battery_life > 25) -- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE