Syncs Spoolman filament data into Moonraker's lane_data namespace so
OrcaSlicer automatically sees which filament is loaded in each tool slot.
Works with toolchangers (KTC, StealthChanger), IDEX, and any multi-extruder Klipper setup. Fully open-ended tool count — 1 tool through 12+ lanes, no configuration required.
Hands off automatically if Happy Hare or AFC is already managing
lane_data — safe to install on any printer.
- On startup, checks Moonraker's
lane_data.sourcekey - If unclaimed (or claimed by
spoolman), takes ownership and syncs - Queries Moonraker for the actual extruder count (open-ended)
- Fetches active spools from Spoolman, maps
Location = T0/T1/…to slots - Pushes all tool slots to
lane_data.tools— empty entry for unloaded slots - Polls Spoolman every 30 s — re-syncs when filament data changes
- Listens to Moonraker's WebSocket — re-syncs when Klippy restarts
- Reconnects both WebSockets automatically with exponential backoff
- Python 3.10+
aiohttp(installed automatically byinstall.sh)- Moonraker and Spoolman accessible on your local network
cd ~/printer_data/config # or wherever you want it
git clone https://github.com/Broncosis/spoolman-lane-sync
cd spoolman-lane-sync
./install.shEdit config:
nano .envStart:
sudo systemctl start spoolman-lane-syncWatch logs:
journalctl -u spoolman-lane-sync -fAdd this to your moonraker.conf to get over-the-air updates via Fluidd or
Mainsail:
[update_manager spoolman-lane-sync]
type: git_repo
path: ~/spoolman-lane-sync
origin: https://github.com/broncosis/spoolman-lane-sync.git
primary_branch: main
install_script: install.sh
managed_services: spoolman-lane-syncAdjust path to match where you cloned the repo.
You also need to allow Moonraker to manage the service. Add one line to
~/printer_data/moonraker.asvc:
spoolman-lane-sync
Then restart Moonraker:
sudo systemctl restart moonrakerThe update manager will appear in Fluidd / Mainsail's update panel and will restart the service automatically after each update.
In Spoolman, set the Location field on each spool to its tool number:
| Spoolman Location | Result in OrcaSlicer |
|---|---|
T0 |
Tool 0 (first tool) |
T1 |
Tool 1 |
T2 |
Tool 2 |
| (blank) | Slot left empty |
Dry Box |
Ignored |
Location is case-insensitive (t0 and T0 both work).
Slots with no spool assigned get an empty entry — OrcaSlicer knows the slot exists but has nothing loaded.
OrcaSlicer matches filaments from lane_data using two optional extra fields on the filament (not the spool) in Spoolman. Set these under Extra Fields in the Spoolman filament editor.
| Spoolman extra field | Example value | Purpose |
|---|---|---|
orca_filament_id |
GFL99 |
OrcaSlicer system preset short code — used for built-in generic presets (PLA, PETG, ABS, etc.). See table below. |
orca_setting_id |
eSun PLA+ - 80 |
Exact name of your OrcaSlicer filament preset — used to match custom user-created profiles. |
Common orca_filament_id codes:
| Code | OrcaSlicer preset | Material |
|---|---|---|
GFL99 |
Generic PLA | PLA |
GFG99 |
Generic PETG | PETG |
GFB99 |
Generic ABS | ABS |
GFB98 |
Generic ASA | ASA |
GFN99 |
Generic PA (Nylon) | PA |
GFU99 |
Generic TPU | TPU |
GFL98 |
Generic PLA-CF | PLA |
GFL03 |
eSUN PLA+ | PLA |
Which field to set:
- For filaments well-covered by a generic preset — set
orca_filament_idonly. - For custom or brand-specific presets you've created in OrcaSlicer — set
orca_setting_idto the exact preset name as it appears in OrcaSlicer. - Setting both is fine and forward-compatible.
Note:
setting_idmatching in OrcaSlicer for Moonraker lane_data is a pending feature request (OrcaSlicer #13006). The script already writessetting_idto lane_data so it will work automatically once OrcaSlicer support lands.
Important — material name must be exact uppercase:
OrcaSlicer's material matching is case-sensitive. The Material field on your Spoolman filament must use uppercase exactly as OrcaSlicer expects:
| Correct | Wrong |
|---|---|
PLA |
Pla, pla |
PETG |
Petg, petg |
ABS |
Abs, abs |
ASA |
Asa |
TPU |
Tpu |
Mixed-case material names will cause OrcaSlicer to fall back to the wrong preset.
# Each tool slot is its own key — check T0 and T1 for example:
curl -s 'http://localhost:7125/server/database/item?namespace=lane_data&key=0' \
| python3 -m json.tool
curl -s 'http://localhost:7125/server/database/item?namespace=lane_data&key=1' \
| python3 -m json.toolExpected output (5-tool toolchanger, T0 and T1 loaded):
{
"result": {
"namespace": "lane_data",
"key": "0",
"value": { "material": "PLA", "color": "FF3D00", "vendor": "eSun", "name": "eSun PLA+ - 80", "filament_id": "GFL99", "setting_id": "eSun PLA+ - 80", "lane": "0" }
}
}{
"result": {
"namespace": "lane_data",
"key": "1",
"value": { "material": "PETG", "color": "0047AB", "vendor": "Bambu", "name": "PETG HF", "filament_id": "GFG99", "setting_id": "", "lane": "1" }
}
}All settings go in .env (copied from .env.example by install.sh):
| Variable | Default | Description |
|---|---|---|
MOONRAKER_URL |
http://localhost:7125 |
Moonraker base URL |
SPOOLMAN_URL |
http://localhost:7912 |
Spoolman base URL |
MOONRAKER_API_KEY |
(blank) | API key if Moonraker auth is on |
LOG_LEVEL |
INFO |
DEBUG / INFO / WARNING |
Set LOG_LEVEL=DEBUG to see every sync and WebSocket event in the logs.
This service checks the lane_data.source key in Moonraker's database before
doing anything:
- If the key is absent or set to
spoolman→ takes ownership and syncs - If the key is set to
happy_hare,afc, or anything else → exits immediately
To take over from a previous system (e.g. if you switched from Happy Hare to a toolchanger):
curl -s -X DELETE \
'http://localhost:7125/server/database/item?namespace=lane_data&key=source'
sudo systemctl restart spoolman-lane-syncsudo systemctl stop spoolman-lane-sync
sudo systemctl disable spoolman-lane-sync
sudo rm /etc/systemd/system/spoolman-lane-sync.service
sudo systemctl daemon-reload"lane_data is owned by another system" Another service (Happy Hare, AFC) wrote the source key first. See Coexistence section above.
"Sync skipped: …"
Spoolman or Moonraker wasn't reachable at sync time. The service retries
automatically via the WebSocket reconnect loop. Check URLs in .env.
OrcaSlicer shows wrong/no filament
- Verify the
Locationfield in Spoolman is exactlyT0,T1, etc. - Check the
lane_data.toolskey with the curl command above - Set
LOG_LEVEL=DEBUGand checkjournalctl -u spoolman-lane-sync -f
Service won't start
journalctl -u spoolman-lane-sync -n 50Usually a Python version or aiohttp issue. Re-run ./install.sh.