A professional, dark-themed dashboard for controlling smart trainers using the FTMS (Fitness Machine Service) protocol via Web Bluetooth. Supports Zwift Hub, Wahoo KICKR, Tacx NEO, Elite, and many more!
π Try it live! (Replace with your GitHub Pages URL after deployment)
- Live power, heart rate, and cadence (RPM) display
- Real-time chart with power, heart rate, and target power
- 2-minute rolling window
- Color-coded metrics
- Cadence calculated from crank revolution data
- Percentage-based intervals - all workouts scale with your FTP
- Six workout types:
- Warmup (50% FTP)
- Endurance (65% FTP)
- Tempo (85% FTP)
- Threshold (100% FTP)
- VO2 Max (120% FTP)
- Cooldown (40% FTP)
- Drag and drop to reorder intervals
- Click to edit intensity percentage and duration
- Visual timeline with color-coded intervals
- Automatic execution - trainer adjusts power automatically
- Save workouts to localStorage with custom names
- Load saved workouts from browser storage
- Export workouts as JSON files
- Import workouts from JSON files
- Share workouts with friends!
- Manual power target slider
- Instant power adjustment
- Connection management
- Ride with friends in real-time using peer-to-peer connections
- Workout sharing - host sends workout to all participants
- Individual FTP scaling - everyone rides at their own intensity
- Real-time metrics - view power, cadence, and FTP for all riders
- Synchronized start - countdown ensures everyone starts together
This app works with any smart trainer that supports FTMS (Fitness Machine Service) via Bluetooth. Tested and confirmed with Zwift Hub and Wahoo Kickr.
Note: Your trainer must support FTMS protocol. Most modern smart trainers (2017+) support this standard.
The app is automatically deployed to GitHub Pages via GitHub Actions.
- Open
index.htmlin a modern browser (Chrome, Edge, or Opera) - Ensure you're using HTTPS or localhost (Web Bluetooth requirement)
- Click Connect to pair with your smart trainer
- Set your FTP in the workout designer
- Start designing and riding!
- Chrome 56+, Edge 79+, or Opera 43+
- Web Bluetooth API support
- HTTPS or localhost (Web Bluetooth security requirement)
-
Create a new GitHub repository
-
Push your code:
git init git add . git commit -m "Initial commit: Zwift Hub Controller" git branch -M main git remote add origin https://github.com/wolfv/cycling-workout git push -u origin main
-
Enable GitHub Pages:
- Go to your repository settings
- Navigate to Pages (left sidebar)
- Under "Build and deployment":
- Source: GitHub Actions
-
Wait for deployment:
- The GitHub Action will automatically run
- Check the Actions tab to see deployment progress
- Once complete, your site will be live at:
https://wolfv.github.io/cycling-workout
-
Update the README with your actual URL
- Enter your FTP (Functional Threshold Power) in the input field at the top of the Workout Designer
- All intervals will automatically scale based on this value
- Click interval buttons to add segments:
- Warmup - Easy spinning
- Endurance - Long steady efforts
- Tempo - Moderate intensity
- Threshold - At FTP
- VO2 Max - High intensity intervals
- Cooldown - Easy recovery
- Drag intervals to reorder them
- Click an interval to edit intensity % and duration
- Click Start Workout
- Your trainer will automatically adjust resistance
- The timeline highlights the current interval
- Click Stop Workout to end early
- Save: Stores workout in browser (persists across sessions)
- Load: Browse and load saved workouts
- Export: Download workout as JSON file
- Import: Load JSON workout files
{
"name": "My Workout",
"ftp": 200,
"intervals": [
{
"type": "warmup",
"name": "Warmup",
"percentage": 50,
"duration": 300
},
{
"type": "threshold",
"name": "Threshold",
"percentage": 100,
"duration": 600
}
],
"created": "2025-10-26T10:00:00.000Z"
}index.html- Main HTML structurestyle.css- Dark theme stylingftms.js- FTMS protocol handlerchart.js- Real-time canvas chartworkout-designer.js- Workout builder with FTP scalingapp.js- Main application logic
- Chrome 56+, Edge 79+, or Opera 43+
- Web Bluetooth API support
- HTTPS or localhost
- Uses Fitness Machine Service (UUID: 0x1826)
- Control Point characteristic (UUID: 0x2AD9)
- Direct power target commands
- No DirCon wrapper needed
MIT
Built with vanilla JavaScript, Lucide icons, and the Web Bluetooth API.