Skip to content

Fix AMS mapping never being applied to local (SD-card / LAN) prints - #99

Open
qoncept96 wants to merge 1 commit into
drndos:mainfrom
qoncept96:fix/ams-mapping-local-prints
Open

qoncept96 wants to merge 1 commit into
drndos:mainfrom
qoncept96:fix/ams-mapping-local-prints

Conversation

@qoncept96

@qoncept96 qoncept96 commented Sep 3, 2026 •

Copy link
Copy Markdown

May be relevant to #84, #91 and #90 — I haven't read those threads closely,
so treat that as a guess rather than a claim.

Problem — two bugs that compound

1. The dispatch is gated on a print_type that isn't set yet (:391-397).

if PENDING_PRINT_METADATA and PENDING_PRINT_METADATA.get("complete"):
  if TRACK_LAYER_USAGE:
    if PENDING_PRINT_METADATA.get("print_type") == "local":
      FILAMENT_TRACKER.apply_ams_mapping(...)
    else:
      FILAMENT_TRACKER.set_print_metadata(PENDING_PRINT_METADATA)

print_type is copied from PRINTER_STATE at :260, at the moment the
project_file command arrives — but the printer still reports "idle" there and
only flips to "local" one MQTT message later. So for a local print the
"local" branch never runs and apply_ams_mapping() is never called.

2. The local path then hardcodes an empty mapping (:318).

PENDING_PRINT_METADATA["ams_mapping"] = []

This runs on a later message and clobbers whatever mapping was established from
the project_file payload.

Net effect: using_ams goes False and every layer's usage is attributed to the
external spool (trayUid ending _255_254), which has no spool assigned, so
nothing is deducted in Spoolman. The log line is
Queued <mm> for filament 0 (tray <serial>_255_254 has no assigned spool).

Cloud prints go down a different branch, which is why this isn't visible from
Bambu Studio.

Fix

Call both unconditionally — apply_ams_mapping() already no-ops on an empty
mapping, so it's safe either way — and reuse the printer's own mapping (which
persists in PRINTER_STATE["print"], merged from the project_file payload)
instead of clearing it.

       if TRACK_LAYER_USAGE:
-        if PENDING_PRINT_METADATA.get("print_type") == "local":
-          FILAMENT_TRACKER.apply_ams_mapping(PENDING_PRINT_METADATA.get("ams_mapping") or [])
-        else:
-          FILAMENT_TRACKER.set_print_metadata(PENDING_PRINT_METADATA)
+        FILAMENT_TRACKER.set_print_metadata(PENDING_PRINT_METADATA)
+        FILAMENT_TRACKER.apply_ams_mapping(PENDING_PRINT_METADATA.get("ams_mapping") or [])
-            PENDING_PRINT_METADATA["ams_mapping"] = []
+            PENDING_PRINT_METADATA["ams_mapping"] = PRINTER_STATE["print"].get("ams_mapping") or []

Debugging notes for reviewers

The two bugs look identical in the logs. Grep for Applying AMS mapping: absent
means bug 1; present but usage still landing on ..._255_254 means bug 2.

Also worth knowing: duplicated Parsed N gcode operations lines are normal here,
not two processes — tracking legitimately starts from two code paths.

Testing

Running in production on a LAN-mode P1S (AMS via a BMCU, 4 slots) since 2026-08,
rebased onto main and redeployed mid-print on 2026-09-03. Per-layer deductions
land on the correct spools across filament changes — the log goes from

Queued 142.8mm for filament 0 (tray 01P00C580300948_255_254 has no assigned spool)

to

Consume spool 22 for filament 1 with 155.95155mm (tray_uid=01P00C580300948_0_2)
Consume spool 11 for filament 2 with 382.22458mm (tray_uid=01P00C580300948_0_0)

i.e. real tray UIDs instead of the _255_254 external-spool fallback, with the
weights reflected in Spoolman afterwards.

Caveat on scope: I can only test the local/LAN path. The cloud path now also
calls apply_ams_mapping() where it previously didn't — that call no-ops on an
empty mapping, but a cloud-print sanity check from someone set up for it would be
worth having before merge.

Two bugs that compound, so no filament is deducted for a print started
from the printer itself rather than from Bambu Studio.

1. The tracker dispatch is gated on print_type == "local", but
   print_type is read when the project_file command arrives, and the
   printer still reports "idle" there -- it flips to "local" one MQTT
   message later. So apply_ams_mapping() never ran for a local print.

2. The local path then hardcodes ams_mapping = [] on a later message,
   clobbering the mapping from the project_file payload.

Either one leaves using_ams False, so every layer is attributed to the
external spool (trayUid ending _255_254), which has no spool assigned
and deducts nothing.

apply_ams_mapping() already no-ops on an empty mapping, so calling both
unconditionally is safe for cloud prints too, and the printer's own
mapping is still in PRINTER_STATE, so reuse it instead of clearing it.
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