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.
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
- Python 3.8+
- Node.js 16+
- Git
-
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 Python dependencies:
pip install -e ".[dev]" -
Install frontend dependencies:
cd frontend npm install cd ..
For most development work, use the unified development server:
# Run both Vue dev server + FastAPI backend
python dev.pyThis provides:
- Vue UI: http://localhost:5173 (with hot reload)
- FastAPI: http://localhost:8000
- Automatic proxy setup between frontend and backend
For frontend-focused work:
# Terminal 1: Run backend
python -m peloterm.web.server
# Terminal 2: Run frontend with proxy
cd frontend
npm run devFor backend-focused work:
# Run just the FastAPI server
python -m peloterm.web.server# Build frontend into Python package
python build.py
# Test production build
python dev.py prod- 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 interfacepeloterm/web/server.py- Web server and APIpeloterm/devices/- Bluetooth device handlerspeloterm/strava/- Strava integrationpeloterm/recording/- Ride recording and FIT file generation
- 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 componentsfrontend/src/composables/- Reusable logicfrontend/src/types/- TypeScript definitions
- Vue builds optimized production files using Vite
build.pycopies files topeloterm/web/static/- FastAPI serves the built files as static assets
- Single Python command runs everything in production
# Run all Python tests
pytest
# Run with coverage
pytest --cov=peloterm
# Run specific test file
pytest tests/test_devices.pycd 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# Test the full build process
python build.py
python dev.py prod
# Verify http://localhost:8000 works correctlyThe build process creates a self-contained Python package:
- All frontend assets bundled into the package
- No separate frontend server needed in production
- Single
pip installfor end users - Automatic static file serving via FastAPI
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
Peloterm includes comprehensive Strava integration:
# 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"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/
Create a .env file in the project root:
DEBUG=true
LOG_LEVEL=debug
STRAVA_CLIENT_ID=your_client_id
STRAVA_CLIENT_SECRET=your_client_secretDevice configuration is stored in ~/.peloterm/config.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
}
}- Tree-shaking removes unused code
- Asset optimization and caching
- Efficient reactivity with Vue 3 Composition API
- WebSocket for low-latency data updates
- Async/await for non-blocking operations
- Efficient Bluetooth scanning and connection
- Minimal memory footprint for long rides
- Graceful error handling and reconnection
Python:
- Follow PEP 8
- Use
blackfor formatting:black . - Use
isortfor 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
Use conventional commits:
feat:new featuresfix:bug fixesdocs:documentation changesstyle:formatting changesrefactor:code refactoringtest:adding testschore:maintenance tasks
Examples:
feat: add power meter support for Wahoo devices
fix: resolve WebSocket connection timeout issue
docs: update installation instructions
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Add tests for new functionality
- Run the test suite:
pytest && cd frontend && npm test - Commit your changes with conventional commit messages
- Push to your fork:
git push origin feature/amazing-feature - Open a Pull Request
- 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)
Bluetooth connection problems:
# Enable debug mode
peloterm start --debug
# Check device permissions (Linux)
sudo usermod -a -G dialout $USERFrontend build issues:
# 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.pyWebSocket connection issues:
- Check firewall settings
- Verify port 8000 is available
- Try different port:
peloterm start --port 8001
- 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
- FastAPI Documentation
- Vue 3 Documentation
- Chart.js Documentation
- Bleak (Bluetooth) Documentation
- FIT SDK Documentation
- GoldenCheetah - Cycling analytics
- Endurain - Self-hosted fitness tracking
- PyCycling - Python cycling sensors library
- 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! 🚴♂️