Agent Brief: OpenClaw-Fitnessbericht-Konnektoren für Garmin, WHOOP, Speediance und weitere entwickeln
Ein implementierungsbereiter Agent-Brief zur Entwicklung von OpenClaw-Fitnessbericht-Konnektoren für Garmin, WHOOP, Speediance, Cronometer, 8Sleep, normalisierte JSON-Snapshots und öffentliche GitHub-Repositories.
Dieser Artikel ist dazu gedacht, einem KI-Codieragenten als Implementierungsbrief übergeben zu werden.
Das Ziel ist nicht, meine private Maschine zu duplizieren oder meine Dateien zurückzuentwickeln. Das Ziel ist, dass ein Agent diese Seite liest und funktionierende Konnektoren zu den Fitness-Systemen baut: Garmin, WHOOP, Speediance, Cronometer, 8Sleep und optional Open Wearables.
Die zentrale Anweisung ist einfach: Behandle jeden Anbieter als Konnektor, speichere normalisierte JSON-Snapshots und sorge dafür, dass der Report-Generator ausschließlich diese Snapshots verarbeitet. Diese Trennung verwandelt das anbieterspezifische API-Chaos in ein vom Agenten aufbaubares System.
Der Agent soll dieselbe Art von Verbindungen aufbauen, ohne sich auf meine exakten lokalen Pfade zu stützen:
- Garmin für Cardio, Trainingsbelastung, Pace, Herzfrequenzzonen und Aktivitätsdetails
- WHOOP für Erholung, HRV, RHF, Schlaf, Belastung und Readiness-Kontext
- Speediance für Krafttrainings-Historie, Volumen, Kalorien, Vorlagen und Übungsdetails
- Cronometer für den Ernährungskontext
- 8Sleep für verspätet eintreffenden Schlafkontext, sofern verfügbar
- OpenClaw als Orchestrierungsschicht, die Synchronisierungen ausführt, Daten normalisiert und Reports erzeugt
Es deckt außerdem die GitHub-Projekte, öffentlichen APIs, Datenverträge, Fehlermodi und Abnahmeprüfungen ab, die ein Implementierungsagent benötigt, um einen funktionierenden Stack zu liefern, ohne mein privates Repository zu sehen.
1. Agentenaufgabe
Baue einen Local-First-OpenClaw-Fitness-Reporting-Stack, der sich mit den Systemen verbinden kann, deren Daten normalisiert und Reports erzeugt, ohne während des Renderings Live-Aufrufe an die Anbieter zu tätigen.
Der Agent soll Folgendes liefern:
- Konnektor-Skripte
Einen Sync-Job pro System: Garmin, WHOOP, Speediance, Cronometer und 8Sleep, sofern konfiguriert. - Roh-Snapshots
Datierte Roh-JSON- oder CSV-abgeleitete Payloads zum Debuggen von Anbieteränderungen. - Normalisierte Verträge
Stabile JSON-Dateien, denen der Report-Generator vertrauen kann, selbst wenn sich die Anbieter-Payloads ändern. - Morgenreport
Einen Report, der Erholung, Schlaf, Readiness, Trainingsbelastung, Ernährung und den Tagesplan zusammenführt. - Snapshot für adaptives Training
Einen datierten Speediance/BJJ/Laufplan, der aus der heutigen Readiness und der jüngsten Belastung abgeleitet wird. - Abendreport
Einen Plan-vs.-Ist-Vergleich, der gegenüberstellt, was empfohlen wurde und was tatsächlich bei Garmin, WHOOP und Speediance stattgefunden hat. - Veröffentlichbare Ausgabe
Statisches HTML und maschinenlesbares JSON, das auf GitHub Pages oder einem anderen statischen Host bereitgestellt werden kann.
Baue dies nicht als „ein Skript, das sechs APIs aufruft und HTML live rendert". Das ist fehleranfällig.
2. Architektur, die der Agent umsetzen soll
Baue sie in vier Schichten:
- Konnektor-Schicht
Ein Sync-Job pro Plattform.
Normalisierte Datenschicht
Jede Synchronisierung schreibt stabile JSON-Snapshots.
3. Analyse-/Berichtsschicht
Der Berichtscode liest ausschließlich normalisierte JSON-Dateien.
4. Präsentationsschicht
HTML, Dashboards, tägliche Briefings, Telegram-Beiträge, Sprachzusammenfassungen.
Diese Trennung ist es, die das System wartbar macht.
KI-Implementierungsvertrag
Agent, erstelle diesen Vertrag, bevor du eine Dashboard-Benutzeroberfläche schreibst:
- Eingaben: ausschließlich Umgebungsvariablen und Anbieter-Zugangsdaten; niemals Geheimnisse in Quellcodedateien hartkodieren.
- Synchronisierungs-Ausgaben: ein Roh-JSON-Snapshot pro Anbieter-Abruf, plus eine normalisierte JSON-Datei pro Anbieter.
- Berichts-Eingaben: ausschließlich normalisierte JSON-Dateien. Der Berichts-Generator sollte Garmin, WHOOP, Speediance oder Cronometer nicht direkt aufrufen.
- Fehlermodus: Wenn ein Connector fehlschlägt, bewahre die letzte als fehlerfrei bekannte normalisierte Datei von gestern auf und markiere diese Quelle im Bericht als veraltet.
- Prüfbarkeit: Bewahre genügend Roh-Nutzlasten, um Änderungen der Anbieter-API zu debuggen, ohne Tokens, Cookies, Passwörter oder private Header zu protokollieren.
- Sende-Gate: E-Mail-, Sprach-, Telegram- und adaptive Trainings-Aktionen sollten tagesaktuelle bewertete Erholungsdaten erfordern. Ein Web-Bericht kann weiterhin im reduzierten Modus erstellt werden, aber das System sollte kein selbstsicheres Coaching aus veralteten Erholungsdaten senden.
- Plan-Snapshots: Adaptive Trainingspläne sollten als tägliche JSON-Snapshots geschrieben werden, bevor sie irgendwohin gesendet werden. Der nächtliche Bericht kann dann den Plan mit dem vergleichen, was tatsächlich passiert ist.
Mindestumgebungsvariablen für einen agentenfertigen Build:
GARMIN_EMAIL=
GARMIN_PASSWORD=
WHOOP_CLIENT_ID=
WHOOP_CLIENT_SECRET=
WHOOP_ACCESS_TOKEN=
WHOOP_REFRESH_TOKEN=
SPEEDIANCE_USER_ID=
SPEEDIANCE_TOKEN=
SPEEDIANCE_REGION=Global
CRONOMETER_EXPORT_PATH=
EIGHTSLEEP_EMAIL=
EIGHTSLEEP_PASSWORD=
3. Definition of Done
Ein Implementierungs-Agent ist erst dann fertig, wenn diese Artefakte existieren und neu generiert werden können:
data/garmin/summary/latest.jsondata/whoop/normalized/latest.jsondata/speediance/normalized/history.jsondata/speediance/normalized/by_exercise.jsondata/nutrition/latest.jsondata/eightsleep/normalized/latest.json, falls 8Sleep konfiguriert istdata/training_plans/YYYY-MM-DD_morning.jsonreports/morning/latest.htmlreports/nightly/latest.html- ein Sende-Gate, das E-Mail-, Sprach-, Telegram- und adaptive Trainings-Sendungen zurückhält, wenn tagesaktuelle bewertete WHOOP-Erholung fehlt
- Warnungen vor veralteten Quellen, wenn ein Connector fehlschlägt, aber die letzte als fehlerfrei bekannte normalisierte Datei von gestern verfügbar ist
- eine Keine-Geheimnisse-Prüfung, die beweist, dass Tokens, Cookies, Passwörter und private Header nicht committet wurden
Wenn der Agent während der Entwicklung keine Authentifizierung bei einem Anbieter durchführen kann, sollte er trotzdem die Connector-Schnittstelle, .env.example, Fake-Fixtures, Normalizer, Stale-Source-Handling und Report-Integration implementieren.
4. Öffentliche Projekte und Quellreferenzen
Dies sind die öffentlichen Bausteine, die ein Agent als Implementierungsreferenzen verwenden sollte.
Schnelle GitHub/API-Checkliste:
- Garmin-Connector:
https://github.com/cyberjunky/python-garminconnect - Garmin Legacy-Auth-Kontext:
https://github.com/matin/garth - WHOOP offizielle Entwickler-API:
https://developer.whoop.com/api - Speediance öffentliche Extraktion für diesen Build:
https://github.com/clawdassistant85-netizen/speediance-smartgym-workout-manager - Speediance Arbeits-Fork, aus dem dies extrahiert wurde:
https://github.com/ANPC86/SmartGymWorkoutManager - Speediance Upstream/Original-Referenz:
https://github.com/hbui3/UnofficialSpeedianceWorkoutManager - Report-Generator/Vorlagenreferenz:
https://github.com/tobyglenn/scriptsJinja - Cronometer-Exporte/Integrationen:
https://cronometer.com/
OpenClaw
- Plattform/Orchestrator: OpenClaw
- Rolle: Sync-Jobs planen, Transformationen ausführen, Berichte generieren, Ausgaben veröffentlichen
Garmin
- Primärer Python-Client: cyberjunky/python-garminconnect
GitHub:https://github.com/cyberjunky/python-garminconnect - Legacy-Auth-Bibliothek, die früher relevant war: matin/garth
GitHub:https://github.com/matin/garth - Status-Hinweis:
garthist veraltet;python-garminconnectverwendet jetzt neuere Garmin-Auth-Flows und ist das, worauf man aufbauen sollte.
WHOOP
- Offizielle Entwickler-API-Dokumentation:
https://developer.whoop.com/api - Öffentliche API-Oberfläche: OAuth2 + REST-Endpunkte für Erholung, Zyklen, Schlaf, Workouts, Profil, Körpermessungen
- Optionale Community-Wrapper existieren, aber ein vom Agent erstellter Connector sollte sich nach Möglichkeit an der offiziellen WHOOP-Entwickler-API orientieren.
Speediance
- Praktische öffentliche Speediance-Implementierungsreferenz: ANPC86/SmartGymWorkoutManager
GitHub:https://github.com/ANPC86/SmartGymWorkoutManager - Upstream-Projektabstammung / ursprüngliche öffentliche Referenz: hbui3/UnofficialSpeedianceWorkoutManager
GitHub:https://github.com/hbui3/UnofficialSpeedianceWorkoutManager - Verwende den ANPC86 SmartGymWorkoutManager-Fork als praktische Verbindungsreferenz, da er nützliche Arbeit rund um Verlauf, Exporte, API-Debugging, Zeitzonenbehandlung und Einheitenbehandlung enthält.
- Dies ist eine inoffizielle Speediance-Integration und sollte standardmäßig als instabil behandelt werden.
Ernährung
- Cronometer-Produktseite / Exporte / Integrationen:
https://cronometer.com/ - Behandle Cronometer als strukturierte Ernährungs-Exportquelle, nicht als magische direkte Berichtsabhängigkeit.
5. Produktionsaktualisierungen, die der Agent beibehalten sollte
Die aktuelle Version dieses Stacks weist einige wichtige Verhaltensweisen auf, die der Agent beibehalten sollte.
Einzelne Besitzer-Maschine
Die Fitness-Pipeline sollte eine autoritative, immer eingeschaltete Maschine haben. Lasse nicht zwei verschiedene Computer Berichte gegen dasselbe Ausgabe-Repository generieren und bereitstellen.
Die aktive Maschine besitzt Anbieter-Synchronisierungsjobs, die Berichterstellung, die adaptive Trainingsplan-Erstellung, das Deployment auf GitHub Pages sowie Watchdog-Prüfungen.
Andere Maschinen können die Berichte anzeigen oder lokale Dashboards hosten, sollten aber die Fitnessberichte nicht neu generieren.
Sequenzielle Pipeline statt gestaffelter Cron-Vermutungen
Die morgendlichen und nächtlichen Pipelines sollten als geordnete Phasen ablaufen:
- Anbieterdaten synchronisieren
- erforderliche Tagesdaten prüfen
- Berichte generieren
- bereitstellen
- Benachrichtigungen senden
- Sprachzusammenfassungen generieren, falls verwendet
- Watchdog-Validierung ausführen
Der alte Fehler besteht darin, diese Schritte mit festen Uhrzeit-Versätzen zu planen und zu hoffen, dass jede vorherige Phase abgeschlossen wurde. Das bessere Muster ist ein einziger Orchestrator, der jede Phase erst dann ausführt, nachdem die vorherige sauber beendet wurde.
Tagesaktuelle WHOOP-Erholungs-Gate
Für diesen Stack ist die tagesaktuelle WHOOP-Erholung eine harte Voraussetzung für das Coaching. Fehlt die heutige Erholung, kann das System weiterhin einen Web-Bericht mit Warnungen zu veralteten Quellen veröffentlichen, sollte jedoch E-Mail-, Sprach-, Telegram-Coaching sowie adaptive Trainingsempfehlungen zurückhalten.
Diese eine Regel verhindert den schlimmsten Fehlermodus: eine plausibel klingende Empfehlung, die auf der gestrigen Erholung basiert.
8Sleep-Behandlung verspäteter Daten
8Sleep kann nach dem ersten morgendlichen Lauf aktualisiert werden. Ein erneuter Lauf sollte heute und gestern vor der Neugenerierung zwangsweise aktualisieren, anstatt einer bestehenden lokalen JSON-Datei nur deshalb zu vertrauen, weil sie existiert.
Nur echte Garmin-Herzfrequenzzonen
Erfinde keine Herzfrequenz-Zonenverteilungen aus der durchschnittlichen Herzfrequenz. Enthalten die Garmin-Aktivitätsdetails Zeit-in-Zone-Daten, verwende diese. Ist dies nicht der Fall, blende dieses Diagramm aus oder kennzeichne es als nicht verfügbar.
Überprüfung der Planausführung
Der nächtliche Bericht funktioniert nun besser, wenn er den Tagesplan mit den tatsächlichen Tagesdaten vergleicht:
- geplantes BJJ-Training vs. WHOOP-BJJ-Training
- geplante Speediance-Einheit vs. abgeschlossene Speediance-Einheiten
- geplanter Lauf vs. Garmin-Laufdistanz
- geplante Schritte vs. Garmin-Schritte
Das verwandelt den nächtlichen Bericht in eine Feedback-Schleife statt nur in eine Zusammenfassung.
Open-Wearables-Schattenmodus
Open Wearables ist als zukünftige Abstraktionsebene nützlich, aber ich würde ein funktionierendes persönliches Berichtssystem nicht auf einen Schlag umstellen. Die sicherere Migration ist der Schattenmodus:
- die bestehende dateibasierte Pipeline als maßgeblich behalten
- Garmin-/WHOOP-Daten in Open Wearables importieren oder spiegeln
- Open-Wearables-Daten zurück in Schatten-JSON-Dateien exportieren
- Schatten-Dateien gegen Produktionsdateien vergleichen
- erst übernehmen, wenn Anzahlen, Daten und Tagesdatensätze übereinstimmen
Die Schatten-Dateien sollten während des Pilotbetriebs niemals Produktionseingaben überschreiben.
6. Garmin: die Kardio- und Aktivitätsdetailschicht
Wenn WHOOP die Frage „wie erholt bin ich?" beantwortet, beantwortet Garmin die Frage „was genau habe ich getan?"
Garmin ist der Bereich, in dem der Bericht Folgendes enthält:
- Distanz
- Tempo und Geschwindigkeit
- Dauer
- durchschnittlicher und maximaler HF
- Herzfrequenzzonen
- Kadenz
- Leistung
- Trainingseffekt
- Aktivitätsmetadaten
- umfassendere Cardio-/Trainingsdetails, die WHOOP nicht so detailliert hervorhebt
Empfohlenes öffentliches Repository
Empfohlen: cyberjunky/python-garminconnect
GitHub:
https://github.com/cyberjunky/python-garminconnect
Warum dies wichtig ist:
- es wird aktiv als der zu verwendende Garmin-Connect-Python-Wrapper positioniert
- es stellt eine sehr große Garmin-Endpoint-Oberfläche bereit
- es enthält Beispiele und Token-Handling-Muster
- es hat ältere Authentifizierungsannahmen ersetzt, die bei früheren Garmin-Änderungen fehlschlugen
Wichtiger Hinweis zur Garmin-Kompatibilität
In der Vergangenheit verwendeten viele Builds garth.
GitHub:
https://github.com/matin/garth
Aber garth ist nun explizit veraltet. Das ist wichtig, weil ein Agent eine neue Implementierung nicht auf eine veraltete Authentifizierung stützen sollte.
Minimales ausführbares Garmin-Beispiel
from garminconnect import Garmin
from datetime import date
from pathlib import Path
import json
import os
email = os.environ["GARMIN_EMAIL"]
password = os.environ["GARMIN_PASSWORD"]
client = Garmin(email=email, password=password)
client.login()
today = date.today().isoformat()
stats = client.get_stats(today)
activities = client.get_activities_by_date(today, today)
payload = {
"date": today,
"stats": stats,
"activities": activities,
}
out = Path("data/garmin/raw")
out.mkdir(parents=True, exist_ok=True)
(out / f"{today}.json").write_text(json.dumps(payload, indent=2))
Was aus Garmin normalisiert werden sollte
Schütten Sie rohe Garmin-Payloards nicht direkt in Ihre endgültige Berichtslogik. Normalisieren Sie sie zunächst in Felder wie:
calendarDatetotalStepsrestingHeartRatesleepingSecondsbodyBatteryactivityNameactivityTypedurationSecondsdistanceMetersdistanceMilesaverageHRmaxHRcaloriestrainingEffectcadencepower
Empfohlenes Speichermuster
data/garmin/raw/YYYY-MM-DD.jsondata/garmin/normalized/YYYY-MM-DD.jsondata/garmin/summary/latest.json
Damit erhalten Sie sowohl Wiederholbarkeit als auch schnellen Berichtszugriff.
7. WHOOP: die Erholungs- und Bereitschaftsschicht
WHOOP macht die Berichte als Entscheidungs-Engine nützlich, statt sie nur als einfaches Aktivitätsprotokoll zu führen.
Es liefert:
- Recovery-Score
- HRV
- Ruhepuls
- Schlafleistung
- Belastung
- Zykluskontext
- Bereitschafts-Einordnung für morgendliche und nächtliche Empfehlungen
Zu verwendende öffentliche API
Verwenden Sie die offizielle WHOOP-Entwickler-API:
- Dokumentation:
https://developer.whoop.com/api
Relevante Endpunktgruppen:
/developer/v2/cycle/developer/v2/recovery/developer/v2/activity/sleep/developer/v2/activity/workout/developer/v2/user/profile/basic/developer/v2/user/measurement/body
Kritische Einschränkung
Eine der wichtigsten Erkenntnisse bei der Implementierung: Journaldaten sind nicht über die WHOOP-API verfügbar.
Wenn Sie Journalantworten oder Gewohnheitsannotationen möchten, können Sie sich dafür nicht auf einen öffentlichen WHOOP-API-Endpunkt verlassen. Die praktischen Optionen sind:
- manueller CSV-Export aus WHOOP
- eine eigene parallele Journal-Schicht
- separate Metadaten, die Sie nach der Synchronisierung anhängen
Diese Einschränkung sollte im Artikel klar erwähnt werden, da sie jeden ernsthaften Build betrifft.
Minimales ausführbares WHOOP-Beispiel
from pathlib import Path
import json
import os
import requests
BASE = "https://api.prod.whoop.com/developer/v2"
TOKEN = os.environ["WHOOP_ACCESS_TOKEN"]
headers = {"Authorization": f"Bearer {TOKEN}"}
def get(path):
response = requests.get(f"{BASE}{path}", headers=headers, timeout=30)
response.raise_for_status()
return response.json()
payload = {
"recovery": get("/recovery"),
"sleep": get("/activity/sleep"),
"workouts": get("/activity/workout"),
}
out = Path("data/whoop/raw")
out.mkdir(parents=True, exist_ok=True)
(out / "latest.json").write_text(json.dumps(payload, indent=2))
Was von WHOOP normalisiert werden soll
Normalisieren Sie in Felder wie:
recovery_scorehrv_rmssd_milliresting_heart_ratespo2_percentageskin_temp_celsiussleep_performance_percentagerespiratory_ratestraincycle_startcycle_endworkout_sport_name
Empfohlenes Speichermuster
data/whoop/raw/recovery.jsondata/whoop/raw/sleep.jsondata/whoop/raw/workouts.jsondata/whoop/normalized/latest.json
8. Speediance: die Krafttrainings-Schicht
Speediance ist der ungewöhnlichste Connector im gesamten Stack.
Anders als Garmin und WHOOP handelt es sich hier nicht um eine saubere offizielle öffentliche Entwicklerplattform. Der Agent sollte diese öffentlichen Repos als Verbindungsreferenzen verwenden:
Öffentliche Extraktion/Referenz: https://github.com/clawdassistant85-netizen/speediance-smartgym-workout-manager
ANPC86/SmartGymWorkoutManager
GitHub: https://github.com/ANPC86/SmartGymWorkoutManager
Dieses Repo ist selbst ein persönlicher Fork bzw. eine Fortsetzung des ursprünglichen öffentlichen Speediance-Projekts:
hbui3/UnofficialSpeedianceWorkoutManager
GitHub: https://github.com/hbui3/UnofficialSpeedianceWorkoutManager
Diese Repos sind der wichtige Ausgangspunkt, da sie zeigen, wie man:
- sich bei Speediance-Endpunkten authentifiziert
- Workout-Daten und API-Antworten inspiziert
- den Trainingsverlauf durchsucht/exportiert
- Vorlagen/Workouts auf desktopfreundliche Weise verwaltet
- praktische Probleme wie die Zeitzonenanzeige und die Handhabung von imperialem/metrischem Gewicht behandelt
Warum diese Repos wichtig sind
Verwenden Sie den ANPC86 SmartGymWorkoutManager-Fork als praktische Grundlage für das Speediance-Integrationsmuster, während Sie die hbui3-Upstream-Referenz für die Herkunft beibehalten. Zusammen sind sie die deutlichsten öffentlichen Referenzen für die Arbeit mit Speediance-Daten außerhalb der offiziellen App.
Stabilitätswarnung
Das ursprüngliche Projekt weist darauf hin, dass Speediance Sicherheits-Upgrades implementiert hat. Das bedeutet:
- diese Integration kann fehlschlagen
- Header- und Authentifizierungsverhalten können sich ändern
- Endpunkte können verschoben werden
- Sie sollten diesen Konnektor hinter einem Normalisierungsschritt isolieren, damit Ihre Berichte anbieterseitige Änderungen überstehen
Minimales ausführbares Muster für Speediance
Wenn Sie ANPC86/SmartGymWorkoutManager als Ausgangspunkt verwenden und gleichzeitig die hbui3/UnofficialSpeedianceWorkoutManager-Upstream-Referenz für den ursprünglichen Kontext prüfen, ist der saubere Ansatz:
- Führen Sie dessen App- oder Client-Schicht lokal aus
- Authentifizieren Sie sich mit Ihrem Speediance-Konto
- Rufen Sie die Trainingshistorie über die bereitgestellten API-Methoden ab
- Exportieren Sie normalisiertes JSON in Ihr eigenes Datenverzeichnis
Pseudo-Beispiel mit diesem Client-Muster:
# Dies rund um die api_client.py in folgendem Pfad aufbauen:
# https://github.com/clawdassistant85-netizen/speediance-smartgym-workout-manager
from api_client import SpeedianceClient
from datetime import date
from pathlib import Path
import json
import os
client = SpeedianceClient()
success, msg, debug = client.login(
os.environ["SPEEDIANCE_USER_ID"],
os.environ["SPEEDIANCE_TOKEN"],
)
if not success:
raise RuntimeError(msg)
start_date = os.environ.get("SPEEDIANCE_START_DATE", "2026-01-01")
end_date = date.today().isoformat()
records = client.get_training_data(start_date, end_date)
out = Path("data/speediance/raw")
out.mkdir(parents=True, exist_ok=True)
(out / "history.json").write_text(json.dumps(records, indent=2))
Was aus Speediance normalisiert werden sollte
Normalisieren Sie in Felder wie:
training_iddatetitleduration_secondscaloriestotal_volumeexercise_counttemplate_nameplanned_durationactual_durationexercise_breakdownestimated_1rm
Bewährtes Datenmodell
Für ein ernsthaftes Berichtssystem führen Sie zwei Indizes:
- bySession
- ein Datensatz pro abgeschlossenem Training
- byExercise
- ein Datensatz-Stream pro Übungsname
- enthält Gewicht, Wiederholungen, Seite, Sitzungs-ID, Zeitstempel
Diese Struktur macht Fortschrittsdiagramme und PR-Erkennung später trivial.
Empfohlenes Speichermuster
data/speediance/raw/monthly/YYYY-MM.jsondata/speediance/normalized/history.jsondata/speediance/normalized/by_exercise.jsondata/speediance/dashboard/latest.json
Adaptive Speediance-Trainings-Snapshots
Die fortgeschrittenere Version dieses Builds liest nicht nur abgeschlossene Speediance-Trainings.
Es erstellt auch geplante Workouts aus aktuellen Bereitschaftsdaten.
Das nützliche Muster ist:
- Lade tagesaktuelle WHOOP-Erholung, aktuelle Belastung, BJJ-Belastung, Garmin Body Battery, Ruhepuls, aktuelle Laufbelastung, Wetter und den aktuellen Speediance-Planungsverlauf.
- Klassifiziere den Tag in eine Kategorie wie
build,maintain,recover,protectoderpost_bjj_brutal. - Wähle ein Speediance-Gerät für das gesamte Workout, normalerweise Griffe, Langhantel oder Seil.
- Wähle nur geräteinterne Übungen für das Kern-Speediance-Workout aus.
- Füge null bis zwei Speediance-fremde Ergänzungen nur dann hinzu, wenn die Erholung es zulässt.
- Schreibe den Plan nach
data/training_plans/YYYY-MM-DD_context.json. - Verwende den Snapshot sowohl für die morgendliche Empfehlung als auch für die nächtliche Überprüfung der Planausführung.
Zur Wiederholungskontrolle wird die neue Workout-Signatur mit aktuellen Plan-Snapshots verglichen. Die Produktionsversion verwendet ein rollierendes Eindeutigkeitsfenster, das auf bis zu 30 Tage anwächst, und stempelt den Workout-Titel immer mit dem heutigen Datum, sodass ein wieder auftauchendes Workout dennoch frisch und auffindbar bleibt.
9. Cronometer: die Ernährungs-Kontextschicht
Unabhängig davon, welche genaue Ernährungs-App du verwendest, ist die Rolle dieselbe: dem Bericht Kontext für die Energiezufuhr liefern.
Das ist wichtig, weil Trainingsbelastung ohne Ernährungskontext zu falschen Schlussfolgerungen führt.
Der Bericht sollte in der Lage sein zu fragen:
- War die Erholung niedrig, weil die Trainingsbelastung hoch war?
- Oder weil der Schlaf schlecht war und die Kalorienzufuhr niedrig?
- War der Sportler im Verhältnis zur Leistung unterversorgt?
Praktische Umsetzungsempfehlungen
Verlasse dich nicht auf eine Live-Ernährungs-API zur Renderzeit. Verwende eines der folgenden Verfahren:
- CSV-Export
- Webhook-Erfassung
- Geplante Synchronisierung in normalisiertes JSON
Normalisiere in Felder wie:
calories_consumedprotein_gcarbs_gfat_gfiber_gtarget_caloriesestimated_deficit
Empfohlenes Speichermuster
data/nutrition/raw/YYYY-MM-DD.csvdata/nutrition/normalized/YYYY-MM-DD.jsondata/nutrition/latest.json
10. 8Sleep: die spät eintreffende Schlaf-Kontextschicht
8Sleep ist optional, aber wenn es konfiguriert ist, sollte der Agent es wie jeden anderen Konnektor behandeln: zuerst synchronisieren, zweitens normalisieren, zuletzt aus Dateien rendern.
Das wichtige Verhalten ist der Umgang mit verspäteten Daten. Schlafdaten können sich nach dem ersten Morgenlauf noch ändern, daher sollten ein manueller Neustart oder ein geplanter Wiederholungsversuch sowohl heute als auch gestern zwangsaktualisieren, bevor der Bericht neu erstellt wird.
Normalisiere Felder wie:
sleep_scoresleep_startsleep_endtime_in_bed_secondstime_asleep_secondshrvresting_heart_ratetemperature_adjustmentsaway_mode
Empfohlenes Speichermuster:
data/eightsleep/raw/YYYY-MM-DD.jsondata/eightsleep/normalized/YYYY-MM-DD.jsondata/eightsleep/normalized/latest.json
11.
Was OpenClaw in diesem Stack tatsächlich tut
OpenClaw ist nicht die Datenquelle. Es ist die Orchestrierungs- und Reasoning-Schicht.
Seine Aufgabe ist es:
- Sync-Jobs planmäßig auszuführen
- stabile Ausgaben zu speichern
- Quellen zu vergleichen
- Berichts-HTML zu erzeugen
- Links zu veröffentlichen
- nutzerfreundliche Zusammenfassungen aus den normalisierten Daten zu erstellen
Das bedeutet, der Berichtscode sollte aus Dateien wie diesen lesen:
data/garmin/summary/latest.jsondata/whoop/normalized/latest.jsondata/speediance/normalized/history.jsondata/nutrition/latest.jsondata/eightsleep/normalized/latest.json
Der Reportgenerator sollte niemals wissen müssen, wie die Garmin-Authentifizierung funktioniert oder wie sich die Speediance-Header diese Woche geändert haben.
12. Vom Agenten erstellbare Verzeichnisstruktur
Hier ist eine Struktur, die ein Agent anlegen kann, bevor eine echte Anbieter-Authentifizierung funktioniert:
project/
data/
garmin/
raw/
normalized/
summary/
whoop/
raw/
normalized/
speediance/
raw/
normalized/
dashboard/
nutrition/
raw/
normalized/
eightsleep/
raw/
normalized/
training_plans/
scripts/
sync_garmin.py
sync_whoop.py
sync_speediance.py
sync_nutrition.py
sync_eightsleep.py
gate_same_day_recovery.py
build_adaptive_plan.py
build_report.py
reports/
morning/
latest.html
nightly/
latest.html
frontend/
data/
Die Dateistruktur ist Teil der Schnittstelle. Halte sie einfach genug, damit ein zukünftiger Agent das System untersuchen, jeden Connector finden, einen einzelnen Sync erneut ausführen und rohe Payloads mit normalisierten Ausgaben vergleichen kann.
13. Beispiel-Muster für den Report-Builder
Sobald jeder Connector normalisiertes JSON schreibt, wird der eigentliche Berichtscode einfach.
import json
from pathlib import Path
base = Path("data")
garmin = json.loads((base / "garmin/summary/latest.json").read_text())
whoop = json.loads((base / "whoop/normalized/latest.json").read_text())
speediance = json.loads((base / "speediance/normalized/history.json").read_text())
nutrition = json.loads((base / "nutrition/latest.json").read_text())
eightsleep_path = base / "eightsleep/normalized/latest.json"
eightsleep = json.loads(eightsleep_path.read_text()) if eightsleep_path.exists() else {}
summary = {
"recovery": whoop.get("recovery_score"),
"hrv": whoop.get("hrv_rmssd_milli"),
"rhr": whoop.get("resting_heart_rate"),
"steps": garmin.get("totalSteps"),
"body_battery": garmin.get("bodyBattery"),
"lifting_volume": speediance.get("today", {}).get("total_volume"),
"calories_in": nutrition.get("calories_consumed"),
"sleep_score": eightsleep.get("sleep_score"),
}
python
html = f"""
<html>
<body>
<h1>Täglicher Fitnessbericht</h1>
<ul>
<li>Erholung: {summary['recovery']}</li>
<li>HRV: {summary['hrv']}</li>
<li>RHR: {summary['rhr']}</li>
<li>Schritte: {summary['steps']}</li>
<li>Body Battery: {summary['body_battery']}</li>
<li>Kraftvolumen: {summary['lifting_volume']}</li>
<li>Kalorienzufuhr: {summary['calories_in']}</li>
<li>8Sleep-Wert: {summary['sleep_score']}</li>
</ul>
</body>
</html>
"""
out = Path("reports/morning")
out.mkdir(parents=True, exist_ok=True)
(out / "latest.html").write_text(html)
Hier zahlt sich das gesamte Design aus: Sobald die Synchronisierungsschicht sauber funktioniert, wird die Berichtsschicht auf die bestmögliche Weise langweilig.
14. Wofür jeder Connector tatsächlich gedacht ist
Das ist das einfachste mentale Modell:
WHOOP
Verwenden für:
- Erholung
- HRV
- RHR
- Schlafleistung
- Belastung
- Bereitschafts-Kontext
Garmin
Verwenden für:
- Lauf- und Cardio-Details
- Tempo, Leistung, Trittfrequenz
- HF-Zonen
- Trainingseffekt
- detaillierte Aktivitätshistorie
Speediance
Verwenden für:
- Krafttrainingshistorie
- Gesamtvolumen
- Übungsdetails
- geplante vs. tatsächliche Sitzungsausführung
- Fortschritt auf Bewegungsebene, falls man eine Indexierung pro Übung aufbaut
Ernährungs-App
Verwenden für:
- Kalorienaufnahme
- Makro-Kontext
- Erkennung von Unterversorgung
8Sleep
Verwenden für:
- verspätet eintreffende Schlafdetails
- bettbezogene Schlafdauer und Bewertung
- Querprüfungen des Schlafkontexts gegen WHOOP und Garmin
OpenClaw kombiniert sie anschließend zu einer einzigen Berichts- und Empfehlungs-Oberfläche.
15. Verbindungs-Lieferobjekte nach System
Dies ist die Checkliste, die der Implementierungsagent erfüllen sollte, bevor die Berichtsoberfläche verfeinert wird.
Garmin Verbindungspunkte
- Bibliothek:
garminconnectvoncyberjunky/python-garminconnect - Auth: Garmin Connect E-Mail/Passwort mit der Token-/Sitzungs-Verwaltung der Bibliothek
- Abruf-Kadenz: tägliche Morgensynchronisierung plus optionale Synchronisierung nach dem Training
- Mindestabrufe:
- tägliche Statistiken für Schritte, Ruheherzfrequenz, Schlafsekunden, Body Battery, Kalorien
- Aktivitäten nach Datum für Läufe/Fahrten/Cardio-Sitzungen
- Aktivitätsdetails, falls verfügbar, für HF-Zonen, Tempo, Trittfrequenz, Leistung, Trainingseffekt
- Normalisierte Ausgabe:
data/garmin/summary/latest.json
WHOOP Anbindungspunkte
- API-Dokumentation:
https://developer.whoop.com/api - Authentifizierung: OAuth2-Zugriffstoken + Refresh-Token-Flow
- Basis-URL:
https://api.prod.whoop.com/developer/v2 - Mindest-Endpunktgruppen:
/cyclefür Strain-/Zyklus-Kontext/recoveryfür Recovery-Score, HRV und Ruhepuls/activity/sleepfür Schlaf-Performance und Schlafzeiten/activity/workoutfür Workouts und WHOOP Strain-Daten/user/profile/basicund/user/measurement/bodyfür Profil-/Körper-Kontext bei Bedarf
- Normalisierte Ausgabe:
data/whoop/normalized/latest.json
Speediance Anbindungspunkte
- Öffentliche Extraktion für diesen Build:
https://github.com/clawdassistant85-netizen/speediance-smartgym-workout-manager - Upstream-Referenz:
https://github.com/hbui3/UnofficialSpeedianceWorkoutManager - Authentifizierung: inoffizieller token-/benutzer-id-basierter Flow, der von der SmartGym-Client-Schicht bereitgestellt wird
- Mindest-Abrufe:
- Trainingsverlauf
- Übungs-/Sitzungsdetails
- benutzerdefinierte Workout-/Vorlagen-Metadaten, wenn du „geplant vs. tatsächlich"-Berichte möchtest
- Roh-API/Debug-Antworterfassung ohne Geheimnisse
- Normalisierte Ausgaben:
data/speediance/normalized/history.jsondata/speediance/normalized/by_exercise.json
Cronometer-Anbindungspunkte
- Öffentliche Quelle:
https://cronometer.com/Exporte/Integrationen - Empfohlener Implementierungsansatz: CSV-Export oder geplanter Datei-Drop, keine Live-API-Abhängigkeit zur Renderzeit
- Mindestfelder: Datum, Kalorien, Protein, Kohlenhydrate, Fett, Ballaststoffe und alle Mikronährstoffe, die du in der Erholungsanalyse haben möchtest
- Normalisierte Ausgabe:
data/nutrition/latest.json
8Sleep Anbindungspunkte
- Authentifizierung: umgebungsgestützter Login-/Session-Flow, ohne Zugangsdaten im Quellcode
- Abruf-Kadenz: Morgen-Sync plus Neuaufnahme-/Aktualisierungs-Unterstützung für heute und gestern
- Mindest-Abrufe:
- Schlaf-Score
- Schlafzeiten
- Schlafzeit und Bettzeit
- HRV und Ruhepuls, sofern verfügbar
- Temperatur- und Abwesenheitsmodus-Kontext, sofern verfügbar
- Normalisierte Ausgabe:
data/eightsleep/normalized/latest.json
Bericht-Generierungs-Anbindungspunkt
Der Berichts-Generator sollte nur stabile normalisierte Dateien und Plan-Snapshots lesen. Eine praktische Form ist:
data/garmin/summary/latest.json
data/whoop/normalized/latest.json
data/speediance/normalized/history.json
data/speediance/normalized/by_exercise.json
data/nutrition/latest.json
data/eightsleep/normalized/latest.json
data/training_plans/YYYY-MM-DD_morning.json
data/training_plans/YYYY-MM-DD_post_bjj.json
Das ist die tatsächliche Verbindungsfläche. Alles vorgelagerte kann unabhängig davon kaputtgehen und repariert werden.
16. Die eigentlichen Implementierungsregeln
Wenn ein Agent das erfolgreich bauen soll, sind diese Regeln wichtiger als jedes einzelne Code-Snippet:
Normalisiere jeden Anbieter in dein eigenes Schema
Erlaube niemals, dass ein Bericht von der Anbieter-Payload-Form abhängt.Behalte Roh-Snapshots
Wenn ein Sync bricht, retten dich Roh-Payloads.
Niemals aus Live-APIs rendern, wenn der Bericht zeitkritisch ist
Erst synchronisieren, dann rendern.
Inoffizielle Integrationen als austauschbare Adapter behandeln
Insbesondere Speediance.Garmin und WHOOP ergänzen sich, statt zu konkurrieren
WHOOP = Bereitschaft. Garmin = Ausführungsdetails.Kraftdaten sowohl auf Sitzungs- als auch auf Übungsebene modellieren
Andernfalls bleibt die Fortschrittsberichterstattung oberflächlich.Coaching an der heutigen Bereitschaft ausrichten, nicht an der von gestern
Fehlende Same-Day-Erholung sollte das System auf reine Web-Berichterstattung herunterstufen.Den Plan speichern, bevor der Tag bewertet wird
Ein nächtlicher Adhärenz-Score funktioniert nur, wenn der morgendliche oder post-BJJ-Plan als Daten gespeichert wurde.Neue Backends im Schattenmodus pilotieren
Open Wearables oder jede andere Abstraktionsebene muss beweisen, dass sie aktuelle Produktionsdateien abgleichen kann, bevor sie zur Quelle der Wahrheit wird.
Abschließende Implementierungs-Referenzliste
Dies sind die öffentlichen Referenzen, die einem KI-Coding-Agenten zuerst übergeben werden sollten, wenn dieses System implementiert wird:
- OpenClaw als Orchestrierungsschicht
- Garmin Connector:
https://github.com/cyberjunky/python-garminconnect - Garmin historischer Auth-Kontext:
https://github.com/matin/garth(veraltet; als Kontext verwenden, nicht als Zentrum eines neuen Builds) - WHOOP offizielle Entwickler-API:
https://developer.whoop.com/api - Speediance öffentliche Extraktion für diesen Build:
https://github.com/clawdassistant85-netizen/speediance-smartgym-workout-manager - Speediance vorgelagerte/originale Referenz:
https://github.com/hbui3/UnofficialSpeedianceWorkoutManager - Referenz für Berichtsgenerator/Vorlage:
https://github.com/tobyglenn/scriptsJinja - Cronometer-Ernährungsexporte:
https://cronometer.com/ - 8Sleep Connector-Vertrag: umgebungsgestützte Synchronisierung, die
data/eightsleep/normalized/latest.jsonschreibt
Wenn Sie diesen Artikel an Claude Code, Codex, OpenClaw oder einen anderen Implementierungs-Agenten weitergeben, lautet die korrekte Anweisung: zuerst die Connectors bauen, zweitens normalisierte JSON-Snapshots schreiben, drittens das Same-Day-Erholungs-Gate durchsetzen, dann zuletzt den Bericht-Renderer bauen. Beginnen Sie nicht mit dem Design des finalen HTML-Berichts.