Recognise rolls put back, use CC2 Control's log for bookings
CI / test (push) Successful in 1m13s
CI / image (push) Successful in 48s

- A roll put back into the slot it left, with the tag data unchanged, is
  mapped again and CC2 Control's question answered; if the touchscreen then
  replaces the id, it was another roll and goes to storage.
- A touchscreen edit of a scanned roll keeps the mapping and re-answers
  CC2 Control's question so its use is counted.
- Bookings name the print and its result from CC2 Control's log.
- A weigh-in in CC2 Control sets Spoolman's remaining weight instead of
  being booked as use.
- After "Take out" with the roll still in the tray, the tray's logged use
  is booked to that roll until it leaves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014GcEk5tkfFSYD6NTF66NkC
This commit is contained in:
Jonas MenzelandClaude Opus 5.5 committed 2026-10-25 10:29:33 +01:00
1 parent a9041eb538
commit 67c3b54903
7 files changed
+607 -40

No files matched your search

+17 -2
View File
@@ -48,6 +48,7 @@ class FakeCC2:
self.slots[4]["printer"] = None
self.library: list[dict] = []
self.job = {"active": False}
self.log: list[dict] = [] # newest first, as CC2 Control lists it
self.calls: list[tuple] = []
self.fail = False
self._ids = (f"s{i:04d}" for i in itertools.count(1))
@@ -57,7 +58,7 @@ class FakeCC2:
raise CC2Error("CC2 Control nicht erreichbar")
def spools_json(self):
return {"enabled": self.enabled, "slots": self.slots, "spools": self.library, "job": self.job, "log": []}
return {"enabled": self.enabled, "slots": self.slots, "spools": self.library, "job": self.job, "log": self.log}
def spools(self):
self._check()
@@ -103,6 +104,15 @@ class FakeCC2:
sp = next(s for s in self.library if s["id"] == cc2_id)
sp["remaining"] -= grams
def add_log(self, time, kind="print", spool="", slot=0, grams=0.0, mm=0.0, job="", result=""):
self.log.insert(0, {"time": int(time), "spool": spool, "slot": slot, "kind": kind, "grams": grams, "mm": mm,
"job": job, "result": result})
def weigh(self, cc2_id, remaining, time):
sp = next(s for s in self.library if s["id"] == cc2_id)
self.add_log(time, "correction", cc2_id, -1, remaining - sp["remaining"], 0, "", "weighed")
sp["remaining"] = remaining
def close(self):
pass
@@ -148,7 +158,12 @@ class FakeSpoolman:
for key, value in (body.get("extra") or {}).items():
if value is not None and key not in self.field_defs:
raise SpoolmanError("Spoolman PATCH: HTTP 400")
self.calls.append(("location", sid, body.get("location")))
if "location" in body:
self.calls.append(("location", sid, body.get("location")))
if "used_weight" in body:
self.calls.append(("used", sid, body["used_weight"]))
sp["used_weight"] = body["used_weight"]
sp["remaining_weight"] = sp["initial_weight"] - body["used_weight"]
if "extra" in body:
self.calls.append(("extra", sid, dict(body["extra"])))
if "location" in body: