fix skip object from print dialog

This commit is contained in:
Gangoke
2026-06-15 22:25:38 -10:00
parent 778c4ce85a
commit e64aebd145

View File

@@ -807,6 +807,9 @@ class KobraXBridge:
# Part-Skip: zuletzt vom Drucker gemeldete Skip-Liste (v0.9.10)
self._skip_state: dict = {"objects": [], "skipped": [], "ts": 0}
# Pre-Print-Skip: pending until confirmed/applied via skip/start
self._pending_preprint_skip: list[str] = []
self._pending_preprint_skip_deadline: float = 0.0
# Theme-Name prüfen (keine Sonderzeichen oder Umlaute)
raw_theme = (getattr(args, "ui_theme", None) or "default").strip()
@@ -1060,11 +1063,21 @@ class KobraXBridge:
"""
d = payload.get("data") or {}
skipped = d.get("objects_skip_parts") or d.get("skipped") or d.get("skipped_parts") or []
# Liste immer (auch leer) übernehmen sonst bleibt sie auf alten Stand
# Während ein Pre-Print-Skip noch als pending markiert ist, ignorieren wir
# leere Früh-Reports kurzzeitig, damit die UI nicht sofort zurückspringt.
now = time.time()
if (not skipped and self._pending_preprint_skip
and now <= self._pending_preprint_skip_deadline):
return
# Liste übernehmen (auch leer), sobald kein Pending-Lock aktiv ist.
self._skip_state = {
"skipped": list(skipped),
"ts": int(time.time()),
}
if self._pending_preprint_skip and set(skipped) >= set(self._pending_preprint_skip):
self._pending_preprint_skip = []
self._pending_preprint_skip_deadline = 0.0
if payload.get("state") == "done" or payload.get("code") == 200:
log.info(f"Skip-Antwort: state={payload.get('state')} code={payload.get('code')} skipped={skipped}")
@@ -2434,6 +2447,15 @@ class KobraXBridge:
excluded_objects = body.get("excluded_objects") or []
if not isinstance(excluded_objects, list):
excluded_objects = []
# Pre-Print-Auswahl sofort im UI-Status spiegeln (wird später durch
# skip/report vom Drucker überschrieben/aktualisiert).
self._skip_state = {"skipped": list(excluded_objects), "ts": int(time.time())}
if excluded_objects:
self._pending_preprint_skip = [str(n) for n in excluded_objects if isinstance(n, str) and n]
self._pending_preprint_skip_deadline = time.time() + 12.0
else:
self._pending_preprint_skip = []
self._pending_preprint_skip_deadline = 0.0
if assignments:
ams_box_mapping, unused_count, invalid_count = self._build_assigned_ams_box_mapping(assignments)
@@ -2476,6 +2498,9 @@ class KobraXBridge:
"ai_settings": {"status": 0, "count": 0, "type": 1},
"timelapse": {"status": 0, "count": 0, "type": 64},
"drying_settings": {"status": 0, "target_temp": 0, "duration": 0, "remain_time": 0},
# Firmware-Variante A (funktioniert bei mehreren Builds)
"objects_skip_parts": excluded_objects,
# Firmware-Variante B (beibehalten für Kompatibilität)
"model_objects_skip_parts": excluded_objects,
},
}
@@ -2488,6 +2513,9 @@ class KobraXBridge:
if result is None:
return self._json_cors({"error": "Keine Antwort vom Drucker"}, status=504)
if excluded_objects:
loop.run_in_executor(None, lambda: self._apply_preprint_skip_after_start(excluded_objects))
# Job in History starten
self._current_job_id = self._store.start_job(
gcode_file_id=gcode_file["id"],
@@ -2860,6 +2888,10 @@ class KobraXBridge:
def _start_print(self, filename: str, url: str = "", md5: str = "", filesize: int = 0,
gcode_filaments: list | None = None):
self._state["file_ready"] = ""
# Neuer Druck ohne Pre-Print-Excludes: Skip-State zurücksetzen.
self._skip_state = {"skipped": [], "ts": int(time.time())}
self._pending_preprint_skip = []
self._pending_preprint_skip_deadline = 0.0
loaded = self._select_loaded_slots_for_print(warn_on_empty_default=True)
# Nur die im GCode TATSÄCHLICH genutzten Paints auf Slots mappen. OrcaSlicer
@@ -2915,6 +2947,37 @@ class KobraXBridge:
else:
log.warning("Druckstart: keine Antwort vom Drucker")
def _apply_preprint_skip_after_start(self, names: list[str], retries: int = 20, delay_s: float = 0.75):
wanted = [str(n) for n in (names or []) if isinstance(n, str) and n]
if not wanted:
return False
self._pending_preprint_skip = list(wanted)
self._pending_preprint_skip_deadline = time.time() + max(3.0, float(retries) * float(delay_s) + 2.0)
# UI should already reflect intended skips immediately.
self._skip_state = {"skipped": list(wanted), "ts": int(time.time())}
for i in range(max(1, int(retries))):
try:
if self._state.get("kobra_state") != "printing":
time.sleep(max(0.1, float(delay_s)))
continue
resp = self.client.skip_objects(wanted)
if resp is not None:
log.info(f"Pre-Print skip applied ({len(wanted)} objects) on attempt {i+1}/{retries}")
self._pending_preprint_skip = []
self._pending_preprint_skip_deadline = 0.0
return True
except Exception as e:
log.debug(f"Pre-Print skip attempt {i+1}/{retries} failed: {e}")
time.sleep(max(0.1, float(delay_s)))
log.warning(f"Pre-Print skip could not be confirmed after {retries} attempts")
self._pending_preprint_skip = []
self._pending_preprint_skip_deadline = 0.0
return False
def _theme_index_path(self) -> str:
return os.path.join(_WEB_BASE, "web", "themes", self._ui_theme, "index.html")
@@ -2958,6 +3021,15 @@ class KobraXBridge:
excluded_objects = body.get("excluded_objects") or []
if not isinstance(excluded_objects, list):
excluded_objects = []
# Pre-Print-Auswahl sofort im UI-Status spiegeln (wird später durch
# skip/report vom Drucker überschrieben/aktualisiert).
self._skip_state = {"skipped": list(excluded_objects), "ts": int(time.time())}
if excluded_objects:
self._pending_preprint_skip = [str(n) for n in excluded_objects if isinstance(n, str) and n]
self._pending_preprint_skip_deadline = time.time() + 12.0
else:
self._pending_preprint_skip = []
self._pending_preprint_skip_deadline = 0.0
if filament_assignments is not None:
ams_box_mapping, unused_count, invalid_count = self._build_assigned_ams_box_mapping(filament_assignments)
if unused_count:
@@ -2997,6 +3069,9 @@ class KobraXBridge:
"ai_settings": {"status": 0, "count": 0, "type": 0},
"timelapse": {"status": 0, "count": 0, "type": 0},
"drying_settings": {"status": 0, "target_temp": 0, "duration": 0, "remain_time": 0},
# Firmware-Variante A (funktioniert bei mehreren Builds)
"objects_skip_parts": excluded_objects,
# Firmware-Variante B (beibehalten für Kompatibilität)
"model_objects_skip_parts": excluded_objects,
},
}
@@ -3013,6 +3088,9 @@ class KobraXBridge:
if result is None:
return web.json_response({"error": "Keine Antwort vom Drucker"}, status=504)
if excluded_objects:
loop.run_in_executor(None, lambda: self._apply_preprint_skip_after_start(excluded_objects))
return web.json_response({"result": "ok"})
async def handle_print_pause(self, request):