mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-08-11 00:30:12 -04:00
An H2C ran its startup clean and bed levelling on one hotend, switched, and then printed several millimetres above the plate. The same job from Bambu Studio was fine. The H2C is the only model that mounts its nozzle from a rack of six, and a print command names that nozzle by physical rack position -- the firmware reports those as 16 to 21 -- not by the extruder index, 0 or 1, every other dual-nozzle printer uses. Bambuddy only ever had a rack position when a job arrived through the Virtual Printer, which captures Bambu Studio's pick and replays it (#1780). Anything queued from the library, an archive, the webhook or a slicer pipeline carried none, so the field was omitted and the firmware chose -- and its choice need not match what the file was sliced for. The scheduler now derives the per-slot extruder assignment from the file it is about to send, and the MQTT layer resolves it against the rack position the printer reports live. Both are needed: the file knows which side a slot prints from, only the printer knows which hotend is in the carriage, and it can be swapped from the touchscreen between queueing a job and printing it. Derived at dispatch rather than at creation because that is the first point knowing both the real printer and the real file -- an item can be created unassigned, reassigned later, or have its file swapped for a G-code-injected copy. One call therefore covers the print dialog, bulk library adds, the webhook and pipeline runs, and no column is needed. extract_nozzle_mapping_from_3mf is deliberately untouched. Its output feeds the AMS matcher, where nozzle_id is compared against a tray's extruder_id as a hard filter, and physical_extruder_map is what makes that comparison correct -- on an H2D it is [1, 0] and flips the two. Dropping the translation to suit the rack would send every dual-nozzle AMS match to the wrong extruder. The dense per-slot form is a separate function reusing the same output. Nothing here can fail a dispatch. The command is built and published with no exception handler above it, and the queue item is already committed as printing by then, so a bad input has to degrade to "firmware picks" rather than wedge the item. resolve_rack_nozzle_mapping validates every input and raises nothing; an unresolvable mapping, an unparseable value or an unknown rack position all omit the field, which is the behaviour that existed before. Slot IDs are bounded before the dense list is built: they come from the file, and one declaring filament id="50000000" would otherwise allocate a fifty-million-entry list on the dispatch path. Two things are not guessed. A job printing only from the fixed hotend is still left to the firmware, because that nozzle's physical ID is not confirmed by a known-good capture. And the rack is taken to feed extruder 0 from a single hardware observation -- if that is flipped, a one-sided job matches nothing and falls back to the old behaviour, so only a job using both nozzles at once could be harmed, which is what a second capture needs to confirm. Confined to the H2C throughout. Building the print command for 21 model spellings with and without the new argument changes exactly three of them -- H2C, O1C and O1C2. The other 18, including H2D and X2D, are identical. Reported by @tru3l3gend, who diagnosed it on real hardware against a working Bambu Studio dispatch, established the rack ID range and supplied a patch. |
||
|---|---|---|
| .. | ||
| color_utils.py | ||
| filament_ids.py | ||
| filename.py | ||
| http.py | ||
| local_time.py | ||
| printer_models.py | ||
| safe_path.py | ||
| tag_normalization.py | ||
| threemf_tools.py | ||
| tray_split.py | ||