A Vue 3 SPA that runs on the Android tablet HMI of a Keiser A500 pneumatic
strength machine, replacing Keiser's factory test UI with custom NPS test
protocols. Drives the board directly (setForce/rep events) from JavaScript
rather than using the factory's hardcoded board-firmware test mode — full
control over ramp curves, rep counts, rest timing, and (for the Maximal test)
a machine-aware load ramp.
This repo is a snapshot of keiser_webapp/ from the parent nps_a500
monorepo, working state as of 2026-07-31. See docs/BUILD_AND_DEPLOY.md
for how to actually get this onto a machine.
src/sportPerformance/— the NPS app itself (pages, components, modals, protocols, services). This is the only bundle that gets modified.src/root/— the factory root bundle, kept intentionally unmodified. It owns the 13-step board RPC handshake and registers the nativewindow.A500.*plugins the app depends on. Never edit this — seedocs/ARCHITECTURE.mdfor why.lib/— shared code between both bundles: the native bridge interface (a500AppInterface.ts), board module types (modules/mainBoard.ts), auth client (edgeAuth.ts), constants (Keiser machine-type lookup table, etc.).scripts/— the APK build pipeline (unpacks the factory APK, injects both bundles, patches the manifest, repacks and signs).
npm install
npm run build:sport # builds just the sportPerformance bundle (faster)
npm run build # builds both bundles
npm run dev:sport # Vite dev server — browser preview only, no Cordova bridgeBuilding an installable APK requires external tooling not in this repo
(apktool.jar, uber-apk-signer.jar, a debug keystore, and a factory Keiser
APK to unpack) — see docs/BUILD_AND_DEPLOY.md.
Three protocols are registered (src/sportPerformance/protocols/index.ts):
| Protocol | ID | Summary |
|---|---|---|
| Maximal Strength & Power | keiser-10rep |
ROM calibration → warmup → machine-aware ramp to the athlete's 1RM and beyond |
| Load-Velocity Profile | lvp |
5 fixed reps at 40/50/60/70/80% of 1RM, auto-completes |
| Repetitions Maximum | rm |
AMRAP at 70% of entered 1RM, estimates a refined 1RM from performance |
Full behavior, exact math, and what gets submitted to the edge server vs.
shown on-device only: docs/PROTOCOLS.md.
docs/ARCHITECTURE.md— two-bundle system, service layer, board integration, why the factory root bundle can't be toucheddocs/PROTOCOLS.md— detailed, verified protocol referencedocs/BUILD_AND_DEPLOY.md— build commands, per-machine configuration, adb deploy/rollback proceduredocs/DATA_FORMAT.md— the edge submission contract and how it maps to the real Pi edge server's schemadocs/KNOWN_ISSUES.md— dead code paths, gaps, and things a future contributor should know before assuming something's broken (or assuming something works)docs/DUAL_PISTON_CONVERSION.md— what's needed to support a dual-sided (double-piston) machine; not implemented or tested, this is a design map from reading the code
The handoff-docs branch has a CHANGES.patch file — a git-apply-able diff
against the original nps_a500 monorepo, for merging this snapshot's changes
back into that repo instead of treating this as a permanent fork.
All changes here are confined to the Android HMI layer (Tier 3). The board's processor firmware (Tier 2, safety-critical — pneumatic control, blow-off valves) is never touched by anything in this repo. The app only ever transmits load requests; the board firmware retains final authority over physical safety limits.