Skip to content

feat: two-colour AMS jobs, remote filament load; resume confirms RUNNING - #5

Merged
voska merged 1 commit into
mainfrom
feat/filament-swap-multicolor
Oct 9, 2026
Merged

voska merged 1 commit into
mainfrom
feat/filament-swap-multicolor

Conversation

@voska

@voska voska commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

Summary

Two-colour printing without anyone at the printer, plus a remote colour change at a pause:

  • Two-filament jobs with an automatic AMS change at a layer height.
    • slice --filament P1 --color C1 --filament P2 --color C2 --filament-change-z Z writes the change the way Bambu Studio's layer slider stores it (--load-custom-gcodes, a ToolChange in MultiAsSingle mode), so the G-code carries M620 S1A / T1 / M621 S1A at that layer and the AMS swaps by itself.
    • slice reads the change back from the G-code and exits 11 without touching the output dir if Studio didn't place it. Studio drops a ToolChange silently when the mode doesn't fit.
    • preflight / print send take one --slot per filament. Every per-filament gate runs against that filament's own slot, and ams_mapping becomes e.g. [3, 0].
  • filament load --slot S --confirm swaps the toolhead to another AMS slot over LAN (print.ams_change_filament). It works only while PAUSE or IDLE/FINISH/FAILED (an allowlist). When paused, the toolhead must hold an AMS filament and the slot must hold the same material. It exits 0 only once the printer reports S in the toolhead with the change finished.
  • Fix: print resume used to exit 0 three seconds after the ack even if the printer was still paused. It now waits for RUNNING (--wait, default 30s, must be positive; otherwise exit 14). It refuses during a filament change, and on X1-series printers when the AMS reports an empty toolhead. That's the only place tray_now 255 is verified to mean empty.

Contract

  • Additive only:
    • status.ams_status
    • slice filament_changes / prime_tower / filament_presets, and per-filament model_g / waste_g / nozzle_temp / nozzle_temp_range
    • preflight slots / tray_ids, and filament on gate rows of multi-filament jobs
    • job filament_changes
  • Single-filament jobs are unchanged. Against skunkworks, print send --dry-run --slot A4 on the same file gives a byte-identical MQTT payload and FTPS plan with v0.2.0 and with this branch, and the same gate names and statuses. Only the single_filament detail text differs.
  • Exit codes: print resume can now exit 14 (not RUNNING in time) or 9 (mid-change / empty toolhead) where it used to exit 0.

Verification

  • make ci passes (fmt-check, golangci-lint 0 issues, vet, go test -race, build).
  • New tests run on recorded fixtures: a real G-code pause report, and trimmed real 1- and 2-filament Bambu Studio 02.08 slices with no serials. A test run against main shows print resume --confirm exiting 0 with "state_after": "PAUSE".
  • Real slice: the 27-layer button sliced white (Generic PLA) through Z 4.0 and black (PLA Matte) above it with Bambu Studio 02.08.02.61. Read back with unzip | awk, the only in-print tool change is M620 S1A / T1 / M621 S1A at layer 21 (Z 4.2), plus the end T255. There's no pause. Filament 1 16.98 g (16.02 + 0.97 waste), filament 2 3.06 g (2.89 + 0.18), 44 min 43 s.
  • Live and read-only: against skunkworks, print send --dry-run --slot A4 --slot A1 gives PASS, with one WARN (A4 has no RFID, so its remaining filament is unknown) and ams_mapping [3, 0]. With --slot A4 alone it exits 9; with the same slot twice it exits 2. Nothing was uploaded or published.
  • Not verified on hardware: a real two-colour print (ams_mapping [3, 0]), and the Go filament load itself. The identical payload was verified on this printer from bambu-op.

- slice: repeatable --filament/--color and --filament-change-z write a
  layer-height ToolChange (--load-custom-gcodes, MultiAsSingle), so the AMS
  swaps from the G-code with no pause. The change is read back from the
  G-code; a slice without it exits 11 and never reaches the output dir.
- preflight/print send: one --slot per filament; per-filament gates run
  against each filament's own slot; ams_mapping maps each filament to its
  tray. Single-filament payloads are unchanged.
- filament load --slot S --confirm: print.ams_change_filament while paused
  or idle; exit 0 only once the printer reports S in the toolhead with the
  change over.
- fix: print resume exited 0 while the printer was still paused; it now
  waits for RUNNING (--wait) and refuses mid-change or with an empty
  toolhead.
- job: per-filament settings via filament_self_index /
  filament_extruder_variant; filament changes parsed from the G-code.
@voska
voska merged commit 513c7c0 into main Oct 9, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant