FIT File Faker¶
This application allows you to easily modify FIT files to make them appear to come from a Garmin device (70+ modern devices supported, including Edge 1050, Fenix 8, Forerunner 965, and more) and upload them to Garmin Connect using the garth library. The FIT editing is done using Stages Cycling's fit_tool library.
Support This Project
If FIT File Faker saves you time or enhances your training workflow, consider buying me a coffee ☕. Your support helps maintain and improve this project!
Additionally, it can be run in a "monitor" mode that will watch a folder for new FIT files and will automatically edit/upload them as they are produced. One potential application of this mode is to have the tool auto-start on the computer that you use for indoor training, so rides are automatically uploaded to Garmin Connect when you finish.
Feature walkthrough¶
Overview of FIT File Faker features and commands
Overview¶
The primary motivation for this tool came from the fact that that TrainingPeaks Virtual (previously indieVelo) does/did not support automatic uploading to Garmin Connect. The files can be manually uploaded after the fact, but since they are not "from Garmin", they will not be used to calculate Garmin's Training Effect, which is used for suggested workouts and other features, especially if you have a watch or cycling computer that uses these features.
By changing the FIT file to appear to come from a Garmin device, those features are enabled.
Use Cases
Other users have reported using this tool to edit FIT files produced by:
- Zwift: Upload to Garmin Connect so activities count towards badges and challenges
- TrainingPeaks Virtual: Enable Garmin's Training Effect calculations
- MyWhoosh: Similar compatibility benefits
- Hammerhead Karoo: Enhanced Garmin Connect integration
- COROS Dura: Enhanced Garmin Connect integration
Contributors¶
- jat255: Primary author
- benjmarshall: bug fixes, monitor mode, and other improvements
- Kellett: support for Zwift FIT files
- lrybak: support for Hammerhead Karoo files
- dermarzel: support for MyWhoosh files
Installation¶
Requirements
Python 3.12 or higher is required. If your system Python is older, use pyenv or uv to manage locally installed versions.
This tool works cross-platform on Windows, macOS, and Linux (primarily developed on Linux).
If you have uv installed:
This installs the tool and makes fit-file-faker available on your PATH.
If you have pipx installed:
This installs the tool and makes fit-file-faker available on your PATH.
Install manually using pip in a virtual environment:
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
pip install fit-file-faker
The pip package installs a script named fit-file-faker that should be available on your path when the virtual environment is activated.
For development, clone the repo and use uv:
git clone https://github.com/jat255/Fit-File-Faker.git
cd Fit-File-Faker
uv sync # Installs all dependencies
Pre-commit hooks:
The project uses pre-commit to run code quality checks. After cloning and running uv sync:
This automatically runs ruff check and ruff format on staged files before each commit.
Run hooks manually on all files:
Configuration¶
As of version 2.0.0, FIT File Faker now supports multi-profile configuration, allowing you to manage multiple Garmin accounts and trainer apps. See the Multi-Profile Guide for comprehensive documentation.
Multi-Profile Format¶
{
"profiles": [
{
"name": "tpv",
"app_type": "tp_virtual",
"garmin_username": "user@work.com",
"garmin_password": "secret123",
"fitfiles_path": "/Users/josh/TPVirtual/abc123/FITFiles",
"manufacturer": 1,
"device": 3122,
"serial_number": 1234567890,
"software_version": 975
},
{
"name": "zwift",
"app_type": "zwift",
"garmin_username": "personal@gmail.com",
"garmin_password": "secret456",
"fitfiles_path": "/Users/josh/Documents/Zwift/Activities",
"manufacturer": 1,
"device": 4061,
"serial_number": 2362467083,
"software_version": 2922
}
],
"default_profile": "tpv"
}
Profile Management
Use the interactive profile manager to create and manage profiles:
Creating a new profile with the interactive menu
This supports:
- Multiple Garmin accounts with isolated credentials
- Multiple trainer apps (TPV, Zwift, MyWhoosh)
- Auto-detection of FIT file directories
- Customizable device simulation (Edge 830, Edge 1030, Tacx, etc.)
- Profile-specific monitoring and uploads
Single Profile (Legacy Format)¶
For backward compatibility, the tool still supports the legacy single-profile format:
{
"garmin_username": "username",
"garmin_password": "password",
"fitfiles_path": "C:\\Users\\username\\Documents\\TPVirtual\\0123456789ABCDEF\\FITFiles"
}
Automatic Migration
When you first run v2.0.0+, legacy configs are automatically migrated to the multi-profile format with a "default" profile.
Device Simulation¶
By default, FIT File Faker modifies files to appear as if they came from a Garmin Edge 830. However, each profile can be configured to simulate a different Garmin device.
Supported Target Devices¶
The tool supports simulating activities from 70+ modern Garmin GPS devices, including bike computers like the Edge 840, 1050, etc., multisport watches like the ForeRunner and Fenix series, and others.
Two-Level Device Selection
During profile creation or editing, the tool uses a curated two-level menu system:
Level 1: Shows 11 common devices grouped by category (bike computers, watches)
Level 2: Access 70+ devices via "View all devices" option
This makes the most common devices easily accessible while maintaining access to the full device catalog if you want to simulate a particular device.
Customizing Device Simulation¶
When creating or editing a profile via --config-menu, you'll be prompted:
If you select Yes, you can:
- Choose from common devices - Curated list of 11 popular devices
- View all devices - Access full catalog of 70+ devices organized by category
- Enter a custom numeric device ID - Allows you to specify a custom "device id" in the resulting FIT file; this can allow you to match your FIT files to a real Garmin device that you may already have on your account
- Enter a custom serial number/Unit ID - Allows you to specify the unique device that the FIT file will appear to have been written by. This is important for enabling certain features on Garmin Connect (see next section).
Custom Device IDs
If you enter a numeric device ID that's not in the registry, the tool will show a warning but still create/update the profile. This allows using newer Garmin devices or less common models.
⚠️ Important: Device Serial Numbers/Unit IDs¶
For Garmin Connect to correctly recognize an activity as coming from a specific device (which affects Training Status, challenges, badges, and other features), both the device ID and serial number (Unit ID) must match a valid Garmin device. This is a bit confusing on Garmin's implementation, since they call the value "serial number" in the FIT file, but it actually needs to be your device's Unit ID, not the serial number. To find the Unit ID, you can look either on your device (may vary depending on your device) or in the Garmin Connect app:
Garmin Connect app¶
Finding your device's Unit ID in the Garmin Connect Android app
Go to "Devices → [Your Device] → System → About" to see the Unit ID
On an Edge device¶
Finding your device's Unit ID on an Edge 1040 device
Go to "Menu → System → About → Copyright Info" to see the Unit ID
Why This Matters¶
Garmin Connect uses server-side validation to ensure that (so far as we know):
- The device product ID (e.g., Edge 1050, Fenix 8) is legitimate
- The Unit ID is valid for that specific device type
- The combination of device ID + Unit ID represents a real device
If the Unit ID doesn't match the device type, Garmin Connect may:
- Not apply Training Effect calculations correctly
- Not count the activity toward challenges or badges
- Not update Training Status or training load metrics
- Display the activity with incorrect device information
Recommendations¶
Option 1: Use Your Real Garmin Device Unit ID (Recommended)
If you own a Garmin device and want your activities to count properly for all Garmin Connect features:
- Find your device's Unit ID:
- On the device: Settings → About → Copyright Info → Unit ID
- On Garmin Connect: Device settings page
- On the device packaging or receipt
- During profile setup, choose to customize the serial number
- Enter your actual device's Unit ID as the serial number
- Select the matching device model (e.g., if you have an Edge 830, select Edge 830)
Option 2: Accept Limited Functionality
If you don't own a Garmin device or don't need full Garmin Connect integration:
- The tool will generate a random serial number automatically
- Activities will upload successfully to Garmin Connect
- Basic activity data (distance, time, power, heart rate) will display correctly
- However, advanced features may not work as expected
What We Don't Know¶
The mapping of Unit ID ranges to specific device models is proprietary Garmin information and not publicly documented. This means:
- We cannot automatically generate valid Unit IDs/serial numbers for specific devices
- Random Unit IDs/serial numbers may or may not be accepted by Garmin Connect
- The only guaranteed way to ensure full functionality is to use a real device's Unit ID
Usage¶
Command-line Options¶
To see all available options:
usage: fit-file-faker [-h] [--profile PROFILE] [--list-profiles] [--config-menu] [--show-dirs] [-u] [-ua] [-p] [-m] [-d] [-v] [input_path]
Tool to add Garmin device information to FIT files and upload them to Garmin Connect. Currently, only FIT files produced by TrainingPeaks Virtual (https://www.trainingpeaks.com/virtual/) and Zwift
(https://www.zwift.com/) are supported, but it's possible others may work.
positional arguments:
input_path the FIT file or directory to process. This argument can be omitted if the 'fitfiles_path' config value is set (that directory will be used instead). By default, files will just be
edited. Specify the "-u" flag to also upload them to Garmin Connect.
options:
-h, --help show this help message and exit
--profile PROFILE specify which profile to use (if not specified, uses default profile)
--list-profiles list all available profiles and exit
--config-menu launch the interactive profile management menu
--show-dirs show the directories used by Fit File Faker for configuration and cache
-u, --upload upload FIT file (after editing) to Garmin Connect
-ua, --upload-all upload all FIT files in directory (if they are not in "already processed" list)
-p, --preinitialize preinitialize the list of processed FIT files (mark all existing files in directory as already uploaded)
-m, --monitor monitor a directory and upload all newly created FIT files as they are found
-d, --dryrun perform a dry run, meaning any files processed will not be saved nor uploaded
-v, --verbose increase verbosity of log output
Basic Usage¶
The default behavior loads a given FIT file and outputs a file named path_to_file_modified.fit that has been edited and can be manually imported to Garmin Connect:
If a directory is supplied rather than a single file, all FIT files in that directory will be processed in the same way.
Upload to Garmin Connect¶
Multi-Profile Usage¶
FIT File Faker v2.0.0+ supports multiple profiles for different Garmin accounts and trainer apps.
Profile Selection¶
# Use a specific profile
fit-file-faker --profile zwift -ua
fit-file-faker -p tpv -u ride.fit
# List all profiles
fit-file-faker --list-profiles
# Launch interactive profile manager
fit-file-faker --config-menu
# Show directories used by FIT File Faker
fit-file-faker --show-dirs
Editing an existing profile configuration
Profile Selection Priority¶
- Explicit
--profileargument - Default profile (marked with ⭐)
- Interactive prompt (if multiple profiles exist)
- Error if no profiles configured
Credential Isolation¶
Each profile has isolated Garmin credentials stored in profile-specific directories: - .garth_tpv/ for TPV profile - .garth_zwift/ for Zwift profile - etc.
Verbose Output¶
The -v flag can be used (with any of the other options) to provide more debugging output:
Example output:
[12:38:33] INFO Activity timestamp is "2024-05-21T17:15:48" app.py:84
DEBUG Record: 1 - manufacturer: 255 ("DEVELOPMENT") - product: 0 - garmin app.py:55
product: None ("BLANK")
DEBUG Modifying values app.py:87
DEBUG New Record: 1 - manufacturer: 1 ("GARMIN") - product: 3122 - garmin app.py:55
product: 3122 ("GarminProduct.EDGE_830")
DEBUG Record: 14 - manufacturer: 32 ("WAHOO_FITNESS") - product: 40 - garmin app.py:55
product: None ("BLANK")
DEBUG Modifying values app.py:97
DEBUG New Record: 14 - manufacturer: 1 ("GARMIN") - product: 3122 - garmin app.py:55
product: 3122 ("GarminProduct.EDGE_830")
[12:38:34] DEBUG Using stored Garmin credentials from ".garth" directory app.py:118
[12:38:35] INFO ✅ Successfully uploaded "path_to_file.fit" app.py:137
"Upload All" and "Monitor" Modes¶
Upload All¶
The --upload-all option will search for all FIT files either in the directory given on the command line, or in the one specified in the fitfiles_path config option. The script will:
- Compare the files found to a list of files already seen (stored in that directory's
.uploaded_files.jsonfile) - Edit them
- Upload each to Garmin Connect
The edited files will be written into a temporary file and discarded when the script finishes running, and the filenames will be stored into a JSON file so they are skipped the next time the script is run.
Monitor Mode¶
The --monitor option automates the upload all function by watching the filesystem in the specified directory for any new FIT files. It will continue running until the user interrupts the process by pressing ctrl-c.
Example output when a new file named new_fit_file.fit is detected:
$ fit-file-faker --monitor /home/user/Documents/TPVirtual/0123456789ABCEDF/FITFiles
[14:03:32] INFO Using path "/home/user/Documents/TPVirtual/ app.py:561
0123456789ABCEDF/FITFiles" from command line input
INFO Monitoring directory: "/home/user/Documents/TPVirtual/ app.py:367
0123456789ABCEDF/FITFiles"
[14:03:44] INFO New file detected - "/home/user/Documents/TPVirtual/ app.py:94
0123456789ABCEDF/FITFiles/new_fit_file.fit"; sleeping for
5 seconds to ensure TPV finishes writing file
[14:03:50] INFO Found 1 files to edit/upload app.py:333
INFO Processing "new_fit_file.fit" app.py:340
INFO Processing "/home/user/Documents/TPVirtual app.py:202
sync/0123456789ABCEDF/FITFiles/new_fit_file.fit"
[14:03:58] INFO Activity timestamp is "2025-01-03T17:01:45" app.py:223
[14:03:59] INFO Saving modified data to "/tmp/tmpsn4gvpkh" app.py:250
[14:04:00] INFO Uploading modified file to Garmin Connect app.py:346
[14:04:01] INFO Uploading "/tmp/tmpsn4gvpkh" using garth app.py:295
^C[14:04:46] INFO Received keyboard interrupt, shutting down monitor app.py:372
Pre-initializing Uploaded Files
If your TrainingPeaks Virtual user data folder already contains FIT files which you have previously uploaded to Garmin Connect using a different method, you can pre-initialize the list of uploaded files to avoid any possibility of uploading duplicates.
Use the --preinitialize option to process a directory (defaults to the configured TrainingPeaks Virtual user data directory) and add all files to the list of previously uploaded files:
After this, any use of the --upload-all or --monitor options will ignore these pre-existing files.
Already Uploaded Files¶
Duplicate Detection
If a file with the same timestamp already exists on the Garmin Connect account, Garmin will reject the upload. This script will detect that and output:
Troubleshooting¶
If you run into problems, please create an issue on the GitHub repo.
Viewing Configuration Directories
Use fit-file-faker --show-dirs to see:
- Configuration file location
- Cache directory location
- Garmin credential directories for each profile
- Executable paths
This can be helpful when troubleshooting configuration or credential issues.
Note
As this is a side-project provided for free (as in speech and beer), support times may vary 😅.
Next Steps¶
- Learn about the development workflow and testing
- Check the changelog for recent updates
- View the project on GitHub
- Install from PyPI
Disclaimer¶
The use of any registered or unregistered trademarks owned by third-parties are used only for informational purposes and no endorsement of this software by the owners of such trademarks are implied, explicitly or otherwise. The terms/trademarks Garmin, indieVelo, TrainingPeaks, TrainingPeaks Virtual, Garmin Connect, Stages Cycling, MyWhoosh, Hammerhead Karoo, COROS Dura, Zwift, and any others are used under fair use doctrine solely to facilitate understanding.
Likewise, the software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.
Logo¶
The application logo was generated primarily using AI tools. If you would like to contribute a better, custom-designed logo, we would welcome pull requests! Please feel free to open a GitHub issue or submit a PR with logo design suggestions.