Print from USB Drive
The following guide describes how to facilitate printing G-code files from USB drives that are externally connected to the host computer.
Note:
- This approach requires and/or generally assumes the standard installation of Klipper, as, for example, setup by KIAUH.
- It also assumes the drive to be formatted as FAT32, or exFAT
- Any deviation might require adjusting the settings, especially the path variables.
1. Setup USBmount
WARNING:
- The described process will alter the mounting behavior for USB drives.
- On more complex systems or systems with multiple USB drives, this might lead to changed behavior.
- On regular Single Board Computers (SBC), like a Raspberry Pi, this probably goes largely unnoticed unless one is very familiar with headless Linux systems.
USBmount is a set of shell scripts that cleverly utilizes built-in Linux functions to increase control over the USB mounting process without the need for additional programs or services. As such, it should be quite robust and work on a wide range of different Linux versions.
To install USBmount on Debian-like distributions, log on to the host computer (e.g., via SSH) and follow these simple steps:
wget https://github.com/Sineos/useful_bits/raw/refs/heads/main/Linux/usbmount_0.0.26_all.deb
sudo apt install ./usbmount_0.0.26_all.deb
sudo apt install ntfs-3g exfat-fuse
If one prefers to build it locally, the repository contains the needed instructions to do so.
2. Configure USBmount
To mount the USB drives under the correct user that also runs Klipper and Moonraker, one needs the User-ID and Group-ID of this user. It can be obtained with the following commands:
# User-ID
id -u <your Klipper user here>
# Group-ID
id -g <your Klipper group here (likely the same as the user)>
Note down the result of the above two commands and then execute
sudo nano /etc/usbmount/usbmount.conf
In the usbmount.conf
file, change the following items:
MOUNTPOINTS="/home/<your Klipper user here>/printer_data/gcode/external
/media/usb0 /media/usb1 /media/usb2 /media/usb3
/media/usb4 /media/usb5 /media/usb6 /media/usb7"
MOUNTOPTIONS="sync,noexec,nodev"
FS_MOUNTOPTIONS="-fstype=vfat,rw,uid=1000,gid=1000 -fstype=exfat,rw,uid=1000,gid=1000"
The following changes are needed:
- In
MOUNTPOINTS
, add the folder to Klipper’sprinter_data
folder as the future mount point, e.g.,/home/<your Klipper user here>/printer_data/gcode/external
. It needs to be the first entry, as the mount points are processed in the sequence as listed. - In
MOUNTOPTIONS
, removenoatime,nodiratime
- In
FS_MOUNTOPTIONS
, add the settings shown above, replacing the User-ID obtained asuid
and the Group-ID asgid
(note that both appear twice)
Finally, create the folder as a mount point that is specified in the configuration above:
mkdir ~/printer_data/gcodes/external
3. Ensure Metadata Updates
When the USB drive is mounted, the G-code files will immediately become available in the web interfaces (Mainsail, fluidd, Klipper Screen, etc.), but the metadata and thumbnails will not be updated automatically.
To also ensure this functionality, a small Python script will be called upon a USB mount event that will scan the drive and force an update of the metadata:
sudo wget https://raw.githubusercontent.com/Sineos/useful_bits/refs/heads/main/Linux/90_refresh_meta -O /etc/usbmount/mount.d/90_refresh_meta
sudo chmod u+x /etc/usbmount/mount.d/90_refresh_meta
Edit the script to accommodate for the given setup:
sudo nano /etc/usbmount/mount.d/90_refresh_meta
# The username under which Klipper is running
USERNAME = "<your Klipper user here>"
# Name of the folder below the ROOT_PATH that is used to mount the external drive
EXTERNAL_DRIVE = "external"
4. Test the Setup
The functionality should be executed as soon as a USB drive is connected to the host. The contained G-code files should be shown in the external folder in the web interfaces. To actually show the metadata and thumbnails, a refresh of their file listing is needed.
If it does not work as intended, set VERBOSE="yes"
in the usbmount.conf
file and replug the drive. The relevant information is logged in /var/log/syslog
.
5. Current Limitations
- KlipperScreen seems to only pick up the updated metadata when switching the files’ list from icons to details and back again.
6. Clean Eject (optional)
Since the USB is mounted with the sync
option, no data corruption should happen when simply pulling the drive. Nevertheless, the correct way is to cleanly umount
the drive.
sudo nano /etc/sudoers.d/<your Klipper user here>
Paste the following content into the file and then save it. This will allow calling sudo umount
without being asked for a password:
<your Klipper user here> ALL=(ALL) NOPASSWD:/usr/bin/umount
For calling the umount
command from within the web interfaces, the gcode_shell_command
is needed, which can be installed with KIAUH.
After installing it, add the following macros to the printer.cfg
[gcode_shell_command UMOUNT_EXTERNAL]
command: sudo umount ~/printer_data/gcodes/external
timeout: 2.
verbose: False
[gcode_macro EJECT]
gcode:
RUN_SHELL_COMMAND CMD=UMOUNT_EXTERNAL