feat(power): add UPS battery monitoring - #2
Closed
johnpacino wants to merge 10 commits into
Closed
Conversation
added 10 commits
August 15, 2026 17:12
Owner
Author
|
Superseded by the upstream draft: open-flight#212 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
This is stacked on upstream PR #200. Its base is PR200's head branch so this draft contains only the battery feature. Retarget it to upstream
mainafter PR200 merges.What does this PR do?
Adds optional battery and external-power monitoring to OpenFlight, initially supporting the Geekworm X1202 and X1206 UPS boards through
--battery geekworm.The feature introduces a generic
PowerReaderprovider contract, a Linuxpower_supplyreader, and a direct Geekworm MAX1704x/GPIO fallback. The existing WebSocket UI shows plugged-in, on-battery, low, critical, and unavailable states. Dismissible warnings appear at 20% and 10% while discharging, and throttledpower_statusrecords are written to session logs.Raspberry Pi setup and operator documentation are organized under
scripts/battery/anddocs/battery/. The setup enables native MAX17040 and charger telemetry and can install a shared Raspberry Pi taskbar compatibility package. It intentionally does not install automatic-shutdown or charging-control services.Screenshots
OpenFlight battery status
Indicator states
Warning dialogs
Raspberry Pi taskbar
Why was this required?
OpenFlight can run from UPS batteries, but previously gave the operator no indication that external power had been removed or that the battery was nearing depletion. That made an unexpected Pi power loss and filesystem damage more likely.
The hardware integration also needed to be provider-based rather than embedded as Geekworm-specific application behavior. Comparable UPS boards expose the same minimum information through different Linux drivers or I2C register maps, so the generic reader contract keeps UI state, warnings, retries, and logging independent of the selected board.
On the tested Geekworm configuration, the MAX17040 Linux driver exposes a standard
capacityvalue rather than the charge or energy counters expected by Raspberry Pi's taskbar plugin. The included compatibility patch reads that standard value and clamps small full-charge overshoots to 100%.Automated tests
Added and updated tests covering:
power_supplydiscovery, validation, and 100% clamping--battery geekwormforwarding and server argument validationValidation performed:
uv run pytest tests/ -q- 1,315 passed, 8 skippeduv run pylint src/openflight/ --fail-under=9- 9.72/10uv run ruff check src/openflight/- passedcd ui && npm test -- --run- 35 passedcd ui && npm run build- passedcd ui && npm run lint- passedbash -n scripts/start-kiosk.sh scripts/setup/setup.sh scripts/battery/geekworm/setup.sh- passedManual (human) testing
Deployed the feature checkout to a separate directory on a Raspberry Pi 5 and built the production UI there. With a connected Geekworm UPS board:
/sys/class/power_supply.charger/onlinechanged between1and0when input power was connected and removed.--state or Raspberry Pi taskbar 0% state.max17040_batteryandgpio_chargermodules, EEPROM power settings, UPower device, patched taskbar package, andget_throttled=0x0.Automatic shutdown was deliberately not exercised because this PR does not implement shutdown control.
Checklist
uv run pytest tests/ -v)uv run pylint src/openflight/ --fail-under=9)uv run ruff check src/openflight/)cd ui && npm run build)cd ui && npm run lint)