3
20
Fork
You've already forked paiesque
1
A privacy-focused fitness analyzer that transforms heart rate data into training load (TRIMP), injury risk (ACWR), and recovery metrics (RHR, HRV) using only peer-reviewed scientific papers
  • Java 95.2%
  • HTML 2.2%
  • PHP 1.4%
  • Kotlin 1.2%
OJ Randon c9251e275f fix: store remote device status and re-upload on group change
- Restore writing of per-device status JSON and zone thresholds to the
 local shared database so the chart and map use the remote user's
 actual thresholds.
- Reset upload timestamps when the user changes group so recent
 recordings are re-sent to the new group (up to server max_file_age_days).
- Reduce server MAX_FILE_AGE_DAYS from 30 to 7.
2026年07月13日 12:26:50 +02:00
app fix: store remote device status and re-upload on group change 2026年07月13日 12:26:50 +02:00
docu/pic doc: pictures for wiki 2025年12月08日 16:07:00 +01:00
fastlane/metadata/android v88 2026年07月11日 17:28:29 +02:00
gradle/wrapper fix: Update Gradle wrapper to version 8.13 2025年11月09日 16:10:54 +01:00
webservice v88 2026年07月11日 17:28:29 +02:00
.gitignore more git ignore files 2026年03月15日 16:45:30 +01:00
build.gradle.kts Migrate from Gadgetbridge to Health Connect 2026年02月08日 22:10:17 +01:00
gradle.properties Initial commit: Paiesque PAI calculator 2025年11月02日 14:56:33 +01:00
gradlew fix: Update Gradle wrapper to version 8.13 2025年11月09日 16:10:54 +01:00
gradlew.bat fix: Update Gradle wrapper to version 8.13 2025年11月09日 16:10:54 +01:00
LICENSE MIT license 2025年11月03日 20:28:23 +01:00
README.md feat: refactor HRV calculation into dedicated HrvCalculator class 2026年06月29日 11:03:24 +02:00
settings.gradle.kts Initial commit: Paiesque PAI calculator 2025年11月02日 14:56:33 +01:00

PAIesque — Training Load & Recovery Analytics

PAIesque is an Android application built on a three-step logic to help athletes and fitness enthusiasts monitor their training and gain actionable insights:

  1. Measure training impulse (TRIMP) - The faster and longer your heart beats, the higher your daily score. Choose from four scientifically-validated methods: Banister, iTRIMP, LT-TRIMP, and PAI-inspired. Your score is automatically distributed across low/moderate/high intensity zones (polarized training).

  2. Analyze patterns over time - Track rolling loads (EWMA = Exponentially Weighted Moving Average) and monitor your Acute:Chronic Workload Ratio (ACWR) to help prevent injury and avoid undertraining.

  3. Monitor your body's response - Overlay your resting heart rate (RHR) and heart rate variability (HRV) directly on your training charts to see how your body reacts to each workout.

All metrics are derived from published, peer-reviewed sports science literature — and all your data stays on your device.

License: MIT

Main Screen Main Screen Profile TRIMP Formula Polarized Zone ACWR Settings Sleep Measurment Time
TRIMP, ACWR, HRR RHR Global Settings Banister Target Settings EWMA Windows RHR/HRV Time

Installation

Install Gadgetbridge from F-Droid, and configure, to read heart rate data from your fitness tracker / wearable, and to write it into Health Connect.

Enable automatic Export

Gadgetbridge Gadgetbridge Gadgetbridge Gadgetbridge Gadgetbridge PAIesque
Open Settings Open External Integration Open Health Connect Health Connect Open Select Devices Import into PAIesque

2. Install PAIesque

PAIesque is available on F-Droid - the free and open-source app store:

Get it on F-Droid

Recommended for most users - automatic updates, verified builds, and easy installation.

Why Choose This App?

Transparent, Verifiable Science

Commercial fitness apps (Garmin, Polar, Whoop) use proprietary algorithms for metrics like Training Effect, Recovery Score, and Body Battery. These calculations are black boxes - users cannot verify how their numbers are derived, and the algorithms can change without notice.

PAIesque takes a different approach. Every metric is implemented from peer-reviewed, published sports science literature with formulas you can examine, understand, and verify. When the app shows you a TRIMP score, you know exactly how it was calculated [Banister, 1991; Morton et al., 1990]. When it warns of a high ACWR, you can trace it to the research that established the 0.8-1.3 "sweet spot" [Gabbett, 2016].

Local-First, No Cloud Lock-In

Commercial fitness ecosystems lock your data into their cloud services. Your heart rate history, training logs, and personal metrics become a liability - you're dependent on their servers, subject to their terms of service, and at risk if they discontinue a product line.

PAIesque stores everything on your device. No accounts, no cloud uploads, no data mining. Your training data belongs to you. You can export your complete history as CSV files or full database backups at any time, without asking permission from anyone.

Only What We Can Verify

PAIesque includes only metrics that can be calculated from heart rate data alone using published, peer-reviewed methods. This means no proprietary "Training Effect" scores, no undisclosed "Recovery" algorithms, no "Body Battery" with secret formulas. If the science isn't published, it's not in this app.

For a detailed discussion of why certain popular metrics (like aerobic/anaerobic contribution scores) are not included - and the laboratory conditions required to calculate them properly - see further below.


Features

Training Load (TRIMP)

TRIMP (Training Impulse) quantifies training load by converting heart rate data into a single score that accounts for both duration and intensity. The key insight: higher intensity efforts receive exponentially more weight, reflecting the greater physiological stress they impose [Banister, 1991].

Banister TRIMP

The original TRIMP formulation with continuous exponential weighting:

TRIMP = duration ×ばつ HRr ×ばつ a ×ばつ exp(b ×ばつ HRr)

where HRr = (HR - HRrest) / (HRmax - HRrest)

  • a and b coefficients are fixed by sex based on empirical data [Morton et al., 1990]:
    • Males: a = 0.64, b = 1.92
    • Females: a = 0.86, b = 1.67
  • Why exponential? Higher heart rates produce disproportionately greater physiological stress - a 5-minute effort at 90% HRmax imposes more fatigue than 10 minutes at 70% HRmax. The exponential term captures this nonlinear relationship.

iTRIMP

Individualized TRIMP using a flexible b coefficient:

iTRIMP = duration ×ばつ HRr ×ばつ exp(b ×ばつ HRr)

  • b coefficient range 1.5-4.0 validated in elite soccer players [Stagno et al., 2007]
  • Physiological meaning of b:
    • b = 1.5-2.5: Gradual lactate rise (typical of endurance-trained athletes)
    • b = 2.5-3.5: Moderate lactate response
    • b = 3.5-4.0: Steep lactate rise (typical of power/sprint athletes)
  • How b affects the curve: Higher b values produce steeper exponential weighting, meaning the same HR increase yields a larger TRIMP increase. This reflects individual differences in lactate accumulation rate.
  • Fitness-based default: The app interpolates b from 1.5 (fitness=0) to 4.0 (fitness=100). This is a heuristic - true individualization requires lactate testing. Override the default if you have test results.

LT-TRIMP (Cheng)

Uses lactate threshold (LT) as a physiological breakpoint, with different weighting above and below [Cheng et al., 1992]:

Below LT (aerobic dominance): TRIMP = 0.5 ×ばつ (HR - HRrest) / (LT - HRrest)

Above LT (anaerobic contribution): TRIMP = 0.5 + sexFactor ×ばつ ((HR - LT)/(HRmax - LT)) ×ばつ exp(β ×ばつ ((HR - LT)/(HRmax - LT)))

  • Why LT as a breakpoint? At LT, the body shifts from predominantly aerobic to increasingly anaerobic metabolism. This transition is physiologically meaningful - below LT, fatigue accumulates linearly with HR; above LT, fatigue accumulates exponentially [Mader et al., 1976].
  • Why 0.5? The 0.5 factor ensures a continuous, smooth transition at LT:
    • At HR = LT, linear formula = 0.5 ×ばつ (LT - HRrest)/(LT - HRrest) = 0.5
    • At HR = LT, exponential formula = 0.5 + sexFactor ×ばつ 0 ×ばつ exp(0) = 0.5
    • This eliminates discontinuities that would otherwise occur at the threshold, creating a physiologically realistic load curve.
  • LT estimation: LT is estimated from fitness level using ranges from exercise physiology literature:
    • Untrained (0-24): 63% of HRmax
    • Recreational (25-49): 75% of HRmax
    • Trained (50-74): 82% of HRmax
    • Elite (75-100): 88% of HRmax
  • β coefficient (0.04-0.11) controls exponential steepness above LT. Higher values produce steeper curves, reflecting faster lactate accumulation in well-trained athletes. The fitness-based default (0.04 → 0.11) is a heuristic - adjust if you have lactate test results.
  • sexFactor = 0.64 (male) / 0.86 (female) [Morton et al., 1990]

PAI-like

A scaled version of the selected base method, inspired by Personal Activity Intelligence research [Nes et al., 2017]:

PAI = baseTRIMP ×ばつ calibration ×ばつ 100

Base method: Choose Banister, iTRIMP, or LT-TRIMP as the foundation

Calibration factor: Scales the base TRIMP so that your typical weekly activity yields PAI values roughly in line with a commercial implementation.

Why 100 PAI? The HUNT Study (n=39,298, >1 million person-years, 26.2 years follow-up) found that maintaining 100 PAI/week is associated with 38% reduced cardiovascular mortality and 46% reduced all-cause mortality [Nes et al., 2017]. This is an evidence-based target, not a maximum - higher values are possible.

How this implementation works:

  • The official PAI algorithm is proprietary and not publicly documented
  • Analysis of commercial implementations shows behavior that does not precisely match either a simple sum or EWMA
  • Paiesque uses a 7-day Exponentially Weighted Moving Average (EWMA) with λ = 0.25
  • This gives greater weight to recent training and produces smooth decay rather than abrupt "cliff edges" when points expire
  • Research shows EWMA is more sensitive for detecting meaningful changes in training load [Murray et al., 2017]

How to calibrate:

  1. Use a device or app that provides official PAI values
  2. Note your 7-day rolling PAI from that device over a typical week
  3. In PAIesque, enable the layer PAI 7d along with layer PAIesque to see the app's rolling PAI
  4. Adjust the calibration factor so that your typical weekly activity yields PAI values roughly comparable to the commercial device
  5. Fine-tune over multiple weeks until the values align consistently with your expectations

Help improve the defaults: If you have access to a commercial PAI device and find a calibration factor that works well for your activity patterns, consider sharing your settings with the community. Your contribution can help establish better default values for users who don't have access to commercial implementations. Report your findings via the issue tracker.

Important disclosure:

  • This is NOT an official implementation of the commercial PAI algorithm
  • Values will differ from commercial PAI devices
  • Focus on trends relative to your baseline, not absolute numbers

Load Monitoring (EWMA & ACWR)

EWMA (Exponentially Weighted Moving Average)

EWMA tracks training load over time, giving more weight to recent sessions. Unlike simple rolling averages (which treat all days equally), EWMA accounts for the decaying nature of fitness and fatigue [Murray et al., 2017].

Formula: EWMA_today = (load_today ×ばつ λ) + (EWMA_yesterday ×ばつ (1-λ))

where λ = 2 / (window + 1)

With the default 7-day window, λ = 0.25.

  • How it works: EWMA gives more weight to recent training. A workout from today contributes 100% to your current load, while a workout from 7 days ago contributes only about 13%. Old training gradually fades away - your fitness adapts and past sessions matter less over time.
  • Example: A hard 60-minute run today adds 60 minutes of load. The same run 7 days ago would add only about 8 minutes to your current load.
  • Why EWMA over rolling averages? In a study of 59 elite Australian football players over 2 seasons, EWMA was more sensitive for detecting meaningful changes (AUC 0.71 vs 0.64) and explained significantly more variance in injury likelihood than rolling averages [Murray et al., 2017].

ACWR (Acute:Chronic Workload Ratio)

ACWR compares short-term load to long-term baseline:

ACWR = acute_EWMA / chronic_EWMA

  • Acute window (default 7 days): Captures recent training stress
  • Chronic window (default 28 days): Establishes historical baseline
  • Interpretation [Gabbett, 2016]: In a study of 53 elite rugby league players, a very-high ACWR (≥2.11) was associated with 16.7% injury risk in the current week, while players with high chronic workload were more resistant to injury across moderate workload ratios
    • <0.8: Possible under-training, may not maintain fitness
    • 0.8-1.3: "Sweet spot" - optimal loading with minimal injury risk
    • >1.3: Elevated injury risk; >1.5 associated with ×ばつ increased risk
  • Coupled vs. uncoupled: Coupled includes acute loads in chronic calculation (standard). Uncoupled excludes them, addressing mathematical coupling concerns [Lolli et al., 2019]
  • Sport-specific windows: The default 7:28 day windows are the most studied across all sports. However, research has identified sport-specific optimal windows:
    • Rugby league: 3:14 days provided the best fit (129,448 loads across 13 clubs) [Griffin et al., 2021]
    • Australian football: 3:21 or 6:21 days best explained injury risk (53 athletes, 2 seasons) [Carey et al., 2017]
    • Soccer (football): No consensus; methodological heterogeneity limits recommendations [Wang et al., 2020]
    • Individual sports (tennis, swimming): Limited evidence; ACWR may be less valid than other monitoring tools [Frontiers, 2019]

You can adjust the windows in settings to match your sport's research base.


Recovery Metrics (RHR & HRV)

Resting Heart Rate (RHR)

RHR is your heart rate during stable sleep - a key indicator of cardiovascular fitness and recovery status.

  • How it's calculated: The app uses the 5th-15th percentile of heart rates during your defined sleep window. The percentile adapts to data quantity (5th percentile with 300+ readings, 15th with fewer) to balance accuracy and reliability.
  • Why percentile instead of minimum? The absolute minimum can be an outlier (e.g., a sensor artifact). The percentile approach gives a stable, representative value [Task Force, 1996].
  • Sleep window: Define your typical sleep hours (e.g., 00:00-06:00). Only data within this window is used, ensuring measurements are taken during actual rest.
  • Trend lines: 7-day acute (dashed) and 30-day chronic (solid) EWMA lines help visualize short-term fluctuations against long-term baseline.
  • Warning threshold: +5 bpm above baseline triggers a dotted red line. Sustained elevation may indicate overreaching [Meeusen et al., 2013].

Heart Rate Variability (HRV)

HRV measures the variation in time between consecutive heartbeats - higher HRV indicates a more responsive, adaptable nervous system.

  • How it's calculated: The app uses RMSSD (Root Mean Square of Successive Differences), the standard time-domain HRV metric in clinical settings [Task Force, 1996]: RMSSD = √[ Σ(BB interval differences)2 / N ]
  • Why RMSSD? It reflects parasympathetic (vagus nerve) activity and is more suitable for daily monitoring than frequency-domain metrics [Buchheit, 2014].
  • Sleep window: Same as RHR—only data during your defined sleep window is used.
  • Trend lines: 7-day acute (dashed) and 30-day chronic (solid) EWMA lines.
  • Warning threshold: -10% below baseline triggers a dotted red line, which may indicate accumulated fatigue [Plews et al., 2013].

Interpreting RHR and HRV Together [Stanley et al., 2013; Plews et al., 2013]

Pattern Interpretation
RHR ↓ + HRV ↑ Positive adaptation - fitness improving, recovery capacity enhanced
RHR ↑ + HRV ↓ Sympathetic dominance - possible accumulated fatigue, inadequate recovery, or stress
RHR stable + HRV ↓ Isolated parasympathetic withdrawal - may indicate mental stress or early fatigue
RHR ↑ + HRV stable External factors - possible hydration issues, caffeine, or minor illness [Atha, 1984]

Polarized Training

Research on elite endurance athletes (cycling, rowing, cross-country skiing) reveals a consistent pattern: ~80% of training at low intensity, ~20% at high intensity, with minimal time in the moderate "gray zone" [Seiler & Tønnessen, 2009]. In recreational runners completing ~35 miles per week, a polarized training model improved 10km race time by 5% compared to 3.6% with threshold training [Muñoz et al., 2014].

Polarized Score (0-100)

A measure of how closely your training distribution matches your zone targets:

Score = 100 - (deviation below targets only)

  • Only penalizes under-target: If you exceed a target (e.g., 80% low instead of 70%), your score stays at 100. This reflects that extra low-intensity work is beneficial, not detrimental.
  • Why this matters: The Polarized Score helps you identify which zones need more focus. If your moderate zone is consistently below target, you might be avoiding threshold work. If your low zone is consistently low, you might not be building enough aerobic base.

Zone Achievements

Daily and rolling 7-day percentages of target time achieved in each zone:

achievement% = min(100, (actual minutes / target minutes) ×ばつ 100)

  • Daily achievements: Show which zones you hit or missed today
  • Rolling 7-day achievements: Smooth out day-to-day variability to show patterns

Interactive Chart

  • Layer toggles — Show/hide:
    • TRIMP (daily scores by zone)
    • 7-day Load (EWMA scores or simple sum)
    • ACWR/Polarized (ACWR zones, polarized score, zone achievements)
    • RHR Daily and RHR Trends
    • HRV Daily and HRV Trends
  • Configurable date range — Use the calendar button to select range. The dual-slider dialog features logarithmic scaling for duration and rate-dependent scaling for end date, making it easy to navigate years of data.

Built‐in Activity Recording (BLE + GPS)

Record heart rate and location data directly from Bluetooth chest straps or other BLE heart rate sensors, without needing Gadgetbridge or any third‐party app.

  • BLE heart‐rate sensor support – connects to standard HR‐service devices (Polar H10, Coospo, etc.); shows live HR, battery level, and RMSSD on the recording screen.
  • GPS tracking – captures speed, distance, and altitude.
  • Configurable recording interval (1–60 seconds) and optional GPS‐accuracy threshold to discard poor‐quality positions.
  • Automatic exports – when you finish, the session is saved as a GPX file (compatible with OSMand, Strava, Garmin, etc.) and a CSV file (time‐series: HR, lat/lon, altitude, speed, RMSSD).
  • Health Connect integration – recorded heart rate and HRV samples can be written back to Health Connect, so they become available for all other apps and for Paiesque’s own analysis.
  • Background recording – a foreground service keeps the recording running even when the screen is off.

This turns Paiesque into a one‐stop solution: you can record a workout, immediately see your TRIMP score and recovery metrics update, and export the raw data for external analysis.


Data Management

  • Health Connect integration — Reads HR and HRV data from any device that writes to Health Connect
  • Built-in Recording – Record heart rate and GPS right inside the app; recorded data feeds into the same analytics and can be exported as GPX/CSV
  • CSV Export — Export all tables with detailed column explanations for analysis in R/Python/Excel
  • CSV Import — Import devices, heart rate samples, and HRV samples
  • Delete Heart Rate Data — Remove raw heart rate samples for a specific device and time range. Useful for cleaning corrupted data or excluding specific periods. TRIMP and RHR automatically recalculate afterward.
  • Full Backup — Complete database snapshot (.db) for migration or archiving
  • Full Restore — Restore complete database snapshot (.db)
  • Delete All Data — Complete local data removal

Educational Resources

  • Dynamic Legend — Tap any metric for detailed explanations, research citations, and direct links to relevant settings. The legend expands to show "why this formula," "how it works," and "what the numbers mean."
  • Comprehensive Help — Built-in HTML help covering all metrics, formulas, and references, with the same educational depth as this README.

Privacy First

  • No accounts — Everything stays on your device
  • No analytics — Zero tracking, zero ads
  • No cloud — All data stored locally in SQLite
  • Full data ownership — Export your data anytime, delete everything with one action

Group Sharing

PAIesque supports sharing your live status and recorded sessions with other users who are members of the same group. All data is stored on a simple PHP web server that you or a friend administrate. No accounts, no database – just static files on a server you control.

How it works

  • The app sends your current heart rate, location, speed, altitude and active device name to the server only while a recording is active and sharing is enabled.
  • When you open the Analysis screen in live mode, the app fetches the status of every other member of your group and displays their positions on the map. Tapping a remote user in the device spinner centres the map on that user.
  • When you save a recording, the full session is uploaded as a daily CSV file (YYYYMMDD_DeviceName.csv). Other group members can download and view your past recordings in the Analysis history mode.
  • A group is identified by a deterministic UUID derived from the group name you choose. All users who enter the same group name automatically become part of the same group.

Server setup (admin)

  1. Copy all PHP files (config.php, auth.php, status.php, upload.php, list.php, group.php, cleanup.php, logger.php) and the .htaccess file into a directory on your web server (e.g. public_html/paiesque/).

  2. Ensure the web server can write to that directory; the data/ and logs/ subdirectories will be created automatically.

  3. Generate a strong random API key (do this once for each key you want to issue):

    openssl rand -hex 32
    

    This prints a 64‐character hexadecimal string, e.g. d4f8a1b2c3d4e5f6.... Of course, you can use just something like Cycle Group Munich instead of a 64‐character hexadecimal string.

  4. Compute the SHA‐256 hash of that key. On Linux or macOS:

    echo -n 'd4f8a1b2c3d4e5f6...' | sha256sum
    

    On macOS you can also use:

    echo -n 'd4f8a1b2c3d4e5f6...' | shasum -a 256
    

    The command outputs a long hex string (the hash) followed by a hyphen or space. Only the hex string matters.

  5. Open config.php in a text editor. Find the $VALID_API_KEYS array. Add the hash as a new element, e.g.:

    $VALID_API_KEYS = [
     'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', // example
     'the_actual_hash_from_step_4',
    ];
    

    You can add as many hashes as you need – one for each key you want to allow. To revoke a key, remove its hash from the array.

  6. Add the User-Agent string that the app sends (Paiesque/ + the app version, e.g. Paiesque/77) to the $VALID_USER_AGENTS array. The default already contains the current version; update it when you update the app.

  7. Optionally adjust MAX_FILE_AGE_DAYS (default 30) – files older than this are deleted during the daily cleanup. You can also change LOG_LEVEL to DEBUG for troubleshooting, then switch back to INFO for normal operation.

  8. Give the raw key (the output of step 3) to the users who are allowed to share. Never share the hash – only the raw key is entered into the app.

No database, no further configuration is needed.

App setup (user)

  1. Open the Recording screen, tap the overflow menu (⋮) and choose Sharing settings.

  2. Enable sharing with the checkbox.

  3. Fill in:

  • Your display name – shown to other group members.
  • Group name – must be exactly the same for all members of the group (e.g. "Cycle Group Munich"). Leave empty to stay private.
  • Server URL – the full URL of the directory where the PHP files are installed (e.g. https://example.com/paiesque/, or use this test server https://jfellow.net/paiesque).
  • API key – the raw key you received from the server administrator. (Use guest for the test server https://jfellow.net/paiesque)
  • Status update interval – how often the app uploads your status while recording, and how often it polls for remote users' positions in live mode.
  1. Save the settings. Sharing starts immediately; disabling it stops all background uploads.

Privacy & data retention

  • The server only stores the data you explicitly send (status snapshots and recordings).
  • Old files are automatically deleted after the configured number of days (MAX_FILE_AGE_DAYS). Empty user directories are removed at the same time.
  • Remote recordings are stored in a separate database on your device and never mixed with your own training data. They are never written to Google Health Connect.
  • You can delete all shared data from your device at any time. The app does not send your data to the server when sharing is disabled.

Troubleshooting

  • Check the server log file (logs/app.log) for authentication errors, upload failures, or cleanup actions. Set LOG_LEVEL to DEBUG in config.php for more detail.
  • On the device, filter logcat by SharingManager, LiveSharingHelper, HistorySharingHelper or SharedRecordingRepository to see detailed upload/download logs.

Getting Started

Using Gadgetbridge with PAIesque

Gadgetbridge is an open-source app that communicates directly with wearables (smartwatches, fitness trackers, chest straps) without sending any data to the manufacturer's cloud. It pairs with PAIesque in two ways:

  1. Direct integration — Gadgetbridge writes heart rate data to Health Connect, which PAIesque reads
  2. No data leaks — Unlike manufacturer apps (Garmin Connect, Polar Flow, etc.), Gadgetbridge doesn't upload your health data to external servers

This combination gives you complete control: open-source firmware communication (Gadgetbridge) plus open-source analytics (PAIesque), with no commercial cloud services between.

Prerequisites

  • Android device with Health Connect installed (pre-installed on GrapheneOS, or available on Google Play)
  • Heart rate data synced to Health Connect from Gadgetbridge or another source

First Run

  1. Grant Health Connect permissions — The app requests READ_HEART_RATE and READ_HEART_RATE_VARIABILITY permissions. When granting these permissions, you can choose to allow access to all historical data (full history) or only recent data, giving you control over how much heart rate and HRV history the app can read.

  2. Sync data — Choose to sync immediately or import from a backup

    • Sync now: Reads heart rate and HRV data from Health Connect based on the permission level granted
    • Restore from backup: Imports a complete database snapshot (.db file) including all previously calculated metrics
    • Skip for now: Proceed without syncing (useful if you plan to import data later)
  3. Configure your profile — Set age, gender, fitness level, and preferred HR calculation methods

  4. Start analyzing — Explore the chart, toggle layers, and adjust date ranges

Data Sources

PAIesque reads from Health Connect, which aggregates data from:

  • Gadgetbridge (recommended for open-source wearables)
  • Smartwatches (Garmin, Samsung, Apple Watch via third-party sync)
  • Chest straps (Polar, Wahoo, etc.)
  • Any app that writes to Health Connect

Why Some Metrics Are Not Included

Commercial fitness apps often display metrics like "Aerobic/Anaerobic Training Effect," "EPOC" (Excess Post-Exercise Oxygen Consumption), or detailed breakdowns of alactic vs. lactic energy system contributions. PAIesque does not calculate these metrics for specific, evidence-based reasons:

Aerobic/Anaerobic Contribution Scores

Metrics like the 0-5 Training Effect in commercial systems (Firstbeat, 2024) are proprietary algorithms. While these metrics are used by over 1,000 elite teams worldwide [Firstbeat Analytics, 2023], the exact calculations are not publicly documented for independent verification [Firstbeat Technologies, 2023]. The white papers describing them are not peer-reviewed publications with transparent methodologies.

The only peer-reviewed method with strong evidence for quantifying anaerobic contribution - MAOD (Maximal Accumulated Oxygen Deficit) - requires laboratory conditions [Medbø et al., 1988; Ambaum & Hoppe, 2025]:

  • Multiple submaximal tests on a treadmill or cycle ergometer to establish oxygen demand
  • A supramaximal test to exhaustion requiring maximal effort under supervision
  • Metabolic cart for breath-by-breath oxygen measurement

These conditions cannot be replicated from heart rate data alone.

EPOC (Excess Post-Exercise Oxygen Consumption)

EPOC prediction models in commercial wearables require:

  • Classification of exercise type (continuous vs. interval vs. accumulated) [Jung et al., 2021]
  • Knowledge of body composition (fat-free mass) [Jung et al., 2021]
  • Controlled conditions rather than real-world 24/7 monitoring

These parameters are not available from heart rate data alone.

Alactic vs. Lactic Contribution

Methods that distinguish between alactic and lactic energy contributions (PCr-La-O2 models) require either:

  • Muscle biopsy samples to measure phosphocreatine depletion [Bangsbo, 1998]
  • Post-exercise oxygen consumption measurement with specific protocols

Neither is feasible from consumer-grade heart rate monitors.

Our philosophy: If you find published, peer-reviewed research with transparent methods that can be calculated from heart rate data alone, those metrics are candidates for future integration. The app only includes metrics we can verify and reproduce from first principles.


Scientific References

TRIMP Methods

  • Banister, E. W. (1991). Modeling elite athletic performance. In: Physiological Testing of the High-Performance Athlete, pp. 403-424.
  • Morton, R. H., Fitz-Clarke, J. R., & Banister, E. W. (1990). Modeling human performance in running. Journal of Applied Physiology, 69(3), 1171-1177.
  • Stagno, K. M., Thatcher, R., & van Someren, K. A. (2007). A modified TRIMP to quantify the in-season training load of elite soccer players. Journal of Sports Sciences, 25(6), 629-634.
  • Cheng, B., Kuipers, H., Snyder, A. C., Keizer, H. A., Jeukendrup, A., & Hesselink, M. (1992). A new approach for the determination of the individual anaerobic threshold. International Journal of Sports Medicine, 13(5), 354-361.
  • Nes, B. M., Gutvik, C. R., Lavie, C. J., Nauman, J., & Wisløff, U. (2017). Personalized Activity Intelligence (PAI) for Prevention of Cardiovascular Disease and Promotion of Physical Activity. The American Journal of Medicine, 130(3), 328–336.

EWMA & ACWR

  • Murray, N. B., Gabbett, T. J., Townshend, A. D., & Blanch, P. (2017). Calculating acute:chronic workload ratios using exponentially weighted moving averages provides a more sensitive indicator of injury likelihood than rolling averages. British Journal of Sports Medicine, 51(9), 749-754.
  • Gabbett, T. J. (2016). The training—injury prevention paradox: should athletes be training smarter and harder? British Journal of Sports Medicine, 50(5), 273-280.
  • Griffin, A., Kenny, I. C., Comyns, T. M., & Lyons, M. (2021). The association between the acute:chronic workload ratio and injury and its application in team sports: A systematic review. British Journal of Sports Medicine, 55(3), 145-152.
  • Lolli, L., Batterham, A. M., Hawkins, R., Kelly, D. M., Strudwick, A. J., Thorpe, R. T., & Gregson, W. (2019). Mathematical coupling in the acute:chronic workload ratio. British Journal of Sports Medicine, 53(20), 1313-1314.

Recovery Metrics (RHR & HRV)

  • Task Force of the European Society of Cardiology and the North American Society of Pacing and Electrophysiology. (1996). Heart rate variability: standards of measurement, physiological interpretation, and clinical use. European Heart Journal, 17(3), 354-381.
  • Plews, D. J., Laursen, P. B., Stanley, J., Kilding, A. E., & Buchheit, M. (2013). Heart rate variability in athletes: a meta-analysis. Sports Medicine, 43(5), 379-394.
  • Meeusen, R., Duclos, M., Foster, C., Fry, A., Gleeson, M., Nieman, D., ... & Urhausen, A. (2013). Prevention, diagnosis, and treatment of the overtraining syndrome: joint consensus statement of the European College of Sport Science and the American College of Sports Medicine. European Journal of Sport Science, 13(1), 1-24.
  • Buchheit, M. (2014). Monitoring training status with HRV. International Journal of Sports Physiology and Performance, 9(5), 744-754.
  • Stanley, J., Peake, J. M., & Buchheit, M. (2013). Cardiac parasympathetic reactivation following exercise: implications for training prescription. Sports Medicine, 43(12), 1259-1277.
  • Atha, J. (1984). Self-induced lowering of heart rate. Biological Psychology, 18(4), 287-311.

Polarized Training

  • Seiler, S., & Tønnessen, E. (2009). Intervals, thresholds, and long slow distance: the role of intensity and duration in endurance training. International Journal of Sports Physiology and Performance, 4(3), 387-391.
  • Stöggl, T., & Sperlich, B. (2014). Polarized training has greater effects on performance than threshold, high intensity, or high volume training. Frontiers in Physiology, 5, 33.
  • Muñoz, I., Seiler, S., Bautista, J., España, J., Larumbe, E., & Esteve-Lanao, J. (2014). Does polarized training improve performance in recreational runners? International Journal of Sports Physiology and Performance, 9(2), 265-272. (n=27 recreational runners, ~35 miles/week)

Lactate Physiology

  • Mader, A., Liesen, H., Heck, H., Philippi, H., Rost, R., Schürch, P., & Hollmann, W. (1976). Zur Beurteilung der sportartspezifischen Ausdauerleistungsfähigkeit im Labor. Sportarzt und Sportmedizin, 27(4), 80-88.
  • Gaesser, G. A., & Poole, D. C. (1986). Lactate and ventilatory thresholds: disparity in time course of adaptations to training. Journal of Applied Physiology, 61(3), 999-1004.
  • Jones, A. M., & Carter, H. (2000). The effect of endurance training on parameters of aerobic fitness. Sports Medicine, 29(6), 373-386.

Excluded Metrics References

  • Ambaum, C., & Hoppe, M. W. (2025). Evaluation of methods to quantify aerobic-anaerobic energy contributions during sports and exercise — a systematic review and best-evidence synthesis. Frontiers in Sports and Active Living, 7, 1650741.
  • Bangsbo, J. (1998). Quantification of anaerobic energy production during intense exercise. Medicine & Science in Sports & Exercise, 30(1), 47-52.
  • Firstbeat Analytics. (2023). Global adoption statistics. Firstbeat Sports Report.
  • Firstbeat Technologies. (2023). Firstbeat Training Effect algorithm description. Firstbeat White Paper.
  • Jung, W. S., Hwang, H., Kim, J., Park, H. Y., & Lim, K. (2021). Development of regression models for predicting excess post-exercise oxygen consumption after different modes of exercise. European Journal of Applied Physiology, 121(10), 2857-2867.
  • Medbø, J. I., Mohn, A. C., Tabata, I., Bahr, R., Vaage, O., & Sejersted, O. M. (1988). Anaerobic capacity determined by maximal accumulated O2 deficit. Journal of Applied Physiology, 64(1), 50-60.

Export Data Structure

CSV exports include all tables with detailed column explanations:

Table Description
devices.csv Device metadata (manufacturer, model, identifier)
heart_rate_samples.csv Raw heart rate measurements
hrv_samples.csv Raw HRV measurements (RMSSD)
daily_training_metrics.csv Daily TRIMP scores, zone distribution, EWMA, ACWR, polarized scores
daily_rhr.csv Daily resting heart rates with EWMA trends
daily_hrv.csv Daily HRV averages with EWMA trends
calculation_tracker.csv Last processed dates for incremental calculations
app_preferences.csv All user settings by category

See the in-app Help for full column explanations.

Creative Use Cases

Once you understand the data structures, you can use PAIesque in creative ways:

  • Coach analyzing athlete data — Have athletes export their data (CSV or backup), import into your instance, analyze charts, export charts (PNG/SVG) for feedback
  • Research in spreadsheets or R/Python — Export CSV files and perform your own statistical analysis on the calculated metrics
  • Long-term personal tracking — Export backups periodically to archive your complete training history across device changes
  • Comparing training methodologies — Import different periods (e.g., base building vs. race preparation) and compare the metrics
  • Testing with sample datasets — Create sample CSV files to understand how calculations respond to different inputs
  • Building custom analysis tools — Use the exported data as input for your own applications
  • Switch between athletes — Use "Delete All Data" followed by importing a different athlete's CSV files to analyze multiple individuals on the same device

Settings & Customization

Global Profile

  • Age, gender, fitness level (0-100) — Fitness level affects iTRIMP b coefficient, LT-TRIMP LT% and β, and lactate curve parameters. These are heuristics based on published ranges - override if you have test results.
  • Resting Heart Rate — Can be manual (if you have a measured value) or app-calculated from your sleep data
  • Maximum Heart Rate — Manual or formula-based:
    • Shargal et al. (2015): 208.6 - ×ばつage (male), 209.3 - ×ばつage (female) — largest sample size (28,137)
    • Tanaka et al. (2001): 208 - ×ばつage — best for general population (18,712 subjects)
    • HUNT Study (Nes et al., 2013): 211 - ×ばつage — better for trained individuals
    • Fox (1971): 220 - age — traditional formula, less accurate for older adults

Method-Specific

  • Banister TRIMP: Sex-specific coefficients fixed; optional b coefficient slider for experimental exploration
  • iTRIMP: b coefficient slider (1.5-4.0) with fitness-based default. Higher values = steeper lactate response
  • LT-TRIMP: LT estimated from fitness; β slider (0.04-0.11) controls exponential steepness above LT
  • PAI: Base method selection and calibration factor. Adjust so your typical weekly activity yields around 100 PAI

Load Monitoring

  • Acute window (3-9 days) — Default 7 days. Shorter windows (3-5 days) may work better for team sports [Griffin et al., 2021]
  • Chronic window (14-35 days) — Default 28 days. Longer windows provide more stable baseline
  • Coupled/uncoupled — Coupled is standard; uncoupled addresses mathematical coupling concerns [Lolli et al., 2019]

Recovery Metrics

  • Sleep window — Define your typical sleep hours. Only data within this window is used for RHR and HRV
  • Acute/chronic windows — Default 7/30 days. These control EWMA smoothing for trend lines
  • Data source — Choose between same as training device or all devices combined. "Always All Devices" is best for 24/7 wear

Polarized Training

  • Adjustable zone targets (default: 70% low, 10% moderate, 20% high). These are based on elite endurance athlete patterns [Seiler & Tønnessen, 2009] but can be customized for your sport and goals

Implementation Insights

From Heart Rate to TRIMP Score

flowchart TD
 subgraph TRIMP_Formulas["TRIMP CALCULATION METHODS"]
 direction TB
 
 subgraph Common["Common Parameters"]
 HRrest["HRrest - Resting Heart Rate"]
 HRmax["HRmax - Maximum Heart Rate"]
 HR["HR - Current Heart Rate"]
 HRr["HRratio = (HR - HRrest) / (HRmax - HRrest)"]
 duration["duration - seconds in interval"]
 end
 
 subgraph Banister["BANISTER TRIMP (1991)"]
 BAN_title["TRIMP = duration ×ばつ HRr ×ばつ a ×ばつ e^(b ×ばつ HRr)"]
 BAN_a["a coefficient:<br/>Male: 0.64 | Female: 0.86"]
 BAN_b["b coefficient:<br/>Male: 1.92 | Female: 1.67"]
 BAN_note["Continuous exponential curve<br/>No breakpoint<br/>Validated in endurance sports"]
 end
 
 subgraph iTRIMP["iTRIMP (Stagno et al., 2007)"]
 ITR_title["iTRIMP = duration ×ばつ HRr ×ばつ e^(b ×ばつ HRr)"]
 ITR_b["b coefficient: 1.5 - 4.0<br/>Individualized from lactate profile"]
 ITR_note["Fitness-based default in app:<br/>b = 1.5 + (fitness/100) ×ばつ 2.5<br/>Validated in team sports"]
 end
 
 subgraph LT_TRIMP["LT-TRIMP (Cheng-based)"]
 LT_title1["For HR ≤ LT:"]
 LT_form1["TRIMP = 0.5 ×ばつ (HR - HRrest) / (LT - HRrest)"]
 
 LT_title2["For HR > LT:"]
 LT_form2["TRIMP = 0.5 + sexFactor ×ばつ ((HR - LT)/(HRmax - LT)) ×ばつ e^(β ×ばつ ((HR - LT)/(HRmax - LT)))"]
 
 LT_sex["sexFactor: Male 0.64 | Female 0.86"]
 LT_b["β coefficient: 0.04 - 0.11<br/>Fitness-based default (0.04 → 0.11)"]
 LT_LT["LT - Lactate Threshold HR<br/>Estimated from fitness level:<br/>Untrained: 63% HRmax<br/>Recreational: 75%<br/>Trained: 82%<br/>Elite: 88%"]
 LT_note["Linear below LT, exponential above LT<br/>Smooth transition at 0.5"]
 end
 
 subgraph PAI["PAI (Personal Activity Intelligence)"]
 PAI_title["PAI = baseTRIMP ×ばつ calibration ×ばつ 100"]
 PAI_base["Base method: Banister, iTRIMP, or LT-TRIMP"]
 PAI_cal["Calibration factors:<br/>LT-TRIMP: 3.2<br/>Banister: 1.0<br/>iTRIMP: 0.48"]
 PAI_note["7-day rolling (EWMA)<br/>100 PAI/week = evidence-based health target"]
 end
 
 subgraph Thresholds["Scoring Thresholds (where accumulation begins)"]
 TH_rest["Resting HR: Most sensitive, counts all activity"]
 TH_50max["50% HRmax: Moderate filtering (Edwards, 1993)"]
 TH_50hrr["50% HRR: Personalized (Karvonen, 1957)"]
 end
 
 Common --> Banister
 Common --> iTRIMP
 Common --> LT_TRIMP
 Common --> PAI
 end

Implementing Core Classes

TrimpCalculator.java
TrainingMetricsCalculator.java
SimpleRHRCalculator.java
SimpleHrvCalculator.java

Heart Rate Variability (HRV) – How Paiesque Measures It

Data Source

  • A BLE heart rate sensor (e.g., chest strap) continuously sends notification packets to the phone.
  • Paiesque does not poll at fixed intervals – it receives every single packet pushed by the sensor in real time.
  • Each packet contains the current heart rate and, optionally, one or more RR‐intervals (the time between two heartbeats).

RR‐Interval Extraction

  • The format is defined by the Bluetooth Heart Rate Service Specification and the ISO/IEEE 11073‐10407 standard.
  • RR intervals are transmitted in units of 1/1024 s (about 0.98 ms).
  • Paiesque converts them to milliseconds using value / 1024.0 * 1000.0 and rounds to the nearest integer.

Sliding Window

  • Only the most recent sliding window of RR‐intervals is kept in memory.
  • The default window length is 60 seconds, but this can be changed in the app’s settings.
  • Older intervals are automatically discarded when they fall outside the window.

The HRV Metric – RMSSD

  • The app calculates RMSSD (root mean square of successive differences), the most widely recommended time‐domain HRV parameter for short‐term recordings.
  • Formula (after the 1996 ESC/NASPE Task Force):
    RMSSD = √( (1/N) · Σ (RR[i] – RR[i-1])2 )
    where RR[i] are consecutive RR‐intervals in milliseconds, and N is the number of successive differences.
  • RMSSD primarily reflects parasympathetic (vagal) nervous system activity and is sensitive to recovery, stress, and training load.

Gap Detection (configurable)

  • The app can optionally discard an RR interval if it differs from the previous one by more than a configurable fraction (default 20 %).
  • This removes probable missed beats or sensor artefacts, which would otherwise inflate the RMSSD value.
  • Gap detection can be turned on/off in the settings, together with the allowed change fraction.

Implementation Details

  • The entire HRV logic is encapsulated in a single, self‐contained class: HrvCalculator.
  • It holds the sliding buffer, applies the RMSSD formula, and provides methods to feed new intervals and retrieve the current RMSSD.
  • The BLE manager (BleHeartRateManager) creates one HrvCalculator per connected sensor, feeds RR values as they arrive, and reads the live RMSSD.
  • The window length, gap detection, and gap fraction are read from the app’s settings, so advanced users can experiment with different parameters.

References

  • Task Force of the ESC and NASPE (1996). "Heart rate variability – Standards of measurement, physiological interpretation, and clinical use." Eur Heart J 17: 354‐381.
  • Nunan D et al. (2010). "A quantitative systematic review of normal values for short‐term heart rate variability in healthy adults." Pacing Clin Electrophysiol 33(11): 1407‐1417.
  • Bluetooth Heart Rate Service Specification (v1.0).
  • ISO/IEEE 11073‐10407: Health informatics – Personal health device communication – Device specialization – Cardiovascular fitness and activity monitor.

Similar Products

Comparison of Fitness Scoring Systems and Methods

For Developers: Setup & Building

Prerequisites

  • Android Studio (latest version recommended)
  • JDK 11 or higher
  • Android SDK Platform 33 or higher
  • Git

Build from Source

Clone the repository

git clone https://codeberg.org/ojrandom/paiesque

or

git clone https://codeberg.org/ojrandom/paiesque

then

cd paiesque

Open in Android Studio

android-studio .

Or build from command line

./gradlew assembleDebug

find the apk, e.g.

ls app/build/outputs/apk/release

... and copy the apk to your device.

License

MIT License

Copyright (c) 2025 PAIesque Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Contributing

Contributions are welcome! Please feel free to submit pull requests or open issues for:

  • Code contributions
  • Bug fixes
  • Validation of formulas and scientific sources
  • Help to find default PAI-calibration values

PAIesque — Because your training data should be yours.