Spoolman leads CC2 Control's copies; new spools from the bridge
CI / test (push) Successful in 2m35s
CI / image (push) Successful in 42s

- Master data of CC2 Control's copies follows Spoolman (name, brand,
  colour, diameter, density, net, tare, price; not the material, which was
  fitted to the tray).
- A loaded spool's rest in CC2 Control is set to Spoolman's via
  /api/spools/adjust once everything is booked (old copy after the roll
  printed in the other printer, weigh-in in Spoolman); the resulting
  correction is not booked back.
- Copies of spools archived or deleted in Spoolman are deleted from CC2
  Control when no tray holds them (library limit 128); an outage never
  counts as deleted.
- A roll that ran out is archived in Spoolman (setting, default on); a
  scan of an archived spool maps nothing.
- A roll scanned again with unchanged tag data and put back into its old
  slot (after printing in the other printer) is recognised.
- Tag generator: "Neue Spule" creates spools in Spoolman from an existing
  or a new filament (and vendor), labelled vendor + id, then opens the tag.

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 21:26:49 +01:00
1 parent d03668e3c5
commit b37cd64909
13 files changed
+873 -27

No files matched your search

+31
View File
@@ -133,3 +133,34 @@ def test_printers_editable(tmp_path):
assert dup.status_code == 400
bad = c.post("/api/settings", json={"location_slot": "Slot {n}"}, headers=H)
assert bad.status_code == 400 # two printers need {printer}
def test_create_spools_from_existing_filament(tmp_path):
c, bridge = make_client(tmp_path)
sm = bridge.spoolman_factory(None)
cat = c.get("/api/spoolman/catalog").json()
assert cat["next_id"] == 6 and cat["filaments"][0]["name"] == "PLA+ Black"
body = {"filament_id": 1, "count": 2, "weight": 1000, "spool_weight": 130}
assert c.post("/api/spoolman/create", json=body, headers=H).status_code == 409 # dry-run
assert not [x for x in sm.calls if x[0].startswith("create")]
c.post("/api/settings", json={"dry_run": False}, headers=H)
r = c.post("/api/spoolman/create", json=body, headers=H)
assert r.status_code == 200 and r.json()["spools"] == [{"id": 6, "label": "SUNLU006"}, {"id": 7, "label": "SUNLU007"}]
assert sm.db[7]["lot_nr"] == "SUNLU007" and sm.db[7]["location"] == "Lager" and sm.db[7]["initial_weight"] == 1000
assert ("create_spool", {"filament_id": 1, "location": "Lager", "initial_weight": 1000.0, "spool_weight": 130.0}) in sm.calls
def test_create_spool_with_new_filament_and_vendor(tmp_path):
c, bridge = make_client(tmp_path)
sm = bridge.spoolman_factory(None)
c.post("/api/settings", json={"dry_run": False}, headers=H)
body = {"vendor": "Elegoo", "name": "PLA Matte Black", "material": "PLA Matte", "color": "#1a1a1a", "density": 1.24,
"diameter": 1.75, "weight": 1000, "spool_weight": 154, "extruder_temp": 210, "bed_temp": 60, "count": 1}
r = c.post("/api/spoolman/create", json=body, headers=H)
assert r.status_code == 200 and r.json()["spools"][0]["label"] == "ELEGOO006"
fil = [x[1] for x in sm.calls if x[0] == "create_filament"][0]
assert fil["color_hex"] == "1A1A1A" and fil["settings_extruder_temp"] == 210 and fil["vendor_id"] == 2
assert ("create_vendor", {"name": "Elegoo", "empty_spool_weight": 154.0}) in sm.calls
bad = dict(body, color="red")
assert c.post("/api/spoolman/create", json=bad, headers=H).status_code == 400
assert c.post("/api/spoolman/create", json=dict(body, count=50), headers=H).status_code == 400