Replace equal-split with poll-based per-slot accumulation using
loaded_slot from multiColorBox/report:
- _spoolman_attribute_tick(activity_map): called each poll cycle after
both print/report and multiColorBox/report are processed. Attributes
the supplies_usage delta to whichever slot is currently loaded.
Skips attribution during loading/unloading transitions (tool changes
+ purges) so filament consumed during a slot swap is not charged to
the wrong spool.
- _spoolman_unreported(): returns {slot_idx: mm} not yet sent to
Spoolman. Uses per-slot data when available, falls back to equal
split for single-extruder/no-AMS setups where _ams_loaded_slot
stays -1 throughout the print.
- _spoolman_report(): shared fire-and-forget sender used by both
notify_end and sync_midprint, eliminating duplicated loop logic.
Per-slot state (_spoolman_slot_usage, _spoolman_slot_reported,
_spoolman_last_usage) is reset at print start and when spool
assignments change.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds optional Spoolman (https://github.com/Donkie/Spoolman) integration
for live filament consumption tracking.
Config (config.ini [spoolman] section or env vars):
SPOOLMAN_SERVER = http://192.168.x.x:7912
SPOOLMAN_SYNC_RATE = 30 # mid-print sync interval in seconds (0=end only)
How it works:
- Uses supplies_usage from the printer's own MQTT print/report payload —
the printer's cumulative extrusion counter in mm, reset each print.
Discovered via MQTT payload inspection: matches slicer estimate within
~1% for model filament, and also captures the printer's purge/prime
sequence that the slicer doesn't count.
- Reports to Spoolman via PUT /api/v1/spool/{id}/use with use_length (mm),
letting Spoolman convert to weight using the spool's filament profile.
- Accurate for both completed and cancelled prints — no estimation needed.
- For multi-slot prints, total filament is split equally across mapped spools
(v1 approximation; per-slot MQTT breakdown not available).
UI changes:
- Filament assignment dialog gains a Spoolman section (hidden when not
configured): one spool dropdown per assigned AMS slot, loaded async
from GET /kx/spoolman/spools.
- AMS slot display shows a 🧵 #N badge on any slot with a mapped spool.
- Spool assignments persist across prints (sticky until changed).
New API endpoints:
GET /kx/spoolman/status — configured flag, server URL, slot map
GET /kx/spoolman/spools — spool list proxied from Spoolman
POST /kx/spoolman/active-spool — body: {"slot_map": {"0": 42, "1": 17}}
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>