Real-time physiological monitoring platform for sports medicine β Athlete Β· Coach Β· Medical
Biomedical Engineering Portfolio Β· Alonso MartΓn DΓez Β· Universidad Europea de Madrid Β· 2026
MedSport Monitor is a professional desktop application that centralises real-time physiological data for sports teams. It connects IoMT wearable sensors via MQTT, analyses physiological signals through a Python microservice, and surfaces the results through a multi-role JavaFX interface.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MedSport Monitor β
β β
β ββββββββββββββββ MQTT ββββββββββββββββββββββββββββ β
β β Python β βββββββββββΊ β JavaFX 21 Desktop App β β
β β Simulator β medsport/ β β β
β β (paho-mqtt) β {team}/ β ββββββββββ βββββββββββ β β
β ββββββββββββββββ {athlete}/ β βAthlete β β Coach β β β
β {sensor} β β UI β β UI β β β
β ββββββββββββββββ β ββββββββββ βββββββββββ β β
β β Mosquitto β β ββββββββββββ β β
β β MQTT Broker β β β Medical β β β
β β :1883 β β β UI β β β
β ββββββββββββββββ β ββββββββββββ β β
β β β β
β ββββββββββββββββ HTTP β βββββββββββββββββββββββββ β
β β FastAPI β βββββββββββΊ β β SQLite DB (WAL) ββ β
β β Analytics β :8000 β βββββββββββββββββββββββββ β
β β (uvicorn) β ββββββββββββββββββββββββββββ β
β ββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Capability | Details |
|---|---|
| Live sensor streaming | HR, SpOβ, GPS track, accelerometer (10 Hz), cadence via MQTT |
| Multi-role access control | Three distinct dashboards: Athlete, Coach, Medical |
| Physiological analytics | Heart zones (Karvonen), HRV, fatigue index, ACR, cardiovascular risk |
| Clinical records | SOAP notes, medical restrictions, return-to-play tracking |
| PDF reports | Generated by FastAPI + ReportLab, downloadable from the medical panel |
| Team management | Alert thresholds per team, session control, real-time chat |
| Offline mode | App works fully without Mosquitto β demo data replaces live feeds |
| Layer | Technology |
|---|---|
| Desktop UI | JavaFX 21, FXML, CSS glassmorphism |
| Language | Java 21 (JPMS modules) |
| Build | Maven 3 + Maven Wrapper (mvnw) |
| Sensor data | Eclipse Paho MQTT 1.2.5 |
| Database | SQLite via JDBC (WAL mode) |
| Authentication | PBKDF2-SHA256 (JPMS-compatible, no BCrypt native lib) |
| Simulator | Python 3.11+, paho-mqtt 2.x, NumPy, SciPy |
| Analytics API | FastAPI + uvicorn, NumPy, SciPy |
| PDF reports | ReportLab 4.x |
| MQTT broker | Eclipse Mosquitto 2.x |
| HTTP client | java.net.http (JDK built-in, no extra deps) |
| JSON | Jackson 2.x |
Important: The project must be placed at
~/Downloads/MedSport/(i.e.C:\Users\<you>\Downloads\MedSporton Windows) because the database path is resolved relative to the user home. The database is auto-created on first launch.
cd MedSport
start.batcd MedSport
chmod +x start.sh && ./start.shThe startup script handles everything automatically:
- Starts Mosquitto MQTT broker on port 1883 (graceful skip if not installed)
- Creates a Python virtual environment and installs all dependencies
- Starts the FastAPI analytics service on
:8000 - Starts the physiological simulator (6 athletes, multi-threaded, publishes every 1 s)
- Compiles and launches the JavaFX desktop application
| Requirement | Minimum | Install |
|---|---|---|
| Java | 21 | Adoptium Temurin 21 β set JAVA_HOME |
| Python | 3.11+ | python.org |
| Maven | 3.9+ | Included as Maven Wrapper β no install needed |
| Mosquitto | 2.x | Optional β app runs in demo mode without it |
# Windows
winget install EclipseFoundation.Mosquitto
# macOS
brew install mosquitto
# Ubuntu / Debian
sudo apt install mosquittoMedSport/
β
βββ π± java-app/ # JavaFX 21 desktop application
β βββ src/main/java/com/medsport/
β β βββ auth/ # Login, SessionManager, PasswordUtils
β β βββ controllers/
β β β βββ athlete/ # Dashboard, Sessions, Performance, Team, Profile
β β β βββ coach/ # Dashboard, Session, Comparison, TeamMgmt,
β β β β # Simulator, Performance
β β β βββ medical/ # Dashboard, History (SOAP), Restrictions,
β β β β # Risk, Reports
β β β βββ shared/ # MainLayout, TeamWizard, JoinTeam, Notifications
β β βββ models/ # User, Team, Session, SensorReading, Alert,
β β β # SoapNote, MedicalRestriction, β¦
β β βββ services/ # DatabaseService, MqttService, AlertService,
β β β # SessionService, TeamService, ChatService,
β β β # AnalyticsRestClient, PdfService
β β βββ views/components/ # RippleEffect, AnimatedBackground, ViewTransition
β βββ src/main/resources/
β βββ css/ # base.css + role themes (athlete/coach/medical)
β βββ fxml/ # All screen layouts (login, main, per-role views)
β βββ database/ # schema.sql + seed_data.sql (loaded on first run)
β
βββ π python-simulator/ # IoMT sensor simulator
β βββ simulator.py # Entry point β multi-threaded, 6 athlete threads
β βββ config.py # Broker settings, athlete profiles, publish intervals
β βββ requirements.txt # paho-mqtt, numpy, scipy
β βββ physiological_models/
β βββ heart_rate_model.py # Realistic HR with effort ramps
β βββ spo2_model.py # SpOβ correlated with HR zone
β βββ gps_model.py # GPS route simulation (lat/lon/speed/alt)
β βββ accelerometer_model.py # 3-axis accelerometer at 10 Hz
β βββ athlete_profile.py # Per-athlete biometric parameters
β
βββ π python-analytics/ # FastAPI microservice for advanced analytics
β βββ main.py # API routes
β βββ requirements.txt # fastapi, uvicorn, numpy, scipy, reportlab
β βββ analysis/
β βββ heart_zones.py # Karvonen zone distribution + HRV
β βββ fatigue_index.py # ACR (Acute:Chronic Ratio), fatigue classification
β βββ radar_metrics.py # 6-axis performance polygon
β βββ cardiovascular_risk.py # Risk score + contributing factors
β βββ hrv_analysis.py # RMSSD, SDNN, pNN50 from HR series
β βββ training_load.py # Team-wide load, overload flags
β βββ pdf_generator.py # ReportLab clinical PDF generator
β
βββ ποΈ database/
β βββ schema.sql # 17-table SQLite schema (auto-run on first start)
β βββ seed_data.sql # 29 demo users, 4 teams, sessions, readings, alerts
β
βββ π docs/
β βββ architecture.md # Detailed architecture and design decisions
β
βββ mosquitto.conf # MQTT broker config (port 1883, anonymous)
βββ start.bat # Windows one-click launch
βββ start.sh # macOS/Linux one-click launch
βββ stop_all.bat # Windows β kill all background services
| Screen | Features |
|---|---|
| Dashboard | Live HR with animated pulse dot, SpOβ gauge, GPS track canvas (auto-scale route), heart zone bars (Z1βZ5), speed, cadence, session clock |
| Sessions | Table of past sessions with detail panel (date, type, duration, zone breakdown, avg HR) |
| Performance | Radar chart (6 axes: Endurance Β· Speed Β· Recovery Β· Consistency Β· Load Β· Intensity), Acute:Chronic Ratio, analytics from FastAPI |
| Team Chat | Real-time chat via SQLite polling, chat bubbles, unread badge |
| Profile | Edit name, sport, height, weight; change password with PBKDF2 re-hash |
| Screen | Features |
|---|---|
| Dashboard | FlowPane athlete cards with live HR/SpOβ/zone, alert feed with ACK, session quick-start button |
| Session | Start/stop session, per-athlete live rows with intensity display, zone range control, session timer |
| Comparison | Dual-athlete radar overlay (blue vs green), live HR/SpOβ side-by-side |
| Team Management | Athlete roster, HR%/SpOβ%/weekly-load alert threshold sliders, saved to DB |
| Simulator Control | MQTT connection control panel, per-athlete intensity sliders, message log with counters |
| Performance | Per-athlete radar from radar-metrics, fatigue index, ACR, team load overview |
| Screen | Features |
|---|---|
| Dashboard | Athlete status grid (live HR/SpOβ with alarm dots), critical alert feed with ACK, active restrictions list |
| History (SOAP) | Per-athlete SOAP note list, note detail viewer, new SOAP note form (S/O/A/P + private flag) |
| Restrictions | Add Full / Partial / HR-Limited restrictions with return-to-play date; resolve active restrictions |
| Risk Analysis | Per-athlete risk score bars (live HR + seeded component), team risk radar (6 axes) |
| Reports | PDF clinical report via FastAPI (/api/reports/generate-athlete-pdf), includes SOAP notes + risk score |
| Zone | % HRR | Training Description |
|---|---|---|
| Z1 | < 60% | Active recovery |
| Z2 | 60β70% | Aerobic base |
| Z3 | 70β80% | Aerobic endurance |
| Z4 | 80β90% | Lactate threshold |
| Z5 | > 90% | VOβmax / neuromuscular |
HRmax (Tanaka formula): 208 β 0.7 Γ age
HRR (Heart Rate Reserve): HRmax β RestingHR
| ACR Range | Status |
|---|---|
| < 0.8 | Under-training |
| 0.8 β 1.3 | Optimal β safe training zone |
| 1.3 β 1.5 | Caution β moderate spike risk |
| > 1.5 | High risk β overload injury zone |
Calculated from a rolling 7-day vs 28-day training load window.
| Sensor | Interval | MQTT Topic |
|---|---|---|
| Heart rate (bpm) | 1.0 s | medsport/{team}/{athlete}/hr |
| SpOβ (%) | 2.0 s | medsport/{team}/{athlete}/spo2 |
| GPS lat/lon/speed/alt | 1.0 s | medsport/{team}/{athlete}/gps_* |
| Accelerometer x/y/z | 0.1 s | medsport/{team}/{athlete}/accel_* |
| Cadence (spm) | 1.0 s | medsport/{team}/{athlete}/cadence |
The FastAPI service runs at http://localhost:8000. Interactive docs at http://localhost:8000/docs.
| Endpoint | Method | Description |
|---|---|---|
/api/health |
GET | Service health check |
/api/analysis/heart-zones |
POST | Zone distribution + HRV from HR series |
/api/analysis/fatigue-index |
POST | ACR + fatigue classification |
/api/analysis/radar-metrics |
POST | 6-axis performance polygon |
/api/analysis/cardiovascular-risk |
POST | Risk score + contributing factors |
/api/analysis/training-load |
POST | Team-wide load + overload flags |
/api/analysis/session-summary |
POST | avg/max HR, speed, zones per session |
/api/reports/generate-athlete-pdf |
POST | Clinical PDF (base64) with SOAP notes + risk |
/api/reports/generate-session-pdf |
POST | Session-specific performance PDF |
/api/reports/generate-team-epidemiology |
POST | Team injury/illness epidemiology report |
SQLite at database/medsport.db β created automatically on first launch from schema.sql + seed_data.sql.
| Table | Description |
|---|---|
users |
All accounts (id, email, password_hash, role, name) |
athlete_profiles |
Biometrics (sport, height, weight, hr_max, resting_hr, dob) |
medical_profiles |
Doctor/staff profile data |
teams |
Team config (name, sport, join code, alert thresholds) |
team_members |
Athleteβteam membership links |
training_sessions |
Sessions (start/end, type, active flag) |
session_participants |
Athlete participation per session |
sensor_readings |
Raw IoMT data (type, value, timestamp) |
alerts |
Physiological alerts (severity, acknowledged, parameter) |
soap_notes |
Clinical SOAP notes (S/O/A/P, private flag, doctor) |
medical_restrictions |
Training restrictions (type, HR limit, return date, status) |
medical_records |
Pathologies, allergies, medications, blood type |
personal_records |
Athlete performance personal bests |
chat_messages |
Team chat messages |
Seed data included: 29 users Β· 4 teams Β· 20 sessions Β· 87 session participants Β· 9 alerts Β· 8 SOAP notes Β· 6 active restrictions
All accounts use the password: Demo1234!
| Name | Team | |
|---|---|---|
| Carlos MΓ©ndez | coach@demo.com |
Equipo Γlite A |
| Ana GarcΓa | coach2@demo.com |
Equipo Resistencia B |
| Roberto Silva | coach3@demo.com |
Equipo Velocidad C |
| Miguel Torres | coach4@demo.com |
Equipo Fuerza D |
| Name | Team | |
|---|---|---|
| Dra. Laura Vidal | doctor@demo.com |
Equipo Γlite A |
| Dr. Pedro Ruiz | doctor2@demo.com |
Equipo Resistencia B |
| Dra. Marta LΓ³pez | doctor3@demo.com |
Equipo Velocidad C |
| Name | Team | |
|---|---|---|
| Marco Torres | athlete1@demo.com |
Equipo Γlite A |
| Elena Castro | athlete2@demo.com |
Equipo Γlite A |
| Diego Herrera | athlete3@demo.com |
Equipo Γlite A |
| SofΓa Mendoza | athlete4@demo.com |
Equipo Γlite A |
| Javier Romero | athlete5@demo.com |
Equipo Γlite A |
| LucΓa FernΓ‘ndez | athlete6@demo.com |
Equipo Γlite A |
| Carlos Ruiz | athlete7@demo.com |
Equipo Resistencia B |
| Ana MartΓn | athlete8@demo.com |
Equipo Resistencia B |
| Pablo GonzΓ‘lez | athlete9@demo.com |
Equipo Velocidad C |
| Isabel SΓ‘nchez | athlete10@demo.com |
Equipo Fuerza D |
(22 athletes total across 4 teams β see database/seed_data.sql for the complete list)
listener 1883
allow_anonymous trueMAVEN_OPTS=-Dprism.order=sw -Xmx512m
-Dprism.order=sw forces software rendering, which prevents black-screen issues on systems without a compatible GPU driver.
Edit ATHLETE_PROFILES to change simulated athletes, their base HR, VOβmax, and sport type. Each profile maps to a user in the database via athlete_id.
# Windows
$env:JAVA_HOME = "C:\Program Files\Java\jdk-21"
$env:MAVEN_OPTS = "-Dprism.order=sw -Xmx512m"
cd java-app
.\mvnw.cmd javafx:runcd MedSport
source venv/bin/activate # or venv\Scripts\activate on Windows
cd python-analytics
uvicorn main:app --reload --port 8000cd MedSport
source venv/bin/activate
cd python-simulator
python simulator.py- Add a constant to
SensorReading.SensorType - Add the mapping in
SensorReading.fromString() - Add a processing branch in
DashboardController.processReading() - Add the corresponding model in
python-simulator/physiological_models/
- Create the FXML layout in
src/main/resources/fxml/{role}/ - Create the controller in
controllers/{role}/ - Add a nav button to
MainLayout.fxml - Register the handler in
MainLayoutController.configureNavForRole()
- Karvonen, M.J. et al. (1957). The effects of training on heart rate. Annals of Medicine and Experimental Biology of Finland, 35(3), 307β315.
- Tanaka, H. et al. (2001). Age-predicted maximal heart rate revisited. Journal of the American College of Cardiology, 37(1), 153β156.
- Gabbett, T.J. (2016). The training-injury prevention paradox. British Journal of Sports Medicine, 50(5), 273β280.
- Task Force of the ESC / NASPE (1996). Heart rate variability: standards of measurement, physiological interpretation, and clinical use. Circulation, 93(5), 1043β1065.
- Eclipse Paho MQTT Client. https://eclipse.dev/paho/
- Eclipse Mosquitto MQTT Broker. https://mosquitto.org/
Alonso MartΓn DΓez Β· Biomedical Engineering Β· Universidad Europea de Madrid Β· 2026