saving
This commit is contained in:
204
QUICKSTART.md
Normal file
204
QUICKSTART.md
Normal file
@@ -0,0 +1,204 @@
|
||||
# QUICKSTART
|
||||
|
||||
You're ~5 minutes from a running dashboard. Two ways in: **web** (recommended, almost zero terminal) or **CLI** (for scripting).
|
||||
|
||||
---
|
||||
|
||||
## What you'll need
|
||||
|
||||
- **A Mac or Linux machine** with a terminal. Windows works under WSL but isn't tested.
|
||||
- **[uv](https://github.com/astral-sh/uv)** — Python's package manager. Install:
|
||||
```bash
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
```
|
||||
- **A Garmin export** — see *Getting your Garmin data* below. You can skip this for now and use the manual logger.
|
||||
|
||||
That's it. No accounts, no cloud, no Python knowledge required.
|
||||
|
||||
---
|
||||
|
||||
## Web app (recommended)
|
||||
|
||||
### 1. Get the code & install deps
|
||||
|
||||
```bash
|
||||
git clone <repo-url> openrun
|
||||
cd openrun
|
||||
uv sync
|
||||
```
|
||||
|
||||
`uv sync` creates a `.venv/` and installs everything. ~30 seconds on first run.
|
||||
|
||||
### 2. Launch the app
|
||||
|
||||
```bash
|
||||
uv run openrun-web
|
||||
```
|
||||
|
||||
Your browser opens at `http://localhost:8501`. (If it doesn't, copy that URL manually.)
|
||||
|
||||
### 3. Run the setup wizard
|
||||
|
||||
The first time you load the app, a yellow banner says **"Looks like a fresh install"** with a **Start setup →** button. Click it.
|
||||
|
||||
The wizard has five steps, each ~15 seconds:
|
||||
|
||||
1. **Intro** — read it, click *Start*.
|
||||
2. **Your profile** — name, max HR, lactate-threshold HR, resting HR. If you don't know your max HR, leave the default at 200 and we'll auto-derive zones. You can always come back.
|
||||
3. **HR zones** — auto-filled from your max HR. If you've already configured custom zones in Garmin Connect, paste those bpm boundaries here instead.
|
||||
4. **Race calendar** — optional. Add one row per upcoming race (label + ISO date). Skip-able.
|
||||
5. **Get your data** — upload a Garmin export zip, or skip and start logging by hand.
|
||||
|
||||
When the wizard finishes, you land on the **Dashboard**.
|
||||
|
||||
### 4. Look around
|
||||
|
||||
- **📊 Dashboard** — CTL/ATL/TSB tiles, PMC chart, weekly volume, polarized split, recent activities.
|
||||
- **📋 Activities** — filter by type/date/distance/name. Click any row to drill into splits, time-in-zone, decoupling.
|
||||
- **📈 Race plan** — edit your weekly plan in the table; the projected PMC redraws automatically. Race-day TSB is shown for each race in your calendar.
|
||||
- **📝 Manual log** — quick form to log strength/hike/unrecorded-run sessions. These feed the PMC.
|
||||
- **🛌 Recovery** — sleep stages, HRV + RHR trends, training→next-morning HRV correlation.
|
||||
- **🫀 Efficiency** — m/beat with rolling median, distance-bucket × year heatmap.
|
||||
- **🔄 Sync** — DB status + a place to upload more exports later.
|
||||
|
||||
That's the whole app.
|
||||
|
||||
### 5. Stop / restart
|
||||
|
||||
```
|
||||
Ctrl-C in the terminal that's running it.
|
||||
uv run openrun-web # restart any time
|
||||
```
|
||||
|
||||
Your data is in `data/garmin.db`. Back that file up periodically.
|
||||
|
||||
---
|
||||
|
||||
## Getting your Garmin data
|
||||
|
||||
The web app's Sync page accepts a Garmin Connect **data export zip**. You request one from Garmin:
|
||||
|
||||
1. Sign in at <https://www.garmin.com/account/datamanagement/exportdata>.
|
||||
2. Click **Request Data Export**. Pick the categories you want — `Activities`, `Wellness`, and `Connect Settings` are the useful ones.
|
||||
3. Garmin emails a download link within 24–72 hours.
|
||||
4. Download the zip (several hundred MB to a few GB depending on your history).
|
||||
5. Drag-and-drop it into the **Sync** page, click **Ingest**.
|
||||
|
||||
You'll see a progress log; takes 1–5 minutes depending on how many years of data.
|
||||
|
||||
### Two zip flavours
|
||||
|
||||
Garmin confusingly has two export formats:
|
||||
|
||||
- **Garmin Connect data export** (`connect.zip`) — what you get from the link above. Filenames are clean `<activity_id>_<name>.fit`. The wizard / Sync page handles this directly.
|
||||
- **Garmin Takeout dump** — a separate, UUID-named folder you can request via Google's data tools (less common). FITs use upload-IDs in filenames so they need an extra by-content linking step. If you have one of these, see the **CLI** section below for the 4-step sequence.
|
||||
|
||||
### Live sync (skip on first install)
|
||||
|
||||
You can also pull incrementally from Garmin Connect's live API instead of waiting on the email export. Currently this is **CLI-only** because Garmin's MFA flow needs interactive prompts:
|
||||
|
||||
```bash
|
||||
uv run openrun-auth # email + password + MFA prompt; saves OAuth to .secrets/
|
||||
uv run openrun-sync # incremental top-up (last 14 days by default)
|
||||
uv run openrun-sync --full # 365-day backfill
|
||||
```
|
||||
|
||||
Browser-driven live sync is on the roadmap.
|
||||
|
||||
---
|
||||
|
||||
## CLI quickstart (power-user path)
|
||||
|
||||
If you'd rather skip the web app entirely:
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
uv run openrun-init # creates data/garmin.db, prints status
|
||||
uv run openrun-ingest path/to/export/zip
|
||||
uv run openrun-link-fit path/to/export/ # only if it's a Takeout dump
|
||||
uv run openrun-time-in-zone # precompute the TIZ cache
|
||||
```
|
||||
|
||||
Then open one of the notebooks under `examples/notebooks/`, pick the project's `.venv` as the kernel, and run-all.
|
||||
|
||||
### Manual activity import via CSV
|
||||
|
||||
```bash
|
||||
echo 'activity_date,activity_type,distance_km,duration_min,training_load,notes,external_id
|
||||
2026-05-19,strength,,45,30,upper body,
|
||||
2026-05-18,hike,8.0,120,40,morning hike,' > workouts.csv
|
||||
|
||||
uv run openrun-import-manual workouts.csv
|
||||
```
|
||||
|
||||
`external_id` makes re-imports idempotent (upsert on conflict). Leave blank if you don't care about dedupe.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Port 8501 already in use"
|
||||
|
||||
Another Streamlit is running. Stop it (`Ctrl-C` in the terminal that started it) or pick another port:
|
||||
|
||||
```bash
|
||||
uv run openrun-web -- --server.port 8800
|
||||
```
|
||||
|
||||
### "FIT file not at recorded path"
|
||||
|
||||
You moved your export folder after linking. Run:
|
||||
|
||||
```bash
|
||||
uv run openrun-link-fit /new/path/to/export --relink
|
||||
```
|
||||
|
||||
This rewrites every stored FIT path to the new location by basename match.
|
||||
|
||||
### Dashboard is empty
|
||||
|
||||
Either you haven't ingested any data yet (use the Sync page or `openrun-ingest`), or the activities are filtered out by the default `running` / `trail_running` types — check the **Activities** page with the type filter cleared.
|
||||
|
||||
### Garmin live sync fails with 429
|
||||
|
||||
The endpoint rate-limits aggressively. Wait 30–60 minutes, switch networks, or use the Path A export instead.
|
||||
|
||||
### TSB looks way off
|
||||
|
||||
Most likely your training_load column is missing on a chunk of activities (Garmin only reports it for activities recorded by a compatible device). Check on the **Activities** page; the dashboard's PMC only counts rows where `training_load IS NOT NULL`.
|
||||
|
||||
---
|
||||
|
||||
## What next?
|
||||
|
||||
Once you have data in:
|
||||
|
||||
- **Race-plan page** — set up your goal race in `openrun.toml` (or via the wizard), then iterate on the weekly km / long-run km until projected race-day TSB lands in **+10 to +25**.
|
||||
- **Activity-detail page** — pick a recent race or hard workout, scroll to the **Pa:Hr decoupling** section, and look for where the bar chart crosses Friel's 10 % "unsustainable" line. That's where the wheels came off.
|
||||
- **Recovery page** — after a few weeks of data, check whether the Pearson r between yesterday's training load and tonight's HRV is meaningful for you. Often it's not, which is itself useful information.
|
||||
- **Manual log** — every strength session you log lifts CTL the next day. The Dashboard updates automatically.
|
||||
|
||||
---
|
||||
|
||||
## Where things live
|
||||
|
||||
| What | Where |
|
||||
|---|---|
|
||||
| Your config | `./openrun.toml` (edit by hand any time) |
|
||||
| Your data | `./data/garmin.db` (single SQLite file — back this up) |
|
||||
| Garmin auth tokens | `./.secrets/` (gitignored) |
|
||||
| Logs / errors | Wherever you ran `openrun-web` — stderr in that terminal |
|
||||
| Notebooks (reference) | `./examples/notebooks/` |
|
||||
|
||||
---
|
||||
|
||||
## Resetting
|
||||
|
||||
Want to start over?
|
||||
|
||||
```bash
|
||||
rm -rf data/ openrun.toml .secrets/
|
||||
uv run openrun-web # the wizard reappears
|
||||
```
|
||||
|
||||
Nothing on this list touches anything outside the project directory.
|
||||
Reference in New Issue
Block a user