Project Inspiration

I made Coach Pi to keep me motivated while getting back into running for fitness. The system is bulit around Gold, Silver, and Bronze goals to give a progressive sense of achievement. The main focus is habit building, with organized races as an approximate scaffolding to guide the training load.

Coach Pi is a personalized running coach that uses local AI to generate daily workout recommendations tailored to your training history, recovery status, and current conditions. In a world of subscription models, Coach Pi runs entirely on local hardware—ensuring your training data stays private while providing intelligent, context-aware guidance.

The system analyzes your Strava activities, Oura ring recovery metrics, and weather forecasts to deliver three-tier workout recommendations (Gold, Silver, Bronze) each day. It’s designed to run on low-power hardware like a Raspberry Pi Zero 2W, with AI inference handled by a separate device like a Jetson Orin Nano so that the system can port to a variety of consumer-grade hardware.

Key Features

Daily Workout Recommendations

Each day, the backend aggregates context from linked sources, evaluates the weekly performance and daily readiness against your goals, and generates three workout options at different difficulty tiers to give the user final say. The recommendations produce distance and pace targets that are governed by database queries and basic math gaurdrails to eliminate hallucinations from small models.

Intelligent Context Awareness

The system considers multiple data sources when generating recommendations:

  • Training History: Recent workouts, weekly mileage, and year-to-date progress
  • Recovery Metrics: Available integrations with consumer wearables Oura and Whoop
  • Weather Conditions: Temperature and conditions for the next 6 hours
  • Training Goals: Annual mileage targets and upcoming race dates

Progress Tracking

A visual progress bar tracks effort towards user-configured Bronze, Silver, and Gold distance goals to give the user multiple milestones to achieve. The app has a Stats page to show fun correlations between whatever the user finds interesting, such as readiness score vs. pace, the distribution of selected workout tier, or pace vs. heartrate.

Race Recommendations

To keep my training engaged, the system would look at the quality of my recent training and project an adapative recommendation on the next race I could run. The recommendation also accounts for my current goal, whether that be getting faster, running farther, or maintaining fitness to keep something relevant on the horizon.

Privacy-First Architecture

All data processing happens locally. Your training data never leaves your network, and AI inference runs on your own hardware using open-source models via Ollama.

Design Challenges & Solutions

Memory Constraints

I wanted to make the system lightweight so that it could be useful and accessible with achievable consumer-grade hardware. The backend and database were simple with Flask and SQLite, hosting these on a Raspberry Pi Zero with 512MB of RAM provided a nice hardware limitation to ensure the system is light. The AI inference was a more challenging problem. Frontier models and large open source models have extraordinary capability, but require sending your data to companies or having access to exceptional hardware. By developing the system on the Orin Nano, the largest models could only be around 4 Billion parameters. I learned a lot about managing temperature, chain of thought reasoning, and creating meaningful mathematical utilities to generate gaurdrails to make the system simultaneously creative and logical.

LLM Response Parsing

Local LLMs can produce inconsistent output formats. The system implements robust parsing that handles markdown artifacts, time notation variations (MM:SS vs seconds), and validates responses with Pydantic schemas.

OAuth Token Management

Both Strava and Oura use OAuth 2.0 with refresh tokens. The system implements concurrency-safe token refresh with optimistic locking to prevent race conditions when tokens expire.

Distributed Architecture

Separating the web server from LLM inference allows the system to run on low-power hardware while still providing responsive AI recommendations. Network communication between devices is handled via HTTP with appropriate timeouts.

Technical Architecture

Coach Pi uses a distributed architecture optimized for low-power embedded systems:

Hardware Setup

  • Raspberry Pi Zero 2W (512MB RAM): Runs the Flask web server, SQLite database, and data aggregation
  • Jetson Orin Nano: Hosts the Ollama LLM server for AI inference
  • Both devices communicate over local network

System Components

Backend Services

  • Flask web server handles HTTP requests and serves the web interface
  • SQLAlchemy ORM manages SQLite database for activity history, recommendations, and recovery data
  • Modular API clients for Strava, Oura, and NOAA Weather APIs
  • OAuth token management with automatic refresh and concurrency safety

AI Integration

  • Local LLM inference via Ollama API to make the system approachable for new local AI users
  • Structured prompt engineering for consistent JSON output with small (~4B parameter) models
  • Pydantic validation ensures response quality
  • Response parsing handles markdown artifacts and format variations

Frontend

  • Vanilla JavaScript (no frameworks) for minimal bundle size
  • Responsive design optimized for mobile devices
  • Real-time progress updates via polling mechanism
  • Workout completion tracking for adaptive recommendations

Technology Stack

Backend

  • Python 3.9+
  • Flask 3.0.0 (lightweight web framework)
  • SQLAlchemy 2.0+ (ORM for database operations)
  • SQLite (embedded database, no separate server needed)
  • Pydantic 2.10.6 (data validation and schema enforcement)
  • Requests (HTTP client for API calls)

Frontend

  • HTML5/CSS3
  • Vanilla JavaScript
  • Fetch API with timeout handling

External Services

  • Strava API v3 (activity data)
  • Oura API v2 (recovery and sleep scores)
  • NOAA Weather API (free public weather forecasts)
  • Ollama (local LLM inference server)

Hardware

  • Raspberry Pi Zero 2W (512MB RAM constraint)
  • Jetson Orin Nano (6-8GB VRAM for LLM inference)
Back to Personal Projects