Voron Spoolman Setup — Filament Inventory, Weight Tracking, and Moonraker Integration
Klipper Filament Software
Managing filament inventory across multiple Voron printers is a pain. Which spools are open? How much filament is left? Which brand gave you that perfect print last week? Spoolman solves this with a self-hosted database that tracks every spool in your workshop, integrates with Moonraker for automatic weight tracking, and even triggers alerts when a spool is running low. This guide covers installation, configuration, integration with Mainsail/Fluidd, and advanced automation macros. Last updated: May 2025.
What is Spoolman?
Spoolman is an open-source filament inventory management system. It runs as a Docker container or standalone Python service and provides:
- Spool database: Track brand, material, color, weight, diameter, and cost per spool
- Weight-based tracking: Connect a scale or use manual entry to track remaining filament
- Moonraker integration: Automatically associate spools with prints and update weight from filament usage
- REST API: Query and update spool data from macros, scripts, or other tools
- Multi-printer support: One Spoolman instance can serve all your Vorons
Installation
Option 1: Docker (Recommended)
The easiest way to run Spoolman is via Docker. If you don't have Docker installed on your Raspberry Pi or host:
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
# Log out and back in for group changes to take effect
# Create Spoolman directory
mkdir -p ~/spoolman
cd ~/spoolman
# Download docker-compose.yml
curl -O https://raw.githubusercontent.com/Donkie/Spoolman/main/docker-compose.yml
# Start Spoolman
docker compose up -d
# Check status
docker compose logs -f
Spoolman will be available at http://your-printer-ip:7912. The web UI lets you add spools, define filament types, and view usage history.
Option 2: Manual Python Installation
For systems without Docker, install Spoolman directly:
# Install system dependencies
sudo apt install python3 python3-venv python3-pip git
# Clone Spoolman
cd ~
git clone https://github.com/Donkie/Spoolman.git
cd Spoolman
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Run database migrations
flask db upgrade
# Start Spoolman
gunicorn -w 4 -b 0.0.0.0:7912 app:app
# (optional) Run as a systemd service for auto-start
sudo nano /etc/systemd/system/spoolman.service
Create the systemd service file:
[Unit]
Description=Spoolman filament manager
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/Spoolman
ExecStart=/home/pi/Spoolman/venv/bin/gunicorn -w 4 -b 0.0.0.0:7912 app:app
Restart=always
[Install]
WantedBy=multi-user.target
# Enable and start
sudo systemctl enable spoolman
sudo systemctl start spoolman
Moonraker Integration
Moonraker can communicate with Spoolman to automatically track which spool is being used and deduct filament from its remaining weight. Add this to your moonraker.conf:
[spoolman]
# Enable Spoolman integration
enabled: True
# Spoolman server URL
server: http://localhost:7912
# Sync Spoolman data with Moonraker on startup
sync_on_startup: True
# The Moonraker client name shown in Spoolman
client_name: Voron V2.4
After adding this, restart Moonraker:
sudo systemctl restart moonraker
When Moonraker starts, it will connect to Spoolman and sync the spool database. You can now see your spools in Mainsail or Fluidd under the Spoolman panel.
Using Spoolman in Mainsail / Fluidd
Mainsail v2.12+ and Fluidd v1.30+ have built-in Spoolman support. If you're running an older version, update:
# Update Mainsail via KIAUH or manually
# Using KIAUH:
cd ~/kiauh
./kiauh.sh
# Select option 4 (Update) then select Mainsail
# Or update Fluidd:
cd ~/fluidd
./update.sh
Once updated, go to the Spoolman panel (Mainsail: top toolbar icon, Fluidd: left sidebar). You'll see:
- All spools in your inventory with remaining weight
- Active spool currently loaded for the print
- History of which spools were used in which prints
- Low-spool warnings when remaining filament is below threshold
Automatic Spool Selection via G-Code
The real power comes from automating spool selection. Instead of manually picking a spool in the UI, you can embed the spool ID in your slicer's start G-code. Each spool in Spoolman has a unique ID (visible in the URL when viewing a spool: http://printer:7912/spool/5).
In your slicer's "Start G-code", add:
SET_SPOOLMAN_SPOOL ID=5
This tells Moonraker to associate this print with spool ID 5. Moonraker will then track filament usage during the print and automatically deduct from the spool's remaining weight.
Even better, you can use custom parameters in your PRINT_START macro:
[gcode_macro PRINT_START]
gcode:
{% set BED_TEMP = params.BED|default(100) %}
{% set EXTRUDER_TEMP = params.EXTRUDER|default(250) %}
{% set SPOOL_ID = params.SPOOL_ID|default(0) %}
# Set spool if an ID was provided
{% if SPOOL_ID|int > 0 %}
SET_SPOOLMAN_SPOOL ID={SPOOL_ID}
{% endif %}
# ... rest of PRINT_START ...
In your slicer, pass the spool ID:
PRINT_START BED=110 EXTRUDER=245 SPOOL_ID=5
Weight Tracking — How Accurate Is It?
Spoolman tracks filament usage by monitoring extruder movement. Klipper reports exactly how many millimeters of filament have been pushed through the extruder, which Moonraker converts to grams using the filament density (typically 1.24 g/cm^3 for PLA, 1.27 for PETG, 1.04 for ABS).
Weight_used = filament_length * cross_section_area * density
= length_mm * (pi * (diameter_mm/2)^2) * density_g_per_mm3
This method is surprisingly accurate — within 1-3% of actual weight for most prints. The main source of error is purge filament and wiping that happens before the print starts (which isn't always counted). To compensate, Spoolman lets you set a tare weight for your spools.
Setting Initial Spool Weight
When adding a new spool, you have three options:
- Manufacturer weight: Enter the labeled weight (e.g., 1000g). Spoolman will track usage from this starting point. Less accurate because the spool itself weighs 200-250g.
- Net filament weight: Weigh the entire spool on a scale, then subtract the spool weight. For a 1kg spool, this is typically 750-800g of actual filament.
- Total spool weight: Enter the gross weight. Spoolman shows remaining total weight (filament + spool). Set
spool_weightin Spoolman to subtract automatically.
For best accuracy, weigh each spool when you receive it and enter the net filament weight in Spoolman. This eliminates guesswork.
Low Spool Alerts
Spoolman can warn you when a spool is getting low. Configure thresholds in the Spoolman web UI or via the API:
# Set alert thresholds (in grams of remaining filament)
# Via Spoolman web UI:
# Go to Settings -> Alerts
# Low spool threshold: 200g
# Critical spool threshold: 50g
When a threshold is crossed, Moonraker can trigger a notification. Add this to your macro set:
[gcode_macro _SPOOLMAN_ALERT]
gcode:
{% set state = printer.spoolman %}
{% if state.remaining_weight|float < 50 %}
M117 WARNING: Spool {state.spool_name} critically low!
UPDATE_DISPLAY MSG="FILAMENT LOW - CHANGE NOW"
{% elif state.remaining_weight|float < 200 %}
M117 NOTE: Spool {state.spool_name} running low
{% endif %}
Call this macro periodically during a long print:
[delayed_gcode CHECK_SPOOL]
initial_duration: 3600 # Check after 1 hour
gcode:
_SPOOLMAN_ALERT
UPDATE_DELAYED_GCODE ID=CHECK_SPOOL DURATION=3600
Multi-Printer Setup
One Spoolman instance can serve multiple printers. Each printer registers as a separate client. Install Moonraker on each printer with:
[spoolman]
enabled: True
server: http://192.168.1.100:7912 # IP of the Spoolman host
client_name: Voron_Trident
# On another printer:
[spoolman]
enabled: True
server: http://192.168.1.100:7912
client_name: Voron_V2_4
Each printer's Moonraker instance connects to the same Spoolman database. Spools can be moved between printers manually or via the API. The usage history shows which printer used which spool and when.
Advanced: Spoolman API Macros
Spoolman's REST API lets you build custom automation. Here are useful macro examples:
List All Spools
[gcode_macro SPOOLMAN_LIST]
gcode:
RUN_SHELL_COMMAND CMD=spoolman_list
RESPOND MSG="Check console for spool list"
[shell_command spoolman_list]
command: curl -s http://localhost:7912/api/v1/spool | python3 -c "
import sys, json
data = json.load(sys.stdin)
for s in data['items']:
print(f"ID:{s['id']} {s['filament']['name']} - {s['remaining_weight']}g/{s['initial_weight']}g")
"
timeout: 5.0
Create a New Spool via Macro
[gcode_macro SPOOLMAN_ADD]
gcode:
# Usage: SPOOLMAN_ADD NAME="Overture PLA Pro" MATERIAL=PLA WEIGHT=1000
{% set NAME = params.NAME|default("Unknown") %}
{% set MATERIAL = params.MATERIAL|default("PLA") %}
{% set WEIGHT = params.WEIGHT|default(1000) %}
RUN_SHELL_COMMAND CMD=spoolman_add NAME={NAME} MATERIAL={MATERIAL} WEIGHT={WEIGHT}
RESPOND MSG="Spool created"
[shell_command spoolman_add]
command: curl -s -X POST http://localhost:7912/api/v1/spool -H "Content-Type: application/json" -d '{"filament_id": 1, "initial_weight": WEIGHT, "remaining_weight": WEIGHT}'
timeout: 5.0
Backup and Restore
Spoolman stores data in a SQLite database (Docker: ~/spoolman/data/spoolman.db, manual: ~/Spoolman/instance/spoolman.db). Back it up regularly:
# Backup script
#!/bin/bash
BACKUP_DIR=~/printer_data/config/backups/spoolman
mkdir -p $BACKUP_DIR
cp ~/spoolman/data/spoolman.db $BACKUP_DIR/spoolman_$(date +%Y%m%d).db
# Keep only last 7 backups
ls -t $BACKUP_DIR/spoolman_*.db | tail -n +8 | xargs -r rm
# Restore
cp $BACKUP_DIR/spoolman_20250501.db ~/spoolman/data/spoolman.db
docker compose restart
Add the backup to your nightly cron job or include it in your Klipper backup routine.
Troubleshooting
- Moonraker can't connect to Spoolman: Verify Spoolman is running:
curl http://localhost:7912/api/v1/health. Check firewall rules — Spoolman listens on port 7912. If running in Docker, ensurenetwork_mode: hostor correct port mapping. - Weight not updating after print: Check Moonraker logs for Spoolman-related errors:
grep -i spoolman ~/printer_data/logs/moonraker.log. The extruder must have a validrotation_distancefor accurate filament tracking. - Spoolman web UI not loading: For Docker:
docker compose logs. For manual install: check if gunicorn is running and port 7912 is listening. Restart the service. - SET_SPOOLMAN_SPOOL command not found: Your Moonraker version may not support Spoolman. Update to Moonraker v0.8.0 or newer. Verify
[spoolman]section is inmoonraker.conf. - Duplicate spools in database: Spoolman doesn't auto-deduplicate. Use the web UI to archive or delete duplicates. Consider adding a barcode/QR scanning workflow for new spools.
Example: Complete Workflow
1. Receive a new spool of filament
2. Weigh it on a kitchen scale → 1250g total (spool ≈ 250g)
3. Enter 1000g as initial weight in Spoolman
4. Label the spool with its Spoolman ID (print a QR code!)
5. In your slicer, add SET_SPOOLMAN_SPOOL ID=5 to start G-code
6. Slice and print as normal
7. After print, Moonraker deducts the used filament automatically
8. Check Spoolman dashboard to see remaining weight
9. When spool hits 200g, Spoolman alerts you to order more
With this workflow, you'll never start a print with insufficient filament again. Combined with Moonraker's filament tracking and Spoolman's inventory management, you have complete visibility into your filament usage across all your Voron printers.