On 2026-09-15 I cut AC to the UPS on purpose and let it run all the way down - the first time this system has been taken to a genuine hardware cutoff instead of stopped early. Everything the protection ladder was built to do, it did. And the pack came up 42 % short, with no instrument on the system that would have told me.
The ladder, end to end
- 09:16:58 - AC off.
on_batterysets 12 s later at 12.95 V, -1.94 A. - 09:41:48 - Plateau → Knee at 12.649 V.
- 09:44:47 - first
cliff_imminenttrigger; aborted in the 30 s revalidation. 09:53:51 - the second one held, and HA shut the N100DC host down. The XB7 stayed up. - 10:32:50 - Knee → Cliff at 12.399 V, now carrying only the modem and monitor (~1.41 A).
- 10:47:18 - Victron BP-65 trips. The XB7 drops. The monitor, fed upstream of the BP-65, stays powered.
- Survival sleep, never exercised in a real outage before: 5 sleep/wake cycles over ~12 min 51 s. Wake voltage rose 11.9275 → 11.9762 V as the unloaded pack relaxed. Clean exit.
- ~10:57-10:59 - AC back (bounded, not observed - nothing on the network can see through the LVD blackout). The XB7 and host returned at 10:59:49; the host booted with no button press. Fully unattended.
From host-down to LVD: 52 min 47 s, with nobody watching and the BP-65 as the only protection left.
The number that matters
Onset to LVD, the pack delivered 2.5331 Ah / 31.821 Wh in 1 h 30 m 08 s. I trust that figure more than any capacity number this project has published, because it's the first one that's been checked rather than assumed:
- The firmware counter and an independent trapezoidal integration of HA's recorder series agree to +0.95 % - two storage paths, two clocks.
- The integrator matches its own published current to +0.010 %.
- A 12-minute window nobody observed reconciles, by difference, to 1.428 A - right on the ~1.40 A load measured either side of it.
(All three share one sensor, so they prove the INA260's output is carried and integrated correctly, not its absolute accuracy.)
Then the comparison. The 2026-09-01 test ran fourteen days earlier at essentially the same current, over a voltage span this run also crossed:
| 2026-09-01 | 2026-09-15 | Δ | |
|---|---|---|---|
| Voltage span | 12.97 → 12.565 V | 13.034 → 12.546 V | matched |
| Mean current | 2.089 A | 2.043 A | -2.2 % |
| Elapsed | 54 min | 31.0 min | -42.6 % |
| Charge | 1.833 Ah | 1.0559 Ah | -42.4 % |
| Energy | 23.369 Wh | 13.4394 Wh | -42.5 % |
Ah and Wh agree to a tenth of a point. A voltage fault would move Wh without moving Ah, so the shortfall is in the pack, not the instrument. LVD to LVD against May's 4.179 Ah, it's -39.4 %.
What doesn't explain it
- Rate effect at the fixed 11.80 V loaded endpoint: 0.013-0.036 Ah.
- Peukert: closing the gap would need an exponent of 2.40. LiFePO4 is 1.01-1.05.
- Float droop: ≤ 0.11 Ah.
- Temperature: 77.3-78.2 °F, inside LFP's flat zone.
- A pack that wasn't recharged after 09-01: excluded. The fully-charged detector was on for 3 h 51 m right up to this test's cut, and on before the 09-01 run too - both started from the same float equilibrium.
Together: under 10 % of the LVD-to-LVD gap and none of the load-matched gap.
What might - and the test I could run from a desk
The leading candidate is one weak cell or an imbalanced pack. One cell hitting its knee early drags the 4S pack to 11.80 V while three cells still hold charge. The direct test is per-cell voltage at end of discharge, and this pack is sealed - no balance taps, no BMS telemetry. So I ran a substitute on data that had been sitting in the repo since May: pack OCV against charge removed, each run normalised to its own total.
- Uniform fade predicts the two curves overlay - same voltage at the same percentage depth.
- One weak cell predicts September sits below May at every depth, and the gap widens near the end.
September sits below May at every depth both runs cover: -163 mV at 20 %, -221 mV at 50 %, -180 mV at 90 %. It stays below across the whole measured range of internal resistance (93-260 mΩ) used in the correction. Uniform fade predicts zero everywhere.

Pack OCV estimate (V + |I| × 93 mΩ) against depth of discharge, each run normalised to its own delivered charge. The May record ends at 91.5 % depth, when the HA Green - then the recorder - shut itself down; the September gap is the 12 minutes after HA went down and before the direct-API monitor connected. Rebuilt from the repo’s CSV/JSON/log files; it agrees with report §4.6 to within ~0.02 V.
That's evidence against uniform fade and for a non-uniform pack. It isn't proof: the overlay assumes both runs started from the same state, and the May run predates the fully-charged detector.
Two more things the run settled
- The recharge is PSU-limited. Peak captured charge current 4.4465 A is 98.8 % of the Mean Well HDR-60-12's 4.5 A rating. (An earlier revision of the report read it as a 54 amp supply. It's 54 watts.) The bus took 39 min 25 s to re-cross 13.15 V, and 0.792 A was still flowing 51 min 49 s in.
- The shutdown trigger is noise-dominated. Replaying the firmware against this run and 09-01, the slope term has sd 18.7-24.0 mV/min against a -10 mV/min threshold, and every graceful-shutdown attempt in the record aborted at least once before one held. Firmware V1.20 raised the hold from 60 s to 180 s and fixed the V/I/P publish skew behind several bad figures; that's the next log.
What's next
- Repeat the discharge at May's current (Open Item 14a): shut the host down first, so the load is the XB7 and monitor only (~1.2-1.4 A). Same pack, same load, same endpoint, same instrument. If it still delivers ~2.5 Ah against May's 4.179 Ah, the loss is confirmed.
- Coulomb-count one recharge to termination (Open Item 16). Charge accepted ≈ 2.5 Ah then taper to zero means the usable window really is ~2.5 Ah; materially more means the pack hadn't started full.
- The top-off charger - a 14.40 V hold whose current tail is the first direct look at whether this BMS balances at all.
The safety claim held under a real test. The time budget it's tuned against shrank by about two-fifths, and nothing reported it. That's the case for measuring capacity on purpose rather than trusting last quarter's number.
Full report (r3), raw data and reproduction guide: reports/UPS_Report_2026-09-15_Full_Discharge_Survival_Test.md
Bill Collis
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.