Skip to content

LucasVance/intervals-icu-planner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

49 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Automated Training Planner for Intervals.icu

This repository contains a Python script that automatically generates a daily training plan based on your long-term fitness goals and syncs it as a structured workout to your Intervals.icu calendar. The vast majority of the code in this repository, along with this readme, is generated by Gemini.

The script runs automatically every day using GitHub Actions, creating a dynamic feedback loop: it reads your current fitness state, calculates the precise load needed for the next day, and populates your calendar so you always know what's next.

Core Concepts

This planner is built on the well-established principles of training load management, with a key custom metric for controlling daily intensity.

  • CTL (Chronic Training Load): A proxy for your overall fitness, based on a long-term weighted average of your training load. The number of days is configurable.

  • ATL (Acute Training Load): A proxy for your fatigue, based on a short-term weighted average. The number of days is configurable.

  • TSB (Training Stress Balance): Calculated as CTL - ATL, this represents your "form" or "freshness." A negative TSB is typical during a build phase. This script aims to hold your TSB at a specific target level.

  • ALB (Acute Load Balance): Defined as ATL (at the start of the day) - Daily TSS. This acts as a "guard rail" to prevent excessively large single-day jumps in training stress, ensuring a smooth and sustainable progression.

Features

  • Fetches your current fitness (CTL) and fatigue (ATL) daily from the Intervals.icu API.

  • Calculates the precise Training Stress Score (TSS) required for the next day to progress towards your goals.

  • Configurable Time Constants: Allows you to set custom time periods for CTL and ATL (e.g., 40/4 days instead of the standard 42/7).

  • Dual-Constraint Calculation: Calculates TSS based on two primary inputs:

    1. A long-term Target TSB you want to maintain.

    2. A limiting ALB (Acute Load Balance) that controls day-to-day aggressiveness.

  • Advanced Workout Generation:

    • Builds workouts from a library of user-defined templates.

    • Supports variable duration steps within templates to precisely match the target TSS.

    • Parses a weekly schedule to plan different workout types on different days.

    • Supports "double" days with a fixed workout plus a variable workout, or two workouts with an evenly split TSS load.

  • Uploads one or more workouts to your Intervals.icu calendar for the next day.

  • Designed for full automation via the included GitHub Actions workflow.

Setup and Configuration

To get this running, you'll need to configure your goals and set up the necessary secrets for the GitHub Action. Fork this repository and complete the next steps.

1. The config.json File

This file holds all the non-sensitive parameters for your training plan. Edit the values in config.json to match your personal goals.

{
  "training_goals": {
    "ctl_days": 40,
    "atl_days": 4,
    "target_ctl": 150.0,
    "target_tsb": -28.0,
    "alb_lower_bound": -10.0
  },
  "workout_templates": {
    "endurance": {
      "name": "Endurance Ride",
      "description": "- 10m ramp 40%-65% FTP\n- {{ DURATION }} 65% FTP\n- 5m 50% FTP"
    },
    "threshold": {
      "name": "Threshold Intervals",
      "description": "- 15m ramp 40%-80% FTP\n- 3x({{ DURATION }} 95-100% FTP, 5m 50% FTP)\n- 10m Z1"
    },
    "morning_spin": {
      "name": "Morning Spin",
      "description": "- 45m 60% FTP"
    }
  },
  "weekly_schedule": {
    "monday": ["recovery"],
    "tuesday": ["morning_spin", "threshold"],
    "saturday": "endurance *2",
    "default": ["endurance"]
  },
  "operational_settings": {
    "live_mode": true,
    "workout_name_prefix": "Auto-Plan:",
    "timezone": "America/Los_Angeles"
  }
}

training_goals

  • ctl_days & atl_days: The time constants for your fitness and fatigue calculations.

  • target_ctl: Your ultimate long-term fitness goal.

  • target_tsb: The daily TSB you want to hold during your training block.

  • alb_lower_bound: The "floor" for daily training aggressiveness. A value of -10 allows daily TSS to exceed the morning's ATL by about 10 points.

workout_templates

  • This is your library of workouts. You can define as many as you like.

  • Each template has a name and a description using the Intervals.icu workout format.

  • Use {{ DURATION }} to mark one step in a template as having a variable duration that will be auto-calculated to meet the target TSS.

  • Templates without the {{ DURATION }} placeholder are treated as fixed-load workouts.

weekly_schedule

  • This maps the days of the week to the name of the template(s) you want to perform.

  • Single Day: ["endurance"] - Schedules one workout using the "endurance" template for the day's total target TSS.

  • Fixed + Variable Double: ["morning_spin", "threshold"] - Schedules two workouts. The first is fixed. The second gets the remainder of the day's total target TSS.

  • Evenly Split Double: "endurance *2" - Schedules two workouts using the "endurance" template, each with 50% of the day's total target TSS.

  • "default" is used for any day not explicitly listed in the schedule.

operational_settings

  • live_mode: Should be true for the GitHub Action to run for real.

  • workout_name_prefix: A custom prefix for the name of all generated workouts.

  • timezone: Your local IANA timezone name (e.g., "America/New_York", "Europe/London").

2. GitHub Actions Secrets

To allow the script to securely access your Intervals.icu account, you must add your Athlete ID and API Key as "Repository secrets". They can be found at the bottom of the intervals.icu settings page.

  1. In your GitHub repository, go to Settings > Secrets and variables > Actions.

  2. Click the "New repository secret" button.

  3. Create two secrets:

    • Name: ATHLETE_ID

      • Value: iXXXXXX
    • Name: API_KEY

      • Value: YOUR_API_KEY_HERE

3. GitHub Actions workflow file

This project uses the workflow file at .github/workflows/daily_run.yml to run the script on a schedule. By default, it runs every night at 5 AM UTC, which avoids issues with day rollover for most timezones. You can change the cron schedule if needed.

name: "Run Daily Workout Planner"

on:
  # Schedule to run every day at 05:00 UTC
  schedule:
    - cron: '0 5 * * *'
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

jobs:
  run-python-script:
    runs-on: ubuntu-latest
    steps:
      - name: Check out repository code
        uses: actions/checkout@v4

      - name: Set up Python 3.11
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Execute Python script
        env:
          # Makes the GitHub secrets available as environment variables to the script
          API_KEY: ${{ secrets.API_KEY }}
          ATHLETE_ID: ${{ secrets.ATHLETE_ID }}
        run: python main.py

How it works

The script follows a simple, robust daily cycle:

  1. Trigger: The GitHub Actions scheduler triggers the script at a set time every night.

  2. Read State: The script makes an API call to Intervals.icu to get your latest CTL and ATL values at the end of the current day.

  3. Calculate: Using your configured goals, it calculates the total TSS target for tomorrow.

  4. Build Workout(s): It looks up the day's schedule, parses the workout template(s), and generates one or more complete, structured workouts with durations calculated to match the target TSS.

  5. Write to Calendar: It makes a final API call to create the new workout(s) on your Intervals.icu calendar for the next day.

Local testing

If you want to test the script on your local machine before letting the automation run:

  1. Clone the repository.

  2. Create a Python virtual environment: python3 -m venv .venv and source .venv/bin/activate.

  3. Install dependencies: pip install -r requirements.txt.

  4. Temporarily set your live_mode to false in config.json.

  5. Set your secrets as local environment variables before running the script:

    export ATHLETE_ID="iXXXXXX"
    export API_KEY="YOUR_API_KEY_HERE"
    python main.py
    
    

License

This project is licensed under the MIT License. See the LICENSE file for details.

About

Automated training planner for intervals.icu

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages