mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-18 21:47:39 +02:00
Fix VP queue mode sending wrong plate_id → HMS 0500_4003 (#529)
When a virtual printer auto-queued a file, PrintQueueItem was created without plate_id. The scheduler defaulted to plate_id=1, generating MQTT path "Metadata/plate_1.gcode". For multi-plate 3MF files sliced on a different plate, the printer couldn't find the gcode and returned HMS error 0500_4003. Extract plate index from the 3MF's slice_info.config before creating the queue item.
This commit is contained in:
@@ -5,6 +5,7 @@ All notable changes to Bambuddy will be documented in this file.
|
||||
## [0.2.1] - Unreleased
|
||||
|
||||
### Fixed
|
||||
- **Virtual Printer Queue Sends Wrong Plate ID** ([#529](https://github.com/maziggy/bambuddy/issues/529)) — Files sent to a virtual printer in queue mode always used `plate_id=1`, generating the MQTT path `Metadata/plate_1.gcode`. For multi-plate 3MF files where the actual plate is different (e.g. plate 19), the printer couldn't find the gcode and returned HMS error 0500_4003. Now extracts the plate index from the 3MF's `slice_info.config` before creating the queue item.
|
||||
- **Unnecessary Target Model Selector on "Any" Tab** ([#528](https://github.com/maziggy/bambuddy/issues/528)) — When scheduling a print to "Any {model}", a redundant "Target Model" dropdown appeared even though the G-code is already sliced for a specific printer model. Changing the target model would lead to print failures. The dropdown is now hidden when the sliced model is known (the tab label already shows "Any {model}"). It still appears as a fallback for legacy files without model metadata.
|
||||
- **"Clear Plate & Start Next" Button Shown on Printers Without Correct Filament** ([#527](https://github.com/maziggy/bambuddy/issues/527)) — When a print job was queued for "any printer" of a model (e.g., "any H2S"), the "Clear Plate & Start Next" button appeared on ALL printers of that model, including those without the required filament loaded. Clicking it on a printer without the right filament would start a print that fails. The `PrinterQueueWidget` now filters queue items by filament compatibility — it checks the printer's loaded filament types (from AMS and external spools) against the queue item's `required_filament_types` and only shows items the printer can actually print. If no compatible items exist, the widget is hidden.
|
||||
- **Manual Spool Weight Overwritten by AMS Auto-Sync** ([#525](https://github.com/maziggy/bambuddy/issues/525)) — When a user manually entered a spool weight (via UI or API), the value was overwritten by the automatic AMS remain% sync that runs on every MQTT update. The AMS remain% is integer-only (~10g resolution for 1kg spool) and can't match precise manual entries. Added a `weight_locked` flag that is automatically set when `weight_used` is explicitly updated via the API. Locked spools are skipped by both the automatic AMS remain% sync and the manual force-sync endpoint. The usage tracker (3MF/gcode delta tracking) is unaffected. Users can re-enable AMS sync by setting `weight_locked: false`.
|
||||
|
||||
@@ -310,10 +310,12 @@ class VirtualPrinterInstance:
|
||||
target_model = None
|
||||
if not self.target_printer_id and self.model:
|
||||
target_model = VIRTUAL_PRINTER_MODELS.get(self.model)
|
||||
plate_id = self._extract_plate_id(file_path)
|
||||
queue_item = PrintQueueItem(
|
||||
printer_id=self.target_printer_id,
|
||||
target_model=target_model,
|
||||
archive_id=archive.id,
|
||||
plate_id=plate_id,
|
||||
position=1,
|
||||
status="pending",
|
||||
)
|
||||
@@ -330,6 +332,26 @@ class VirtualPrinterInstance:
|
||||
except Exception as e:
|
||||
logger.error("Error adding to print queue: %s", e)
|
||||
|
||||
@staticmethod
|
||||
def _extract_plate_id(file_path: Path) -> int | None:
|
||||
"""Extract plate index from 3MF slice_info.config."""
|
||||
try:
|
||||
import xml.etree.ElementTree as ET
|
||||
import zipfile
|
||||
|
||||
with zipfile.ZipFile(file_path, "r") as zf:
|
||||
if "Metadata/slice_info.config" in zf.namelist():
|
||||
content = zf.read("Metadata/slice_info.config").decode()
|
||||
root = ET.fromstring(content) # noqa: S314
|
||||
plate = root.find(".//plate")
|
||||
if plate is not None:
|
||||
for meta in plate.findall("metadata"):
|
||||
if meta.get("key") == "index" and meta.get("value"):
|
||||
return int(meta.get("value"))
|
||||
except Exception:
|
||||
return None
|
||||
return None
|
||||
|
||||
# -- Service lifecycle --
|
||||
|
||||
async def start_server(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user