Wahoo Cloud Skill
Provides programmatic access to Wahoo Fitness Cloud data. This skill manages OAuth2 authentication, workout synchronization, and FIT file processing.
🚀 Agent Quickstart
When a user asks about their Wahoo workouts, training, or fitness data, use these workflows:
| User Intent | Action / Command |
| :--- | :--- |
| "Sync my Wahoo workouts" | python3 {baseDir}/scripts/fetch_workouts.py |
| "Show my recent rides" | Query the local SQLite DB: $WAHOO_BASE_DIR/wahoo.db (default: ~/.wahoo/wahoo.db) — schema below |
| "Parse this FIT file" | python3 {baseDir}/scripts/parse_fit.py <PATH_TO_FIT> |
| "Connect/Set up Wahoo" | 1. Verify WAHOO_CLIENT_ID and WAHOO_CLIENT_SECRET exist.<br>2. If missing, ask user to provide them.<br>3. Run python3 {baseDir}/scripts/oauth_setup.py |
| "Token expired / persistent 401 errors" | Run python3 {baseDir}/scripts/oauth_setup.py to re-authorize. Force-refresh without browser: python3 -c "import sys; sys.path.insert(0,'lib'); import wahoo_auth; wahoo_auth.refresh()" |
🛠 Key Workflows
1. Authentication & Setup
This skill requires a Wahoo Developer App.
- Credentials: Must be provided as
WAHOO_CLIENT_IDandWAHOO_CLIENT_SECRET. - OAuth Flow: If tokens are missing or expired, run
scripts/oauth_setup.py. This is an interactive process. You must present the URL to the user, wait for them to authenticate, and then ask them to paste the resulting redirect URL/code back into the terminal. - Token Storage: Tokens are stored at $WAHOO_BASE_DIR/secrets/wahoo_tokens.json (controlled by WAHOO_BASE_DIR env var, default ~/.wahoo).
2. Data Synchronization
- Command:
python3 scripts/fetch_workouts.py - Behavior: Idempotent. It fetches new workouts, downloads FIT files, and populates the local SQLite database.
- Database Path:
$WAHOO_BASE_DIR/wahoo.db (default: ~/.wahoo/wahoo.db) - Rate Limits: The script automatically handles Wahoo's sandbox rate limits (25 req / 5 min) using exponential backoff.
3. Querying Training Data
Once synced, use the following SQL patterns to answer user questions:
- Recent Workouts:
SELECT * FROM workouts ORDER BY starts DESC LIMIT 10; - Power/HR Series:
SELECT timestamp, power_w, heart_rate, cadence FROM records WHERE workout_id = <id> ORDER BY timestamp; - Elevation/GPS:
SELECT timestamp, position_lat_deg, position_long_deg, enhanced_altitude_m FROM records WHERE workout_id = <id>;
⚠️ Critical Constraints & Pitfalls
- Rate Limiting: Wahoo Sandbox is strict. Do not attempt to loop calls rapidly; rely on the
wahoo_api.pybuilt-in backoff. - Data Types: The Wahoo API returns decimal values as strings. Always cast to
float()before performing mathematical analysis. - Metric Conversion:
- Meters to Miles:
m / 1609.34 - Meters/Second to MPH:
m/s * 2.237
- Meters to Miles:
- Workout Summaries: The
/v1/workoutslist endpoint returnsnullforworkout_summary. You must call/v1/workouts/<id>to get specific metrics like NP, TSS, or the FIT file URL.
Error Reference
| HTTP Code | Meaning | Resolution | | :--- | :--- | :--- | | 401 | Token expired/invalid — auto-refresh runs once | Re-run oauth_setup.py if it keeps failing | | 403 | Insufficient scope | Re-authorize with missing scope in WAHOO_SCOPES | | 429 | Rate limit | wahoo_api.py backs off automatically, use --limit to reduce call volume | | 404 | Workout not found | Confirm ID and ownership |
微信扫一扫