Brings the Spoolman writer up to parity with the internal-inventory
side, which has had this fallback since #1119. When a Bambu print
starts without a retrievable .gcode.3mf on the printer (typically an
unsaved BambuStudio project, subtask_name='Untitled'), Spoolman no
longer silently skips the print's filament consumption.
- ActivePrintSpoolman.filament_usage now nullable; new tray_remain_start
column captures per-slot {remain, tray_uuid} at print start.
- store_print_data: always snapshots remain, even when 3MF is present
(mirrors usage_tracker.on_print_start), so partial-3MF prints can also
fall back per-slot.
- report_usage: 3MF path stays primary; new _report_remain_delta_for_slots
handles slots the 3MF didn't cover via delta * Filament.weight / 100,
resolving the spool via the existing slot-assignment table.
- _report_partial_usage: same fallback for aborted no-3MF prints.
#1119 invariant preserved: per-slot, per-print, gated on a valid
start/current remain AND a resolvable Spoolman spool. Uses curated
Filament.weight (not MQTT's unreliable tray_weight) — same trick the
internal-inventory side uses.
Mid-print spool swap detected via tray_uuid mismatch → slot skipped.
Double-charge prevented via handled_global_tray_ids dedup.
Implement accurate per-filament usage tracking for Spoolman integration,
similar to OpenSpoolman v0.3.0. This replaces the previous single-spool
reporting with multi-material aware tracking.
Features:
- Parse G-code from 3MF files at print start to build per-layer,
per-filament cumulative extrusion maps
- Store tracking data in new `active_print_spoolman` database table
(survives server restarts for long prints)
- Report accurate partial usage when prints fail/cancel based on
actual layer progress and G-code data
- Add "Disable AMS Weight Sync" setting to prevent AMS percentage-based
weight estimates from overwriting Spoolman's granular tracking
- Add "Report Partial Usage for Failed Prints" toggle (only shown when
weight sync is disabled)
- Use Spoolman's filament density instead of defaults for mm-to-grams
conversion
- Prefer tray_uuid over tag_uid for spool identification