diff --git a/NIGHTLY_CHANGELOG.md b/NIGHTLY_CHANGELOG.md index a34c495..492b142 100644 --- a/NIGHTLY_CHANGELOG.md +++ b/NIGHTLY_CHANGELOG.md @@ -1,11 +1,4 @@ ## Changes in this build -- Unified axes control panel: XY and Z merged into one card, shared step size selector (0.1 / 1 / 5 / 10 mm) plus custom mm input field, Home XY/Z buttons placed directly below their respective pads -- Language selector moved from header bar to Settings → Appearance -- Filament mismatch detection: Upload-and-Print is intercepted when GCode material differs from the loaded AMS slot — slot mapper dialog opens automatically to correct the assignment before printing -- Spoolman: assign a spool per AMS slot directly in the AMS status tab (dropdown per slot tile) and in the Filaments settings tab (dedicated assignment card) -- Fix: filament profiles now isolated per printer in multi-printer setups — configuring one printer no longer overwrites the other (PR #75 by @walterioo) -- Fix: printer dropdown and switch link now navigate to each printer's own bridge URL (same-origin, no cross-instance profile bleed) -- Fix: Spoolman sync rate label corrected — 0 means sync at end of print, not disabled (Issue #76) -- Slot color editor: Pickr color picker (HSV wheel + hex input), recent color swatches (up to 16, saved in browser), and "Copy color from slot" dropdown for identical backup spool setup (Issue #73) -- UI: unified dropdown and input field styling across all settings panels +- Fix: wrong filament slot used in multicolor prints when T0 is unused — AMS box mapping now includes placeholder entries for all paint indices so the printer correctly matches T1/T2/T3 tool changes to the right slots (Issue #78) +- Fix: Spoolman spool-slot assignment now persisted to config.ini and restored on bridge restart diff --git a/kobrax_moonraker_bridge.py b/kobrax_moonraker_bridge.py index 0d4e9b2..978bab3 100644 --- a/kobrax_moonraker_bridge.py +++ b/kobrax_moonraker_bridge.py @@ -1601,16 +1601,32 @@ class KobraXBridge: loaded = loaded_slots if loaded is None: loaded = self._select_loaded_slots_for_print(warn_on_empty_default=warn_on_empty_default) - return [ - { - "paint_index": pidx, - "ams_index": self._slot_to_print_ams_index(gidx), - "paint_color": [255, 255, 255, 255], - "ams_color": self._slot_color_rgba(s), - "material_type": s.get("type", "PLA"), - } - for pidx, (gidx, s) in enumerate(loaded) - ] + if not loaded: + return [] + loaded_map = {gidx: s for gidx, s in loaded} + max_idx = max(loaded_map.keys()) + # Drucker interpretiert ams_box_mapping als geordnete Liste (Eintrag N = TN). + # Fehlende Slots müssen als Platzhalter rein, sonst verschiebt sich alles. + result = [] + for i in range(max_idx + 1): + if i in loaded_map: + s = loaded_map[i] + result.append({ + "paint_index": i, + "ams_index": self._slot_to_print_ams_index(i), + "paint_color": [255, 255, 255, 255], + "ams_color": self._slot_color_rgba(s), + "material_type": s.get("type", "PLA"), + }) + else: + result.append({ + "paint_index": i, + "ams_index": self._slot_to_print_ams_index(i), + "paint_color": [255, 255, 255, 255], + "ams_color": [255, 255, 255, 255], + "material_type": "PLA", + }) + return result def _build_assigned_ams_box_mapping(self, assignments: list) -> tuple[list[dict], int, int]: """Build print mapping from UI filament assignments.