Zurück zu den Analysen
Feldberichte19 Min. Lesezeit

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.

Toby 3. Mai 2026

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:

  1. Konnektor-Skripte
    Einen Sync-Job pro System: Garmin, WHOOP, Speediance, Cronometer und 8Sleep, sofern konfiguriert.
  2. Roh-Snapshots
    Datierte Roh-JSON- oder CSV-abgeleitete Payloads zum Debuggen von Anbieteränderungen.
  3. Normalisierte Verträge
    Stabile JSON-Dateien, denen der Report-Generator vertrauen kann, selbst wenn sich die Anbieter-Payloads ändern.
  4. Morgenreport
    Einen Report, der Erholung, Schlaf, Readiness, Trainingsbelastung, Ernährung und den Tagesplan zusammenführt.
  5. Snapshot für adaptives Training
    Einen datierten Speediance/BJJ/Laufplan, der aus der heutigen Readiness und der jüngsten Belastung abgeleitet wird.
  6. Abendreport
    Einen Plan-vs.-Ist-Vergleich, der gegenüberstellt, was empfohlen wurde und was tatsächlich bei Garmin, WHOOP und Speediance stattgefunden hat.
  7. 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:

  1. 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.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, falls 8Sleep konfiguriert ist
  • data/training_plans/YYYY-MM-DD_morning.json
  • reports/morning/latest.html
  • reports/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: garth ist veraltet; python-garminconnect verwendet 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:

  1. Anbieterdaten synchronisieren
  2. erforderliche Tagesdaten prüfen
  3. Berichte generieren
  4. bereitstellen
  5. Benachrichtigungen senden
  6. Sprachzusammenfassungen generieren, falls verwendet
  7. 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:

  1. die bestehende dateibasierte Pipeline als maßgeblich behalten
  2. Garmin-/WHOOP-Daten in Open Wearables importieren oder spiegeln
  3. Open-Wearables-Daten zurück in Schatten-JSON-Dateien exportieren
  4. Schatten-Dateien gegen Produktionsdateien vergleichen
  5. 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:

  • calendarDate
  • totalSteps
  • restingHeartRate
  • sleepingSeconds
  • bodyBattery
  • activityName
  • activityType
  • durationSeconds
  • distanceMeters
  • distanceMiles
  • averageHR
  • maxHR
  • calories
  • trainingEffect
  • cadence
  • power

Empfohlenes Speichermuster

  • data/garmin/raw/YYYY-MM-DD.json
  • data/garmin/normalized/YYYY-MM-DD.json
  • data/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_score
  • hrv_rmssd_milli
  • resting_heart_rate
  • spo2_percentage
  • skin_temp_celsius
  • sleep_performance_percentage
  • respiratory_rate
  • strain
  • cycle_start
  • cycle_end
  • workout_sport_name

Empfohlenes Speichermuster

  • data/whoop/raw/recovery.json
  • data/whoop/raw/sleep.json
  • data/whoop/raw/workouts.json
  • data/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:

  1. Führen Sie dessen App- oder Client-Schicht lokal aus
  2. Authentifizieren Sie sich mit Ihrem Speediance-Konto
  3. Rufen Sie die Trainingshistorie über die bereitgestellten API-Methoden ab
  4. 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_id
  • date
  • title
  • duration_seconds
  • calories
  • total_volume
  • exercise_count
  • template_name
  • planned_duration
  • actual_duration
  • exercise_breakdown
  • estimated_1rm

Bewährtes Datenmodell

Für ein ernsthaftes Berichtssystem führen Sie zwei Indizes:

  1. bySession
  • ein Datensatz pro abgeschlossenem Training
  1. 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.json
  • data/speediance/normalized/history.json
  • data/speediance/normalized/by_exercise.json
  • data/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:

  1. Lade tagesaktuelle WHOOP-Erholung, aktuelle Belastung, BJJ-Belastung, Garmin Body Battery, Ruhepuls, aktuelle Laufbelastung, Wetter und den aktuellen Speediance-Planungsverlauf.
  2. Klassifiziere den Tag in eine Kategorie wie build, maintain, recover, protect oder post_bjj_brutal.
  3. Wähle ein Speediance-Gerät für das gesamte Workout, normalerweise Griffe, Langhantel oder Seil.
  4. Wähle nur geräteinterne Übungen für das Kern-Speediance-Workout aus.
  5. Füge null bis zwei Speediance-fremde Ergänzungen nur dann hinzu, wenn die Erholung es zulässt.
  6. Schreibe den Plan nach data/training_plans/YYYY-MM-DD_context.json.
  7. 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_consumed
  • protein_g
  • carbs_g
  • fat_g
  • fiber_g
  • target_calories
  • estimated_deficit

Empfohlenes Speichermuster

  • data/nutrition/raw/YYYY-MM-DD.csv
  • data/nutrition/normalized/YYYY-MM-DD.json
  • data/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_score
  • sleep_start
  • sleep_end
  • time_in_bed_seconds
  • time_asleep_seconds
  • hrv
  • resting_heart_rate
  • temperature_adjustments
  • away_mode

Empfohlenes Speichermuster:

  • data/eightsleep/raw/YYYY-MM-DD.json
  • data/eightsleep/normalized/YYYY-MM-DD.json
  • data/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.json
  • data/whoop/normalized/latest.json
  • data/speediance/normalized/history.json
  • data/nutrition/latest.json
  • data/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: garminconnect von cyberjunky/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:
    • /cycle für Strain-/Zyklus-Kontext
    • /recovery für Recovery-Score, HRV und Ruhepuls
    • /activity/sleep für Schlaf-Performance und Schlafzeiten
    • /activity/workout für Workouts und WHOOP Strain-Daten
    • /user/profile/basic und /user/measurement/body fü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.json
    • data/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:

  1. Normalisiere jeden Anbieter in dein eigenes Schema
    Erlaube niemals, dass ein Bericht von der Anbieter-Payload-Form abhängt.

  2. 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.

  1. Inoffizielle Integrationen als austauschbare Adapter behandeln
    Insbesondere Speediance.

  2. Garmin und WHOOP ergänzen sich, statt zu konkurrieren
    WHOOP = Bereitschaft. Garmin = Ausführungsdetails.

  3. Kraftdaten sowohl auf Sitzungs- als auch auf Übungsebene modellieren
    Andernfalls bleibt die Fortschrittsberichterstattung oberflächlich.

  4. Coaching an der heutigen Bereitschaft ausrichten, nicht an der von gestern
    Fehlende Same-Day-Erholung sollte das System auf reine Web-Berichterstattung herunterstufen.

  5. 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.

  6. 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.json schreibt

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.


#openclaw#garmin#whoop#speediance#Fitnessberichte#KI-Systeme