Transform your Raspberry Pi into a smart USB drive for Tesla dashcam recordings with remote access, web-based file management, and automated maintenance.
🚨 IMPORTANT - CHANGES FOR EXISTING USERS 🚨
Significant changes have been made to the application. All configruration is now centralized in a single
config.yamlfile. Please read the Configuration section for details on updating your setup. You may want to restart from a clean Raspberry PI OS image and follow the Installation steps again to ensure everything is set up correctly. If you do not want to do that, ensure that the config.yaml file is created and updated with your desired settings and then run thesetup_usb.shscript again to apply the new configuration structure.The web interface now runs on PORT 80 (standard HTTP) instead of port 5000.
- Old URL:
http://<pi-ip>:5000❌- New URL:
http://<pi-ip>✅ (no port needed!)This change enables the captive portal feature - when you connect to the TeslaUSB WiFi network, your device will automatically open the web interface without typing any URL.
TeslaUSB creates a dual-drive USB gadget that appears as two separate USB drives to your Tesla:
- TeslaCam Drive: Large exFAT drive for dashcam and sentry recordings
- LightShow Drive: Smaller FAT32 drive for lock chimes, custom wrap images, and light shows with read-only optimization
Key Benefits:
- Remote access to dashcam footage without physically removing storage
- Web interface for browsing videos, managing chimes, managing light shows, managing custom wrap images and monitoring storage (with light/dark mode)
- Automatic cleanup policies to manage disk space
- Scheduled chime changes for holidays, events, or automatic rotation
- Offline access point for in-car web access when WiFi is unavailable
⚠️ Personal Project NoticeThis is a personal project built for my own use. You are welcome to fork the code and make your own changes or updates. Please be aware:
- The Git repository may update frequently with new features and changes
- Bugs may be introduced into the main branch without extensive testing
- Bug fixes will be worked on as time permits, but no timelines or guarantees are provided
- You have access to the source code - if something breaks, you can attempt to fix it yourself
- This project is provided as-is with no warranty or support obligations
- Dual-Drive USB Gadget: Two independent filesystems (TeslaCam + LightShow) with optimized performance
- Two Operating Modes:
- Present Mode: Active USB gadget for Tesla recording
- Edit Mode: Network access via Samba shares for file management
- Web Interface: Browser-based control panel accessible at
http://<pi-ip>(port 80) - Captive Portal: Automatic splash screen when connecting to TeslaUSB WiFi network
- Browse all TeslaCam folders (RecentClips, SavedClips, SentryClips)
- Auto-generated video thumbnails
- In-browser multi-camera event player with 6 camera angles
- HUD Overlay Toggle: Switch between two playback modes:
- Stream Mode (default): Instant video playback with minimal bandwidth - perfect for quick video review
- Overlay Mode: Downloads full video to display real-time telemetry overlay with speed, gear selection (P/R/N/D), steering wheel angle, accelerator/brake pedal position, turn signals, and Autopilot status
- Toggle preference is remembered across sessions
- Bandwidth optimization: Partial downloads are cached and resumed when switching modes
- Download all camera views for an event as a zip file
- Delete entire events (Edit mode only)
- Storage analytics with folder-by-folder breakdown
- Upload WAV or MP3 files (automatically converted to Tesla-compatible format)
- Organized chime library with preview and download
- Volume normalization presets (Broadcast, Streaming, Loud, Maximum)
- Chime Groups: Organize chimes by theme (Holidays, Funny, Seasonal, etc.)
- Random Selection on Boot: Automatically pick a different chime from your selected group each time the device boots
- Scheduled chime changes:
- Weekly schedules (specific days/times)
- Date-based schedules
- Holiday schedules (Christmas, Easter, Thanksgiving, etc.)
- Recurring rotation (every 15min to 12 hours, or on boot)
- Upload FSEQ and MP3/WAV files
- Grouped display (pairs sequence + audio files)
- Preview MP3/WAV tracks in browser
- Delete complete light show sets
- Upload PNG files for Tesla's Paint Shop 3D vehicle visualization
- Thumbnail previews of all uploaded wraps
- Automatic validation (512-1024px dimensions, max 1MB, PNG only)
- Supports up to 10 custom wraps at a time
- Drag-and-drop upload with progress indicator
- Storage Cleanup: Age, size, or count-based policies per folder
- Boot Cleanup: Optional automatic cleanup before presenting to Tesla
- On-Demand Thumbnails: Instant generation via PyAV as you browse (cached for 7 days)
- Chime Scheduler: Checks every 60 seconds for scheduled changes
- Hardware Watchdog: Automatic system recovery on hangs or crashes
- Samba Shares: Windows/Mac/Linux file access in Edit mode
- Offline Access Point: Automatic fallback AP when WiFi unavailable (in-car web access)
- WiFi Roaming: Automatic switching between access points with the same SSID for optimal signal strength (mesh networks and WiFi extenders)
Note: This project has only been tested on Raspberry Pi Zero 2 W. Other OTG-capable models should work but are untested.
- Tesla Software: Version 2025.44.25.1 or later (2025 Holiday Update) required for event thumbnails, SEI telemetry data, and multi-camera event structure
- Raspberry Pi Zero 2 W (tested and recommended) - Small form factor, low power, powered directly from Tesla USB port
- Other Raspberry Pi models with USB OTG capability should work (Pi 4, Pi 5, Compute Modules) - untested
- 128GB+ microSD card (for OS, dashcam storage, and light shows)
- Raspberry Pi OS (64-bit) Desktop - Debian "Trixie"
- Internet connection for initial setup
For USB gadget projects like TeslaUSB, the Raspberry Pi Zero family and Compute Modules are the best choice. Raspberry Pi 4 and 5 offer OTG support, but their higher power requirements can be an issue. Raspberry Pi A, B, 2B, 3B, and 3B+ do NOT support OTG (host mode only).
For detailed information, see the official Raspberry Pi whitepaper: Using OTG mode on Raspberry Pi SBCs
| Model | OTG Support | Notes |
|---|---|---|
| Raspberry Pi Zero / Zero W / Zero 2 W | ✅ Yes | Fully supported on USB data port |
| Raspberry Pi 4 | USB-C port in device mode | |
| Raspberry Pi 5 | USB-C port in device mode | |
| Raspberry Pi A/B/2B/3B/3B+ | ❌ No | Only host mode - not compatible |
| Raspberry Pi Compute Module 1-3 | ✅ Yes | Exposed on OTG pins |
| Raspberry Pi Compute Module 4 | ✅ Yes | micro-USB on CM4 IO board |
* Raspberry Pi 4 and 5 draw power from the host via USB cable, so there may be limitations on available current due to their higher power requirements.
Note for Pi Zero 2 W users: Setup automatically optimizes memory by disabling unnecessary desktop services and enabling 1GB swap. This ensures stable operation on the 512MB RAM platform.
- USB-C power + data splitter adapters (search "USB-C OTG with PD charging")
- Powering the Pi via GPIO pins from a separate car charger (advanced)
- Using a larger SD card instead of external USB storage to avoid power budget issues
- Flash Raspberry Pi OS (64-bit) Desktop using Raspberry Pi Imager
- Configure OS customization settings:
- Set hostname (e.g.,
cybertruckusb) - Enable SSH with password authentication
- Set username/password (default:
pi) - Configure WiFi credentials
- Set timezone and keyboard layout
- Set hostname (e.g.,
- Insert microSD into Pi and boot (wait 2-3 minutes)
- Verify SSH access:
ssh pi@cybertruckusb.local
git clone https://github.com/mphacker/TeslaUSB.git
cd TeslaUSB
chmod +x setup_usb.sh
sudo ./setup_usb.shThe setup script will:
- Install required packages (parted, dosfstools, python3-flask, python3-av, samba, hostapd, dnsmasq, ffmpeg)
- Optimize memory for low-RAM systems (disable desktop services, enable swap)
- Configure USB gadget kernel modules and hardware watchdog
- Create dual disk images (TeslaCam + LightShow)
- Set up Samba shares and web interface with on-demand thumbnail generation
- Configure systemd services with auto-restart on failure
- Create
/Chimeslibrary and migrate existing lock chimes
Open http://<pi-ip-address> or http://<hostname>.local in your browser (port 80 - no port number needed).
Alternatively, connect to the TeslaUSB WiFi network and the captive portal will automatically open.
Connect the Pi to your Tesla's USB port:
- Pi Zero 2 W: Use USB port labeled "USB" (not "PWR")
- Pi 4/5: Use USB-C port
Tesla will detect two separate USB drives automatically.
The TeslaUSB device only runs when the car is awake. When your Tesla enters sleep mode, USB ports are powered off and the Raspberry Pi shuts down.
To keep your vehicle awake for extended management sessions:
- Turn on climate control
- Enable "Dog Mode" or "Camp Mode" from the climate screen
- Connect to the TeslaUSB web interface and manage your lock chimes, light shows, or videos
- When finished, disable Dog/Camp Mode and turn off climate control
- The vehicle will return to sleep, powering off the USB ports
Note: For quick operations like viewing videos or changing a lock chime, the car typically stays awake long enough without needing Dog Mode. Use Dog/Camp Mode only for longer management sessions.
Present USB Mode (default on boot):
- Pi appears as USB drives to Tesla
- Drives mounted read-only locally at
/mnt/gadget/part1-ro,/mnt/gadget/part2-ro - Web interface: View/play only (no editing)
- Samba shares disabled
Edit USB Mode:
- USB gadget disconnected
- Drives mounted read-write at
/mnt/gadget/part1,/mnt/gadget/part2 - Web interface: Full file management (upload, delete, organize)
- Samba shares active for network access
Switch modes via web interface or command line:
sudo /home/pi/TeslaUSB/present_usb.sh # Activate Present mode
sudo /home/pi/TeslaUSB/edit_usb.sh # Activate Edit modeSamba Shares (Edit mode only):
\\<pi-ip-address>\gadget_part1- TeslaCam drive\\<pi-ip-address>\gadget_part2- LightShow drive- Default credentials: username =
pi, password =tesla
Offline Access Point with Captive Portal: When WiFi is unavailable, the Pi automatically creates a fallback access point:
- SSID:
TeslaUSB(configurable inconfig.yaml) - Password:
teslausb1234(change this!) - IP:
192.168.4.1 - Captive Portal: Automatically opens web interface when you connect (no URL needed!)
- Manual access:
http://192.168.4.1orhttp://teslausb(port 80) - Control from web UI: Force start/stop AP or leave in auto mode
- Start AP Now: Forces AP on until reboot or manually stopped
- Stop AP: Returns to auto mode (AP only starts if WiFi fails)
- Change credentials in
config.yamlbefore first use - Note: After clicking "Start AP Now" or "Stop AP" buttons, the status may not update immediately. Wait 10-20 seconds and refresh the page to see the current state.
Settings Tab:
- Switch between Present USB and Edit USB modes
- Configure offline access point (SSID, password, auto/manual mode)
- View network status and Samba share information
Videos Tab:
- Browse all TeslaCam folders with auto-generated thumbnails
- Multi-camera event player with 6 camera angles
- Download all camera views as zip file
- Delete entire events (Edit mode only) - deletes all camera views for the session
Lock Chimes Tab:
- Upload WAV/MP3 files (auto-converted to Tesla format)
- Preview all chimes with in-browser audio player
- Set any chime as active
LockChime.wav - Built-in audio editor with waveform visualization:
- Trim audio with visual waveform display
- Volume normalization presets (Broadcast, Streaming, Loud, Maximum)
- Real-time duration and file size preview
- Save as new file or replace existing
- Schedule automatic chime changes (weekly, date, holiday, recurring)
Light Shows Tab:
- Upload and manage FSEQ + MP3/WAV light show files
- Grouped display for matching files
- Preview MP3/WAV audio in browser
- Delete complete light show sets
Wraps Tab:
- Upload PNG files for custom Tesla vehicle wraps (Paint Shop → Wraps)
- Thumbnail preview gallery of all uploaded wraps
- Client-side validation before upload (dimensions, file size, format)
- Download or delete existing wraps
- Requirements: PNG format, 512x512 to 1024x1024 pixels, max 1MB, up to 10 wraps
Analytics Tab:
- Drive usage gauge and folder breakdown
- Video count and size statistics
- Configure cleanup policies (age, size, count-based)
- Preview and execute cleanup operations
All configuration is centralized in a single config.yaml file - edit this file before running setup.
Both bash scripts and the Python web application read from this YAML file, ensuring consistency across the entire system.
# TeslaUSB Configuration File
#
# All paths, settings, and credentials are defined here.
# Both bash scripts and Python web application use this file.
# ============================================================================
# Installation & Paths
# ============================================================================
installation:
gadget_dir: /home/pi/TeslaUSB # Installation directory
target_user: pi # Linux user running services
mount_dir: /mnt/gadget # Mount directory for USB drives
# ============================================================================
# Disk Images
# ============================================================================
disk_images:
cam_name: usb_cam.img # TeslaCam disk image filename
lightshow_name: usb_lightshow.img # LightShow disk image filename
cam_label: TeslaCam # Filesystem label for TeslaCam drive
lightshow_label: Lightshow # Filesystem label for LightShow drive
boot_fsck_enabled: true # Auto-repair filesystems on boot (recommended)
# ============================================================================
# Setup Configuration (used only by setup_usb.sh)
# ============================================================================
# Leave empty ("") for interactive prompts during setup
setup:
part1_size: "" # TeslaCam drive size (e.g., "50G")
part2_size: "" # LightShow drive size (e.g., "10G")
reserve_size: "" # Free space headroom (default: 5G)
# ============================================================================
# Network & Security
# ============================================================================
network:
samba_password: tesla # Samba password (CHANGE THIS!)
web_port: 80 # Web port (80 required for captive portal)
# ============================================================================
# Offline Access Point Configuration
# ============================================================================
offline_ap:
enabled: true # Enable/disable fallback AP
ssid: TeslaUSB # AP network name (CHANGE THIS!)
passphrase: teslausb1234 # WPA2 passphrase 8-63 chars (CHANGE THIS!)
channel: 6 # 2.4GHz channel (1-11)
force_mode: auto # auto, force_on, or force_off
# ============================================================================
# Web Application Configuration
# ============================================================================
web:
secret_key: CHANGE-THIS-TO-A-RANDOM-SECRET-KEY-ON-FIRST-INSTALL
max_lock_chime_size: 1048576 # 1 MiB
max_lock_chime_duration: 10.0 # 10 secondsImportant settings to change before first use:
network.samba_password- Default istesla(change this!)offline_ap.ssid- Default isTeslaUSB(customize for your vehicle)offline_ap.passphrase- Default isteslausb1234(change this!)web.secret_key- Auto-generated on first run, but can be set manually
Optional settings:
disk_images.boot_fsck_enabled- Auto-repair filesystems on boot (default:true, recommended)
After making changes: Restart affected services
sudo systemctl restart gadget_web.service # For web application changes
sudo systemctl restart wifi-monitor.service # For offline AP changesHow it works:
- Bash scripts use
yqto read YAML values - Python web app uses
PyYAMLto load configuration - Single source of truth for all settings
- Comments and structure make configuration clear
cd /home/pi/TeslaUSB
./upgrade.shPulls latest code from GitHub and prompts to run setup. Disk images and configuration are preserved.
cd /home/pi/TeslaUSB
sudo ./cleanup.shRemoves all files, services, and system configuration.
| Service/Timer | Purpose |
|---|---|
gadget_web.service |
Web interface (port 80) with captive portal |
present_usb_on_boot.service |
Auto-present USB on boot with optional cleanup |
chime_scheduler.timer |
Check scheduled chime changes every 60 seconds |
wifi-monitor.service |
Manage offline access point |
watchdog.service |
Hardware watchdog for system reliability |
Common Commands:
# Check service status
sudo systemctl status gadget_web.service
# View logs
sudo journalctl -u gadget_web.service -f
# Restart web interface
sudo systemctl restart gadget_web.service
# Disable auto-present on boot
sudo systemctl disable present_usb_on_boot.serviceThe hardware watchdog automatically reboots the Pi if the system becomes unresponsive. The default configuration is intentionally simple and reliable:
watchdog-device = /dev/watchdog
watchdog-timeout = 60
max-load-1 = 24
realtime = yes
priority = 1
The following options should be avoided on Raspberry Pi Zero 2 W (512MB RAM):
| Setting | Problem |
|---|---|
min-memory = 50000 |
Pi Zero 2 W often has <50MB free during normal operation, triggering unnecessary reboots |
repair-binary = /usr/lib/watchdog/repair |
This file doesn't exist on Raspberry Pi OS |
interval (low values) |
Can cause timing issues with the kernel watchdog |
If your device keeps rebooting in a loop, the watchdog configuration may be too aggressive. To fix:
- Pull the SD card and mount it on another computer
- Edit
cmdline.txton the boot partition and add:systemd.mask=watchdog.service - Boot the Pi and SSH in
- Fix
/etc/watchdog.confto use the simple configuration above - Remove the mask from
cmdline.txtand reboot
Watchdog timeout: Set to 60 seconds to accommodate large disk images (400GB+) which take longer to configure at boot. Smaller images work fine with 15 seconds, but 60 seconds is safe for all configurations.
Web interface not accessible:
# Check service status and logs
sudo systemctl status gadget_web.service
sudo journalctl -u gadget_web.service -fVideos not showing:
- Verify correct mode (Present or Edit, not Unknown)
- Check TeslaCam folder exists on drive 1
- Confirm drive is properly mounted
Samba shares appear empty:
# Force Samba refresh
sudo smbcontrol all close-share gadget_part1
sudo smbcontrol all close-share gadget_part2
sudo systemctl restart smbd nmbdTesla not recognizing new lock chime: Try these steps in order:
- Power cycle Tesla (close doors, walk away 5+ minutes, wake up)
- Switch USB modes (Edit → wait 10s → Present)
- Physical reconnect (unplug Pi, wait 10s, plug back in)
- Tesla reboot (hold both scroll wheels until screen goes black)
Operation in Progress banner stuck:
# Check and remove stale lock file if older than 120 seconds
ls -lh /home/pi/TeslaUSB/.quick_edit_part2.lock
rm /home/pi/TeslaUSB/.quick_edit_part2.lockiOS file upload not working:
- Use Safari on iOS (third-party browsers have restricted file access)
- Desktop browsers work normally regardless of choice
# Web interface logs
sudo journalctl -u gadget_web.service -f
# Chime scheduler logs
sudo journalctl -u chime_scheduler.service -f
# System USB logs
sudo dmesg | grep -i "mass_storage\|gadget"Dual-Drive Architecture:
- Two separate disk images (
usb_cam.imgexFAT,usb_lightshow.imgFAT32) - Sparse files (only use space as needed)
- Presented as dual-LUN USB gadget to Tesla
USB Gadget Implementation:
- Linux
g_mass_storagekernel module vialibcomposite - LUN 0: Read-write (ro=0) for TeslaCam recordings
- LUN 1: Read-only (ro=1) for LightShow/Chimes
Concurrency Protection:
.quick_edit_part2.lockfile prevents race conditions- 10-second timeout, 120-second stale lock detection
- All services and scripts respect lock state
Performance Optimizations:
- Boot time: ~14 seconds on Pi Zero 2 W (detects existing RW mount at boot to skip unnecessary remount operations)
- Configuration loading: Single YAML parse with secure eval (properly quoted values prevent command injection)
- Web UI responsiveness: Settings page loads in ~0.4s (optimized from 133s through batched configuration reads)
- Memory efficiency: Desktop services disabled, 1GB swap enabled for stable operation on 512MB RAM
All screenshots shown in dark mode.






