The print-dialog spool dropdown built its option label from
sp.filament.vendor (the whole vendor object) instead of
sp.filament.vendor.name, so options rendered as "#5 [object Object] PLA+
(1000g)". The sibling builder in the slot card already uses .vendor.name;
this aligns the two.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The AMS-slot -> Spoolman-spool persistence never worked: KobraXBridge
referenced `config_loader` in both the load (__init__) and save
(handle_kx_spoolman_set_active) paths, but the module alias is `env_loader`
(kobrax_moonraker_bridge.py:32). The resulting NameError was swallowed by a
bare `except`, so the map was neither loaded on startup nor written on change
- it only appeared to persist.
The map also lived in a single global `[spoolman] slot_spools` key, so on a
multi-printer bridge two AMS units clobbered each other's mapping (same class
of bug as #74/#75 for filament profiles).
- config_loader: add list_spool_map()/save_spool_map(printer_id) using a
per-printer `[spoolman_<id>]` section with read-fallback to the legacy
global key, mirroring _filament_section/list_filament_profiles. The global
`[spoolman]` section keeps server/sync_rate.
- bridge: load via config_loader.list_spool_map(self._printer_id); persist via
save_spool_map(..., self._printer_id); surface failures via log.warning
instead of a silent except.
- _build_mmu_object: emit real gate_spool_id from the per-printer map (was
hardcoded [-1]*num_gates) so Happy-Hare/OrcaSlicer can show the bound spool.
- config.ini.example: document the [spoolman] section.
- tests: tests/test_spoolman_slot_map.py (per-printer isolation, persistence
round-trip, server/sync_rate preservation, parser robustness).
Verified on a 2-printer bridge: after restart KX1 loads its spools and KX2
loads its own, isolated; a real multicolor print deducted per slot (white spool
1.02g vs 0.98g slicer estimate) against the correct printer's spools.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drucker interpretiert ams_box_mapping als geordnete Liste (Eintrag N = TN).
Bei Drucken die T0 nicht nutzen wurden die Einträge um 1 verschoben,
sodass T2 (rot) auf den Slot von T3 (weiß) zeigte.
Fixes#78
Bei Multicolor-Drucken mit nicht bei 0 startenden Paint-Indizes (T2, T3...)
wurde paint_index als 0,1,2... statt als tatsächlicher GCode-T-Index gesendet.
Drucker hat dadurch die falschen Slots für die falschen Farben verwendet.
Fixes#78
- Slot color editor: Pickr HSV color picker (offline, served from lib/),
recent swatches (up to 16, localStorage), copy color from other slot
- Unified axes control panel: XY+Z merged, shared step size + custom mm input
- Language selector moved from header to Settings → Appearance
- Filament mismatch detection blocks Upload-and-Print on material mismatch,
slot mapper opens automatically
- Spoolman spool-per-slot assignment in AMS status tab and Filaments settings
- Fix: Spoolman sync rate label — 0=end of print, not disabled (Issue #76)
- Fix: lib/ assets served by bridge static handler for offline use
- UI: global unified select + input styling, set-row labels match modal-field
Per-printer [filament_profiles_<id>] sections so configuring one printer no
longer overwrites another (read-fallback to the legacy global section keeps
single-printer setups unchanged). Dropdown/switch links now navigate to each
printer's own bridge_url. Adds pytest coverage and a CHANGELOG entry.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Merged XY + Z axis cards into single Axes Control panel with shared step
size row and free-text mm input; Home XY/Z placed below respective pads;
Home All + Motors Off centred at bottom
- Language selector removed from header bar, now only in Settings → Appearance
- Upload-and-Print blocked on GCode/AMS material mismatch; slot mapper dialog
opens automatically with mismatch warning highlighting affected slots
- Spoolman spool-per-slot assignment: dropdown in AMS status tab per kachel,
dedicated card in Filaments settings tab with save button
- nightly.yml: NIGHTLY_CHANGELOG.md takes precedence over auto-generated
commit log when present; CI uses it as release body verbatim
Keine manuelle VERSION-Pflege mehr für Nightlies. CI ermittelt:
- letzten Stable-Tag (z.B. v0.9.27)
- nächste Patch-Version (0.9.28)
- laufenden Nightly-Counter aus vorhandenen Tags (nightly-0.9.28-nightlyN)
VERSION-Datei im Repo bleibt auf dem letzten Stable, wird vom CI
für jeden Nightly-Build überschrieben und committet.
CHANGES.md war statisch und zeigte immer denselben alten Stand.
Jetzt: git log <prev-tag>..HEAD, chore-Nightly-Commits rausgefiltert,
englisch, nur echte feat/fix/docs-Commits.