Aktionen
Feature #77
geschlossen
JH
Trainingsdetailseite: Belastung und Schwerpunkt aus der Pulszonenverteilung
Feature #77:
Trainingsdetailseite: Belastung und Schwerpunkt aus der Pulszonenverteilung
Beginn:
Abgabedatum:
% erledigt:
0%
Geschätzter Aufwand:
Gefunden in Version:
Beschreibung
Ziel: Auf der Trainingsdetailseite aus der Verteilung der Pulszonen zwei einfache Angaben ableiten - Belastung (wie anstrengend war das Training) und Schwerpunkt (wofür war es hauptsächlich gut). Bewusst nicht "Nutzen des Trainings": Die Zonenverteilung beschreibt die Dosis, nicht die Wirkung, denn die hängt von Ziel, Trainingszustand und Erholung ab.
Ausgangslage¶
TrainingDetailViewModel.BuildZonePieberechnet die Zeit je Pulszone (zoneSeconds[5], zeitgewichtet über die Zeitabstände der Trainingspunkte) bereits, nutzt sie aber nur für das Kreisdiagramm.- Zonenmodell (
User.PulseZoneIndex): 5 gleich breite Zonen mit 50/60/70/80/90/100 % von HFmax (Erholung, Leicht, Mittel, Hart, Maximum). HFmax historisiert überTraining.MaxPulseAtRecording, Fallback auf den aktuellen Benutzer. PulseZoneIndexklemmt Werte unter 50 % auf Zone 1 - für die Belastung muss Puls unter 50 % HFmax separat behandelt werden (Gewicht 0).- Im Benutzermodell gibt es keine FTP/Schwellenleistung (
StartingPowerist nur der Startwert der pulsgesteuerten Regelung). Ein leistungsbasierter Wert ist daher nicht Teil dieses Tickets. FitnessNoteist bereits durch die Erholungspuls-Note belegt und wird nicht wiederverwendet.
Belastung (Edwards-TRIMP)¶
Belastung = Summe über alle Zonen von (Minuten in der Zone x Zonennummer). Erholung = 1, Leicht = 2, Mittel = 3, Hart = 4, Maximum = 5 Punkte pro Minute. Puls unter 50 % HFmax zählt 0.
- Ergebnis ist eine Zahl ohne Einheit, nur zum Vergleichen (240 ist etwa doppelt so belastend wie 120).
- Beispiel: 10 min Erholung + 30 min Leicht + 15 min Mittel + 5 min Hart = 10 + 60 + 45 + 20 = 135 Punkte.
- Lange lockere Trainings bekommen dadurch automatisch viele Punkte (2 h Leicht = 240 = 1 h Hart). Das ist gewollt.
- Optional später: Einordnung relativ zur eigenen Historie ("leichter / üblich / härter als die letzten 10 Trainings"), statt absoluter Schwellen.
Schwerpunkt (regelbasiertes Label)¶
Wird ausschließlich aus der prozentualen Zeitverteilung berechnet, unabhängig von der Belastung. Regeln der Reihe nach geprüft:
| Bedingung (Zeitanteil) | Label |
|---|---|
| Dauer unter 10 min | kein Label |
| Zone 1 >= 60 % | Erholung |
| Zone 5 >= 10 % oder (Zone 4 + Zone 5) >= 30 % mit deutlichem Wechsel zwischen hoch und niedrig | Intervall / hochintensiv |
| Zone 4 >= 40 % | Schwelle / Tempo |
| Zone 2 + Zone 3 >= 70 % | Grundlagenausdauer |
| sonst | gemischt |
- Schwellenwerte als benannte Konstanten, damit sie sich leicht nachjustieren lassen. Es sind Heuristiken.
- Grenze: Der Puls hinkt bei kurzen Intervallen hinterher, "Intervall" wird dort eher zu selten erkannt.
- Die Zonen laufen nach % von HFmax; Zone 3 entspricht damit etwa dem klassischen GA1, Zone 4 dem Schwellenbereich. Die 3-Zonen-Aufteilung nach Seiler passt nicht 1:1.
Umsetzung¶
- Rechenklasse in ErControl.Core (z. B.
TrainingLoadCalculator): liefert Sekunden je Zone, Belastung und Schwerpunkt.BuildZonePienutzt sie ebenfalls (Logik nur an einer Stelle), gut testbar. - Trainingsdetailseite: Kachel "Belastung" und Zeile "Schwerpunkt" beim Kreisdiagramm. Texte in die Resx unter
TrainingSessionsViewModel.*. Wird beim Öffnen berechnet, keine Migration nötig.
Umgesetzt¶
- Rechenklasse
TrainingLoadCalculator(ErControl.Core/Services): liefert Sekunden je Pulszone, Belastung (Edwards-TRIMP) und Schwerpunkt. Die Schwellenwerte der Schwerpunkt-Regeln stehen als Konstanten dort. Der "deutliche Wechsel zwischen hoch und niedrig" ist als Zone 4+5 >= 30 % und Zone 1+2 >= 20 % umgesetzt. Mit Unit-Tests (TrainingLoadCalculatorTests) - Trainingsdetailseite: Belastung und Schwerpunkt stehen unterhalb der Legende in der Pulszonen-Karte (keine Kachel). Die Zeile Schwerpunkt entfällt, wenn das Training keinen bekommt (unter 10 min). Texte in der Resx (Deutsch/Englisch) unter
TrainingSessionsViewModel.*; berechnet beim Öffnen der Seite, keine Migration - Kreisdiagramm nutzt dieselbe Auswertung. Änderung: Trainingspunkte ohne Pulsmessung (Puls 0) zählen nicht mehr als Zone Erholung - ein Training ohne Brustgurt zeigt kein Pulszonen-Diagramm mehr statt 100 % Erholung
Später (nicht Teil dieses Tickets)¶
- Spalten "Belastung" und "Schwerpunkt" in der Trainingsübersicht (Standard ausgeblendet). Dafür Wert speichern (neue Spalte, Migration, einmaliger Backfill wie bei
MaxPulseAtRecording), sonst müsste das Grid für jedes Training alleTrainingPointsladen. - Wochensumme der Belastung.
- Leistungsbasierte Belastung (TSS-artig), sobald ein FTP-Feld im Benutzer existiert.
- Banister-TRIMP mit Ruhepuls (
RestingPulseAtRecordingist bereits historisiert) als Alternative zu Edwards.
Offene Entscheidungen¶
- Grid-Spalten: umgesetzt wird das in #78.
- Schwellenwerte und Bezeichnungen der Labels bestätigen.
Aktionen