diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0190d8f..05cb7ad 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -92,7 +92,7 @@ jobs: python -m pip install --upgrade pip - name: Build project - run: python build.py + run: python scripts/build.py - name: Verify build outputs run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fbdd8bd..b1f40c3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -88,7 +88,7 @@ jobs: python -m pip install --upgrade pip - name: Build project - run: python build.py + run: python scripts/build.py - name: Verify build outputs run: | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..214d109 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,393 @@ +# Contributing to Peloterm + +Thank you for your interest in contributing to Peloterm! This guide will help you get started with development, understand the project structure, and submit pull requests. + +## ๐Ÿ“ Project Structure + +``` +peloterm/ +โ”œโ”€โ”€ peloterm/ # Python package +โ”‚ โ”œโ”€โ”€ web/ +โ”‚ โ”‚ โ”œโ”€โ”€ static/ # Built Vue files (auto-generated) +โ”‚ โ”‚ โ””โ”€โ”€ server.py # FastAPI backend +โ”‚ โ”œโ”€โ”€ devices/ # Bluetooth device handlers +โ”‚ โ”œโ”€โ”€ cli.py # Terminal interface +โ”‚ โ””โ”€โ”€ ... # Other Python modules +โ”œโ”€โ”€ frontend/ # Vue 3 web interface +โ”‚ โ”œโ”€โ”€ src/ +โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Vue components +โ”‚ โ”‚ โ”œโ”€โ”€ composables/ # Reusable logic +โ”‚ โ”‚ โ””โ”€โ”€ types/ # TypeScript definitions +โ”‚ โ”œโ”€โ”€ package.json +โ”‚ โ””โ”€โ”€ vite.config.ts +โ”œโ”€โ”€ build.py # Build frontend โ†’ Python package +โ”œโ”€โ”€ dev.py # Development server runner +โ””โ”€โ”€ pyproject.toml # Python package configuration +``` + +## ๐Ÿš€ Development Setup + +### Prerequisites + +- Python 3.8+ +- Node.js 16+ +- Git + +### Initial Setup + +1. **Clone the repository:** + ```bash + git clone https://github.com/yourusername/peloterm.git + cd peloterm + ``` + +2. **Create a virtual environment:** + ```bash + python -m venv venv + source venv/bin/activate # On Windows: venv\Scripts\activate + ``` + +3. **Install Python dependencies:** + ```bash + pip install -e ".[dev]" + ``` + +4. **Install frontend dependencies:** + ```bash + cd frontend + npm install + cd .. + ``` + +## ๐Ÿ›  Development Workflow + +### Quick Start (Recommended) + +For most development work, use the unified development server: + +```bash +# Run both Vue dev server + FastAPI backend +python dev.py +``` + +This provides: +- Vue UI: http://localhost:5173 (with hot reload) +- FastAPI: http://localhost:8000 +- Automatic proxy setup between frontend and backend + +### Frontend Development + +For frontend-focused work: + +```bash +# Terminal 1: Run backend +python -m peloterm.web.server + +# Terminal 2: Run frontend with proxy +cd frontend +npm run dev +``` + +### Backend Development + +For backend-focused work: + +```bash +# Run just the FastAPI server +python -m peloterm.web.server +``` + +### Building for Production + +```bash +# Build frontend into Python package +python build.py + +# Test production build +python dev.py prod +``` + +## ๐Ÿ— Architecture + +### Backend (Python) + +- **FastAPI** web server with WebSocket support +- **Bluetooth** device communication using `bleak` +- **Real-time** metrics processing +- **Configuration** management +- **FIT file** generation for ride recording +- **Strava API** integration + +Key modules: +- `peloterm/cli.py` - Command-line interface +- `peloterm/web/server.py` - Web server and API +- `peloterm/devices/` - Bluetooth device handlers +- `peloterm/strava/` - Strava integration +- `peloterm/recording/` - Ride recording and FIT file generation + +### Frontend (Vue 3) + +- **Component-based** architecture with TypeScript +- **Chart.js** for real-time visualizations +- **Responsive** design with mobile support +- **WebSocket** connection for real-time data +- **Hot reload** development + +Key directories: +- `frontend/src/components/` - Vue components +- `frontend/src/composables/` - Reusable logic +- `frontend/src/types/` - TypeScript definitions + +### Build Process + +1. Vue builds optimized production files using Vite +2. `build.py` copies files to `peloterm/web/static/` +3. FastAPI serves the built files as static assets +4. Single Python command runs everything in production + +## ๐Ÿงช Testing + +### Python Tests + +```bash +# Run all Python tests +pytest + +# Run with coverage +pytest --cov=peloterm + +# Run specific test file +pytest tests/test_devices.py +``` + +### Frontend Tests + +```bash +cd frontend + +# Run unit tests +npm run test:unit + +# Run tests in watch mode +npm run test:unit -- --watch + +# Run with coverage +npm run test:unit -- --coverage +``` + +### Integration Tests + +```bash +# Test the full build process +python build.py +python dev.py prod +# Verify http://localhost:8000 works correctly +``` + +## ๐Ÿ“ฆ Distribution + +The build process creates a self-contained Python package: +- All frontend assets bundled into the package +- No separate frontend server needed in production +- Single `pip install` for end users +- Automatic static file serving via FastAPI + +## ๐ŸŽฏ Advanced Features + +### Command Options + +The `peloterm start` command supports many options: + +- `--config PATH` - Use a specific configuration file +- `--timeout 60` - Set connection timeout in seconds (default: 60) +- `--debug` - Enable debug output +- `--web/--no-web` - Enable/disable web UI (default: enabled) +- `--port 8000` - Set web server port +- `--duration 30` - Set target ride duration in minutes +- `--no-recording` - Disable automatic ride recording + +### Strava Integration + +Peloterm includes comprehensive Strava integration: + +```bash +# Set up Strava (interactive) +peloterm strava setup + +# Test connection +peloterm strava test + +# List recorded rides +peloterm strava list + +# Upload specific ride +peloterm strava upload ride_file.fit --name "Epic Ride" +``` + +### File Formats + +Peloterm generates **FIT files** for ride recording: +- โœ… **Compact**: Binary format, smaller than TCX/GPX +- โœ… **Complete**: Supports all cycling metrics +- โœ… **Compatible**: Works with Garmin devices and most apps +- โœ… **Strava-optimized**: Best format for Strava uploads + +Files are saved to `~/.peloterm/rides/` + +## ๐Ÿ”ง Configuration + +### Development Configuration + +Create a `.env` file in the project root: + +```env +DEBUG=true +LOG_LEVEL=debug +STRAVA_CLIENT_ID=your_client_id +STRAVA_CLIENT_SECRET=your_client_secret +``` + +### Device Configuration + +Device configuration is stored in `~/.peloterm/config.json`: + +```json +{ + "devices": { + "heart_rate": "AA:BB:CC:DD:EE:FF", + "power_meter": "11:22:33:44:55:66", + "cadence": "77:88:99:AA:BB:CC" + }, + "web": { + "iframe_url": "https://www.youtube.com/embed/VIDEO_ID", + "port": 8000 + } +} +``` + +## ๐Ÿ“ˆ Performance Considerations + +### Frontend Optimization + +- **Tree-shaking** removes unused code +- **Asset optimization** and caching +- **Efficient reactivity** with Vue 3 Composition API +- **WebSocket** for low-latency data updates + +### Backend Optimization + +- **Async/await** for non-blocking operations +- **Efficient Bluetooth** scanning and connection +- **Minimal memory** footprint for long rides +- **Graceful error handling** and reconnection + +## ๐Ÿค Contributing Guidelines + +### Code Style + +**Python:** +- Follow PEP 8 +- Use `black` for formatting: `black .` +- Use `isort` for imports: `isort .` +- Type hints are encouraged + +**TypeScript/Vue:** +- Follow Vue 3 style guide +- Use Prettier for formatting: `npm run format` +- Use ESLint: `npm run lint` + +### Commit Messages + +Use conventional commits: +- `feat:` new features +- `fix:` bug fixes +- `docs:` documentation changes +- `style:` formatting changes +- `refactor:` code refactoring +- `test:` adding tests +- `chore:` maintenance tasks + +Examples: +``` +feat: add power meter support for Wahoo devices +fix: resolve WebSocket connection timeout issue +docs: update installation instructions +``` + +### Pull Request Process + +1. **Fork** the repository +2. **Create** a feature branch: `git checkout -b feature/amazing-feature` +3. **Make** your changes +4. **Add** tests for new functionality +5. **Run** the test suite: `pytest && cd frontend && npm test` +6. **Commit** your changes with conventional commit messages +7. **Push** to your fork: `git push origin feature/amazing-feature` +8. **Open** a Pull Request + +### Pull Request Checklist + +- [ ] Tests pass locally +- [ ] Code follows style guidelines +- [ ] Documentation updated if needed +- [ ] Commit messages follow conventional format +- [ ] No breaking changes (or clearly documented) +- [ ] Frontend builds successfully (`python build.py`) + +## ๐Ÿ› Debugging + +### Common Issues + +**Bluetooth connection problems:** +```bash +# Enable debug mode +peloterm start --debug + +# Check device permissions (Linux) +sudo usermod -a -G dialout $USER +``` + +**Frontend build issues:** +```bash +# Clear node modules and reinstall +cd frontend +rm -rf node_modules package-lock.json +npm install + +# Clear build cache +rm -rf peloterm/web/static/* +python build.py +``` + +**WebSocket connection issues:** +- Check firewall settings +- Verify port 8000 is available +- Try different port: `peloterm start --port 8001` + +### Development Tools + +- **Vue DevTools** browser extension for frontend debugging +- **FastAPI docs** at http://localhost:8000/docs for API testing +- **WebSocket testing** tools for real-time connection debugging + +## ๐Ÿ“š References + +- [FastAPI Documentation](https://fastapi.tiangolo.com/) +- [Vue 3 Documentation](https://vuejs.org/) +- [Chart.js Documentation](https://www.chartjs.org/) +- [Bleak (Bluetooth) Documentation](https://bleak.readthedocs.io/) +- [FIT SDK Documentation](https://developer.garmin.com/fit/overview/) + +### Related Projects + +- [GoldenCheetah](https://github.com/goldencheetah/goldencheetah) - Cycling analytics +- [Endurain](https://github.com/joaovitoriasilva/endurain) - Self-hosted fitness tracking +- [PyCycling](https://github.com/zacharyedwardbull/pycycling) - Python cycling sensors library + +## ๐Ÿ“ž Getting Help + +- **Issues**: Open a GitHub issue for bugs or feature requests +- **Discussions**: Use GitHub Discussions for questions and ideas +- **Discord**: Join our community Discord server (link in README) + +Thank you for contributing to Peloterm! ๐Ÿšดโ€โ™‚๏ธ diff --git a/LICENSE b/LICENSE index b437526..f6c5b03 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 Your Name +Copyright (c) 2025 Andrew Marder Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 8163b72..3286c5b 100644 --- a/README.md +++ b/README.md @@ -1,160 +1,14 @@ # Peloterm -A terminal-based cycling metrics visualization tool with a modern web interface. - -## ๐Ÿ“ Project Structure - -``` -bike/ -โ”œโ”€โ”€ peloterm/ # Python package -โ”‚ โ”œโ”€โ”€ web/ -โ”‚ โ”‚ โ”œโ”€โ”€ static/ # Built Vue files (auto-generated) -โ”‚ โ”‚ โ””โ”€โ”€ server.py # FastAPI backend -โ”‚ โ”œโ”€โ”€ devices/ # Bluetooth device handlers -โ”‚ โ”œโ”€โ”€ cli.py # Terminal interface -โ”‚ โ””โ”€โ”€ ... # Other Python modules -โ”œโ”€โ”€ frontend/ # Vue 3 web interface -โ”‚ โ”œโ”€โ”€ src/ -โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Vue components -โ”‚ โ”‚ โ”œโ”€โ”€ composables/ # Reusable logic -โ”‚ โ”‚ โ””โ”€โ”€ types/ # TypeScript definitions -โ”‚ โ”œโ”€โ”€ package.json -โ”‚ โ””โ”€โ”€ vite.config.ts -โ”œโ”€โ”€ build.py # Build frontend โ†’ Python package -โ”œโ”€โ”€ dev.py # Development server runner -โ””โ”€โ”€ pyproject.toml # Python package configuration -``` - -## ๐Ÿš€ Quick Start - -### Development Mode (Hot Reload) -```bash -# Run both Vue dev server + FastAPI backend -python dev.py -``` -- Vue UI: http://localhost:5173 (with hot reload) -- FastAPI: http://localhost:8000 - -### Production Mode -```bash -# Build frontend and run production server -python build.py -python dev.py prod -``` -- Production server: http://localhost:8000 - -### Frontend Only -```bash -cd frontend -npm install -npm run dev -``` - -## ๐Ÿ›  Development Workflow - -### 1. Frontend Development -```bash -# Terminal 1: Run backend -python -m peloterm.web.server - -# Terminal 2: Run frontend with proxy -cd frontend -npm run dev -``` - -### 2. Building for Production -```bash -# Build frontend into Python package -python build.py - -# Verify build -python dev.py prod -``` - -### 3. One-Command Development -```bash -# Runs both servers together -python dev.py -``` - -## ๐Ÿ— Architecture - -### Backend (Python) -- **FastAPI** web server with WebSocket support -- **Bluetooth** device communication -- **Real-time** metrics processing -- **Configuration** management - -### Frontend (Vue 3) -- **Component-based** architecture -- **TypeScript** for type safety -- **Chart.js** for real-time visualizations -- **Responsive** design -- **Hot reload** development - -### Build Process -1. Vue builds optimized production files -2. Files are automatically placed in `peloterm/web/static/` -3. FastAPI serves the built files -4. Single Python command runs everything - -## ๐Ÿ“ฆ Distribution - -The build process creates a self-contained Python package: -- All frontend assets bundled into the package -- No separate frontend server needed in production -- Single `pip install` for end users - -## ๐ŸŽฏ Features - -- **Real-time Metrics**: Power, speed, cadence, heart rate -- **Interactive Charts**: Historical data visualization -- **Responsive Design**: Works on desktop and mobile -- **Resizable Panels**: Customizable layout -- **Dark Theme**: Easy on the eyes -- **WebSocket Updates**: Low-latency data streaming - -## ๐Ÿ”ง Configuration - -Configure iframe URL and metrics in the web interface or via config files. - -## ๐Ÿ“ฑ Web Interface - -The Vue frontend provides: -- Real-time cycling metrics display -- Interactive Chart.js visualizations -- Resizable video panel -- Mobile-responsive design -- Dark theme matching terminal aesthetic - -## ๐Ÿงช Testing - -```bash -# Frontend tests -cd frontend -npm run test:unit - -# Python tests -pytest -``` - -## ๐Ÿ“ˆ Performance - -- **Optimized builds** with Vite -- **Tree-shaking** removes unused code -- **Asset optimization** and caching -- **Efficient reactivity** with Vue 3 +A cycling metrics application that connects to Bluetooth sensors to display real-time performance data while you ride. Supports embedding compatible streaming content (like Jellyfin) in the built-in media player using HTML iframes. When you're done, easily save and upload your rides to Strava. ## Features -- Real-time BLE sensor connection with concurrent device scanning -- Modern web-based UI with configurable video integration (YouTube by default) -- Support for multiple sensor types -- Easy-to-use command line interface -- Automatic device reconnection if connection is lost -- Smart listening mode that waits for you to turn on devices - no more timing issues! -- **Automatic ride recording with FIT file generation** -- **Interactive Strava upload during shutdown** +- Real-time BLE sensor connection (heart rate, power, cadence, speed) +- Modern web-based UI with configurable video integration +- Automatic ride recording with FIT file generation +- Interactive Strava upload +- Smart listening mode - turn on devices when you're ready ## Installation @@ -162,138 +16,30 @@ pytest pip install peloterm ``` -## Usage +## Quick Start -First, scan for available Bluetooth sensors in your area: +1. **First time setup - scan for your sensors:** + ```bash + peloterm scan + ``` + This saves your device addresses to a config file, so you only need to do this once. -```bash -peloterm scan -``` - -This will show all available BLE devices and help you set up your configuration file with the correct sensor IDs. - -### Starting Your Session - -```bash -peloterm start -``` - -**Perfect for devices that auto-sleep quickly!** By default, peloterm now uses smart listening mode: -- Shows you which devices it's waiting for -- Lets you turn on your devices when you're ready -- Connects to all devices concurrently as they become available -- Automatically starts monitoring once all devices are connected -- **Records your ride data automatically** - -**Example workflow:** -1. Run `peloterm start` -2. See the list of devices it's waiting for -3. Turn on your heart rate monitor, cadence sensor, and trainer -4. Watch as each device connects in real-time -5. Start your workout once all devices are connected! -6. **Press Ctrl+C when done - you'll be prompted to save and upload your ride** - -### Recording and Strava Integration - -When you stop Peloterm (Ctrl+C), you'll be prompted with: - -1. **๐Ÿ’พ Save this ride as a FIT file?** - Save your ride data -2. **๐Ÿ“ Enter a name for your ride** - Optional custom name -3. **๐Ÿšด Upload this ride to Strava?** - Direct upload to Strava -4. **Activity details** - Name and description for Strava +2. **Start your ride:** + ```bash + peloterm start + ``` -If Strava isn't set up yet, you'll be guided through the setup process automatically. +3. **Turn on your devices** when prompted and start cycling! -### Strava Setup (Optional) - -To set up Strava integration ahead of time: - -```bash -peloterm strava setup -``` - -This will guide you through: -1. Creating a Strava API application -2. Authorizing Peloterm to upload activities -3. Storing your credentials securely - -### Other Strava Commands - -```bash -# Test your Strava connection -peloterm strava test - -# List all recorded rides -peloterm strava list - -# Upload a specific ride file -peloterm strava upload ride_file.fit --name "Epic Mountain Climb" -``` +4. **Press Ctrl+C when done** to stop the session. -### Command Options +## Web Interface -The `start` command supports these options: - -- `--config PATH` - Use a specific configuration file -- `--timeout 60` - Set connection timeout in seconds (default: 60) -- `--debug` - Enable debug output -- `--web/--no-web` - Enable/disable web UI (default: enabled) -- `--port 8000` - Set web server port -- `--duration 30` - Set target ride duration in minutes -- `--no-recording` - Disable automatic ride recording - -Examples: -```bash -# Standard ride with recording -peloterm start - -# Disable recording (monitoring only) -peloterm start --no-recording - -# Use debug mode to troubleshoot connections -peloterm start --debug - -# Listen for devices with 2-minute timeout -peloterm start --timeout 120 -``` - -## File Formats - -When recording rides, Peloterm generates **FIT files** which are: -- โœ… **Compact**: Binary format, much smaller than TCX/GPX -- โœ… **Complete**: Supports all cycling metrics (power, cadence, heart rate, speed) -- โœ… **Compatible**: Native format for Garmin devices and widely supported -- โœ… **Strava-optimized**: Best format for uploading to Strava - -FIT files are saved to `~/.peloterm/rides/` and can be uploaded to Strava or imported into other cycling apps. - -## Development - -To set up the development environment: - -```bash -# Clone the repository -git clone https://github.com/yourusername/peloterm.git -cd peloterm - -# Create a virtual environment -python -m venv venv -source venv/bin/activate # On Windows: venv\Scripts\activate - -# Install dependencies -pip install -e ".[dev]" -``` - -### Running Tests - -To run the test suite: - -```bash -pytest -``` +When you run `peloterm start`, a web interface opens at http://localhost:8000 with: +- Real-time cycling metrics +- Interactive chart +- Configurable video panel (Jellyfin by default) -## References +## Contributing -- https://github.com/goldencheetah/goldencheetah -- https://github.com/joaovitoriasilva/endurain -- https://github.com/zacharyedwardbull/pycycling \ No newline at end of file +Want to contribute? Check out our [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, project structure, and how to submit pull requests. diff --git a/frontend/src/components/MetricCard.vue b/frontend/src/components/MetricCard.vue index 7a4b711..c20a257 100644 --- a/frontend/src/components/MetricCard.vue +++ b/frontend/src/components/MetricCard.vue @@ -1,7 +1,6 @@