/garmin-workouts

Create and sync Garmin workouts with Python

Primary LanguagePythonApache License 2.0Apache-2.0

Garmin Connect Workouts Tools

Ruff CI pre-commit.ci status codecov

Python commandline for managing Garmin Connect workouts.

Note: This is a fork of the original project by mkuthan

Features:

  • Target power is set according to your current FTP.
  • You can define custom pace zones for running workouts.
  • All workouts under Your control stored as JSON files.
  • Easy to understand workout format, see examples below.
  • Workout parts like warm-up or cool-down are reusable.
  • Schedule saved workouts
  • The most important parameters (TSS, IF, NP) embedded in workout description field.

Roadmap

  • add Running workouts

Installation

Requirements:

Clone this repo:

git clone https://github.com/alfranz/garmin-workouts.git

And then install the CLI with poetry.

cd garmin-workouts
poetry install

Usage

First call to Garmin Connect takes some time to authenticate user.

Authentication

Define Garmin connect account credentials as GARMIN_USERNAME and GARMIN_PASSWORD environment variables:

export GARMIN_USERNAME=username
export GARMIN_PASSWORD=password

Alternatively use -u and -p command line arguments.

Import Workouts

Only running workouts have been tested.

Import workouts into Garmin Connect from definitions in YAML files. If the workout already exists it will be updated:

garminworkouts import 'sample_workouts/running//*.yaml'

Sample running workout definition:

name: "Easy 10K with some strides"
description: |
      Easy 10K run at a conversational pace. 
      In the last 2K, do 4x20sec strides at 80% effort.
settings:
  type: "running"
  zones: { easy: "5:10-5:35", intervall: "3:20-3:40", rest: "5:30-10:00" }
steps:
  - { zone: "easy", distance: "8km" }
  - &STRIDES
    - &FAST { zone: "intervall", duration: "0:20" }
    - &SLOW { zone: "rest", duration: "1:30" }
  - *STRIDES
  - *STRIDES
  - *STRIDES
  • Zones have to be defined as min/km with upper and lower pace targets, e.g. 5:10-5:35 format.

Each workout step can be defined with either duration or distance keys:

  • Duration is defined as HH:MM:SS (or MM:SS, or SS) format.If the duration is not specified "Lap Button Press" will be used to move into next workout step.

  • Distance can be specified in kms or meters but shall always include the unit, e.g. "400 meters", "400M", "1km", "1 kilometer".

Reusing workout definitions:

  • !include is a custom YAML directive for including another file as a part of the workout.

Reusing workout steps:

steps:
  - !include inc/warmup.yaml
  - { power: 70, duration: "20:00" }
  - { duration: "5:00" }
  - { power: 70, duration: "20:00" }
  - !include inc/cooldown.yaml
  • Thanks to YAML aliases, workout steps can be easily reused once defined.

Sample Over-Under workout:

steps:
  - { zone: "easy", distance: "8km" }
  - &STRIDES
    - &FAST { zone: "intervall", duration: "0:20" }
    - &SLOW { zone: "rest", duration: "1:30" }
  - *STRIDES
  - *STRIDES
  - *STRIDES
  • All nested sections are mapped as repeated steps in Garmin Connect. First repeat for warmup, second repeat for main interval (repeated 3 times) and the last one for cool down.

Check the sample_workouts folder to get an idea of the formatting possibilities.

Get Workout

Print full workout definition (as JSON):

$ garminworkouts get --id [WORKOUT_ID]
{"workoutId": 188952654, "ownerId": 2043461, "workoutName": "VO2MAX 5x4", "description": "FTP 214, TSS 80, NP 205, IF 0.96", "updatedDate": "2020-02-11T14:37:56.0", ...

Schedule Workouts

Schedule preexisting workouts using the workout number (e.g. "https://connect.garmin.com/modern/workout/234567894") The workout number is the last digits of the URL here: 234567894 Note: the date format is as follows: "2024-04-20"

garminworkouts schedule -d [DATE] -w [WORKOUT_ID]