{"skill":{"slug":"garmin-ultimate-frisbee-analysis","displayName":"garmin-ultimate-frisbee-analysis","summary":"Analyzes Garmin Ultimate Frisbee data to generate interactive HTML dashboards on sprints, fatigue, heart rate, training load, and season trends for performan...","description":"---\nname: garmin-frisbee-analysis\ndescription: Ultimate Frisbee performance analytics powered by Garmin data. Analyzes and monitors game and training data . Generates interactive HTML dashboards for post-game review, tournament fatigue tracking, and season-long trend analysis. Supports four comparison modes: training vs training, tournament vs tournament, training vs game intensity, and early vs late season. Built for competitive Ultimate Frisbee players who want data-driven insight into performance, recovery, and fitness progression.\nversion: 1.1.3\nauthor: Evelyn & Claude\nhomepage: https://github.com/EvelynDevelops/garmin-frisbee-analysis\nenv:\n  - GARMIN_EMAIL\n  - GARMIN_PASSWORD\ninstall: pip install -r requirements.txt && python3 scripts/garmin_auth.py login\nmetadata: {\"requires\":{\"env\":[\"GARMIN_EMAIL\",\"GARMIN_PASSWORD\"]},\"install\":[{\"id\":\"pip-deps\",\"kind\":\"shell\",\"command\":\"pip3 install -r requirements.txt\",\"label\":\"Install Python dependencies\"},{\"id\":\"garmin-auth\",\"kind\":\"shell\",\"command\":\"python3 scripts/garmin_auth.py login\",\"label\":\"Authenticate with Garmin Connect\"}],\"tokenStorage\":\"~/.clawdbot/garmin/ (permissions 700, session tokens only, no plaintext credentials)\",\"clawdbot\":{\"emoji\":\"🥏\"}}\n---\n\n# Garmin Frisbee Analysis\n\nAnalyze Garmin health and performance data specifically for Ultimate Frisbee players. Generate interactive HTML dashboards for post-game review, tournament fatigue tracking, training load optimization, and season-long trend comparison.\n\n## Two Installation Paths\n\n1. **Clawdbot Skill** (this guide) — Use with Clawdbot for natural language queries and proactive monitoring\n2. **MCP Server** ([see MCP setup guide](references/mcp_setup.md)) — Use with Claude Desktop as an MCP server\n\n---\n\n## Setup (first time only)\n\n### 1. Install Dependencies\n\n```bash\npip3 install -r requirements.txt\n```\n\nPinned versions are in [requirements.txt](requirements.txt):\n- `garminconnect>=0.2.19` — Garmin Connect API client\n- `fitparse>=3.2.0` — FIT file parsing for activity data\n- `gpxpy>=1.3.5` — GPX file parsing\n\n### 2. Configure Credentials\n\n> **Why email + password?** Garmin does not expose a public OAuth API. The `garminconnect` library authenticates via Garmin's SSO, the same flow as the Garmin Connect mobile app. The password is used **once** during login and is **never written to disk or logged**. The resulting session token is then stored locally at `~/.clawdbot/garmin/` (permissions 700); all subsequent API requests use that token, not the password.\n\nSet `GARMIN_EMAIL` and `GARMIN_PASSWORD` in your shell profile (`~/.zshrc` or `~/.bashrc`):\n\n```bash\nexport GARMIN_EMAIL=\"your-email@example.com\"\nexport GARMIN_PASSWORD=\"your-password\"\n```\n\n### 3. Authenticate\n\n```bash\npython3 scripts/garmin_auth.py login\npython3 scripts/garmin_auth.py status   # verify\n```\n\n---\n\n## Frisbee Scripts\n\n### Post-Game / Post-Training Analysis\n\nAnalyze a single activity in depth: sprints, speed, heart rate zones.\n\n```bash\n# Most recent activity\npython3 scripts/frisbee_activity.py --latest\n\n# Specific date\npython3 scripts/frisbee_activity.py --date 2026-03-08\n\n# Specific activity ID\npython3 scripts/frisbee_activity.py --activity-id 12345678\n\n# Save to file\npython3 scripts/frisbee_activity.py --latest --output ~/Desktop/game.html\n```\n\n**Dashboard includes:**\n- Summary cards: duration, distance, sprint count, top speed, sprint fatigue index, high-intensity distance\n- Speed timeline with sprint highlight bands\n- Sprint peak speed trend (detects fatigue: are later sprints slower?)\n- Heart rate zone distribution (Zone 1–6)\n\n**Sprint detection:** speed > 14.4 km/h sustained ≥ 2 seconds.\n**Sprint Fatigue Index:** last 3 sprint peaks ÷ first 3 sprint peaks. < 0.85 = significant fatigue.\n\n---\n\n### Tournament Review Dashboard\n\nFull overview of a multi-day tournament: fatigue curve, game intensity, heart rate recovery, overnight sleep/HRV.\n\n```bash\npython3 scripts/frisbee_tournament.py \\\n  --start 2026-03-08 \\\n  --end 2026-03-10 \\\n  --name \"Spring Tournament 2026\" \\\n  --output ~/Desktop/tournament.html\n```\n\n**Dashboard includes:**\n- Body Battery fatigue curve across tournament days (includes day-before baseline)\n- Per-game avg/max heart rate comparison\n- Heart Rate Recovery curves post-game (30 min window, all games overlaid)\n- Overnight sleep hours + HRV per tournament night\n- Activity table with all detected games\n\n---\n\n### Comparison Analysis\n\nCompare training sessions, games, or the full season.\n\n```bash\n# Training vs training (last 90 days)\npython3 scripts/frisbee_compare.py --mode training --days 90\n\n# Game vs game\npython3 scripts/frisbee_compare.py --mode tournament --days 180\n\n# Training intensity vs game intensity\npython3 scripts/frisbee_compare.py --mode cross --days 60\n\n# Full season overview\npython3 scripts/frisbee_compare.py --mode season --days 180\n\n# Save output\npython3 scripts/frisbee_compare.py --mode season --days 180 --output ~/Desktop/season.html\n```\n\n**Activity classification** uses name keywords:\n- Game: `game`, `match`, `tournament`, `vs`, `finals`\n- Training: `practice`, `training`, `train`, `drill`, `scrimmage`\n\n**Dashboard includes:**\n- Top speed trend over time (training vs game color-coded in cross mode)\n- Avg heart rate per activity (color by intensity)\n- Morning HRV on day of each activity\n- Volume trend: duration + distance over time\n- Full activity table\n\n---\n\n## General Garmin Data\n\n```bash\n# Sleep\npython3 scripts/garmin_data.py sleep --days 14\n\n# Body Battery\npython3 scripts/garmin_data.py body_battery --days 30\n\n# HRV\npython3 scripts/garmin_data.py hrv --days 30\n\n# Heart rate\npython3 scripts/garmin_data.py heart_rate --days 7\n\n# Activities\npython3 scripts/garmin_data.py activities --days 30\n\n# Stress\npython3 scripts/garmin_data.py stress --days 7\n\n# Combined summary\npython3 scripts/garmin_data.py summary --days 7\n\n# Custom date range\npython3 scripts/garmin_data.py sleep --start 2026-01-01 --end 2026-01-15\n```\n\n## General Health Charts\n\n```bash\npython3 scripts/garmin_chart.py sleep --days 30\npython3 scripts/garmin_chart.py body_battery --days 30\npython3 scripts/garmin_chart.py hrv --days 90\npython3 scripts/garmin_chart.py activities --days 30\npython3 scripts/garmin_chart.py dashboard --days 30\n```\n\n---\n\n## Answering Frisbee Questions\n\n| Player asks | Script | What to report |\n|-------------|--------|----------------|\n| \"How many sprints did I hit?\" | `frisbee_activity.py --latest` | sprint_count, sprint fatigue index |\n| \"What was my top speed?\" | `frisbee_activity.py --latest` | top_speed_kmh from summary |\n| \"Was I fatigued at the end?\" | `frisbee_activity.py --latest` | sprint_fatigue_index < 0.85 = yes |\n| \"How long was my heart rate elevated?\" | `frisbee_activity.py --latest` | Zone 4-6 time percentage |\n| \"Did I recover fast enough between points?\" | `frisbee_tournament.py` | HRR curves, slope comparison |\n| \"Was I ready for the tournament?\" | `frisbee_tournament.py` | Pre-game Body Battery values |\n| \"Is my training intense enough?\" | `frisbee_compare.py --mode cross` | Avg HR: training vs game |\n| \"Am I improving this season?\" | `frisbee_compare.py --mode season` | Top speed + HRV trends |\n| \"How did I sleep during the tournament?\" | `frisbee_tournament.py` | Recovery nights chart |\n\n---\n\n## Data Availability (Garmin 265S)\n\n| Metric | Available |\n|--------|-----------|\n| Sprint count & speed | ✅ FIT file analysis |\n| Top speed | ✅ FIT file `speed` field |\n| Sprint fatigue index | ✅ Computed from speed time-series |\n| Heart rate zones | ✅ FIT file HR + max HR |\n| Heart Rate Recovery (HRR) | ✅ Intraday HR time-series |\n| Body Battery | ✅ Garmin API |\n| HRV (overnight) | ✅ Garmin API |\n| Sleep stages & score | ✅ Garmin API |\n| Total distance | ✅ FIT file + Garmin API |\n| High-intensity distance | ✅ Computed from speed threshold |\n| Ground Contact Time | ❌ Requires HRM-Run Pod (not wrist) |\n\n---\n\n## Key Frisbee Metrics Explained\n\n### Sprint Fatigue Index\nRatio of last 3 sprint peak speeds to first 3: `≥ 0.95` stable, `0.85–0.95` mild decline, `< 0.85` significant fatigue. Use this to judge if you're losing speed output as the game progresses.\n\n### Heart Rate Recovery (HRR)\nHow fast your HR drops after game ends. Steeper curve = better cardiovascular fitness and recovery. Flatter curves in later games of a tournament = cumulative fatigue.\n\n### Body Battery (0–100)\nPre-game value is the key readiness indicator. `≥ 70` = ready to go, `50–69` = manageable, `< 50` = compromised performance likely.\n\n### Heart Rate Zones\n- **Zone 4 (70–80% max)**: Sustained hard effort — hallmark of well-executed frisbee\n- **Zone 5–6 (80–100% max)**: Explosive sprints and close contests\n- High Zone 4–6 in training = adequate game-prep intensity\n\n---\n\n## Troubleshooting\n\n- **\"FIT file download failed\"**: Check activity ID; some activity types may not export FIT\n- **No sprints detected**: Activity may not include speed data, or you used a non-GPS mode\n- **HRR chart empty**: Intraday HR not available for that date; ensure \"All-day HR monitoring\" is on in Garmin settings\n- **Activities not classified**: Name your activities with keywords like \"game vs X\" or \"practice\" — see classification keywords above\n- **Tokens expired**: Re-run `python3 scripts/garmin_auth.py login`\n\n---\n\n## Privacy & Security\n\n**Credentials**\n- `GARMIN_EMAIL` and `GARMIN_PASSWORD` are read from environment variables at runtime only\n- The Garmin password is **never written to disk or logged** — used only during the authentication step, then discarded\n- No config file stores credentials\n\n**Session tokens**\n- Stored in `~/.clawdbot/garmin/` with directory permissions `700` (owner read/write/execute only)\n- Managed by the `garth` library (part of `garminconnect`); format is an opaque token bundle, not plaintext password\n- To revoke: `rm -rf ~/.clawdbot/garmin/` — next login will re-authenticate\n\n**Network**\n- Credentials are used only to authenticate with Garmin Connect and are not transmitted to any third-party service\n- All API calls go to `connect.garmin.com` only\n- Generated HTML dashboards load Chart.js from `cdn.jsdelivr.net` (versions pinned: `chart.js@4.4.0`, `chartjs-plugin-annotation@3.0.1`) — requires internet access when viewing dashboards\n\n---\n\n## References\n\n- `references/api.md` — Garmin Connect API details\n- `references/health_analysis.md` — Science-backed metric interpretation\n- `references/mcp_setup.md` — Claude Desktop MCP setup\n\n---\n\n## Version Info\n\n- **Version**: 1.1.3\n- **Created**: 2026-03-11\n- **Updated**: 2026-03-16\n- **Author**: Evelyn & Claude\n- **License**: MIT\n- **Dependencies**: garminconnect, fitparse, gpxpy\n","tags":{"latest":"1.0.0"},"stats":{"comments":0,"downloads":534,"installsAllTime":0,"installsCurrent":0,"stars":0,"versions":1},"createdAt":1773639345419,"updatedAt":1778491940346},"latestVersion":{"version":"1.0.0","createdAt":1773639345419,"changelog":"- Initial public release of Ultimate Frisbee analytics skill powered by Garmin data.\n- Generates interactive HTML dashboards for post-game, tournament, training, and season review.\n- Supports four detailed comparison modes: training vs training, tournament vs tournament, training vs game intensity, and early vs late season.\n- Enables in-depth analysis of key metrics, including sprint count, top speed, sprint fatigue index, heart rate zones, recovery, and fitness progression.\n- Provides easy command-line scripts for activity analysis, tournament review, and overall health monitoring.\n- Secure Garmin authentication—no plaintext credentials stored; only session tokens saved locally.","license":"MIT-0"},"metadata":null,"owner":{"handle":"evelyndevelops","userId":"s175f4e5bb17amgmafc7b6jhgs83jn3v","displayName":"Evelyn","image":"https://avatars.githubusercontent.com/u/110106982?v=4"},"moderation":{"isSuspicious":false,"isMalwareBlocked":false,"verdict":"clean","reasonCodes":["review.llm_review"],"summary":"Review: review.llm_review","engineVersion":"v2.4.24","updatedAt":1780089912746}}