Merge branch '0.2.0b' into 0.2.0b

This commit is contained in:
MartinNYHC
2026-02-16 08:36:38 +01:00
committed by GitHub
19 changed files with 9366 additions and 8715 deletions
+94 -1
View File
@@ -748,7 +748,7 @@ async def assign_spool(
matching_kp = None
for kp in spool.k_profiles:
if kp.printer_id == data.printer_id and kp.nozzle_diameter == nozzle_diameter:
if slot_extruder is not None and kp.extruder_id is not None and kp.extruder_id != slot_extruder:
if slot_extruder is not None and kp.extruder is not None and kp.extruder != slot_extruder:
continue
matching_kp = kp
break
@@ -954,6 +954,99 @@ async def clear_spool_usage_history(
return {"status": "cleared"}
# ── AMS Weight Sync ──────────────────────────────────────────────────────────
@router.post("/sync-ams-weights")
async def sync_weights_from_ams(
db: AsyncSession = Depends(get_db),
_: User | None = RequirePermissionIfAuthEnabled(Permission.INVENTORY_UPDATE),
):
"""Force-sync spool weight_used from live AMS remain% data.
Overwrites the database weight_used for every assigned spool using the
current AMS remain% from connected printers. This is a manual recovery
tool — it bypasses the normal "only increase" guard.
"""
from backend.app.services.printer_manager import printer_manager
result = await db.execute(select(SpoolAssignment).options(selectinload(SpoolAssignment.spool)))
assignments = list(result.scalars().all())
logger.info("AMS weight sync: found %d assignments", len(assignments))
synced = 0
skipped = 0
for assignment in assignments:
spool = assignment.spool
if not spool:
logger.debug("AMS weight sync: assignment %d has no spool", assignment.id)
skipped += 1
continue
state = printer_manager.get_status(assignment.printer_id)
if not state or not state.raw_data:
logger.info(
"AMS weight sync: printer %d not connected, skipping spool %d",
assignment.printer_id,
spool.id,
)
skipped += 1
continue
ams_raw = state.raw_data.get("ams", [])
if isinstance(ams_raw, dict):
ams_raw = ams_raw.get("ams", [])
tray = _find_tray_in_ams_data(ams_raw, assignment.ams_id, assignment.tray_id)
if not tray:
logger.info(
"AMS weight sync: no tray data for spool %d (printer %d AMS%d-T%d)",
spool.id,
assignment.printer_id,
assignment.ams_id,
assignment.tray_id,
)
skipped += 1
continue
remain_raw = tray.get("remain")
if remain_raw is None:
logger.debug("AMS weight sync: no remain value for spool %d", spool.id)
skipped += 1
continue
try:
remain_val = int(remain_raw)
except (TypeError, ValueError):
skipped += 1
continue
if remain_val < 0 or remain_val > 100:
logger.debug("AMS weight sync: invalid remain=%s for spool %d", remain_raw, spool.id)
skipped += 1
continue
lw = spool.label_weight or 1000
new_used = round(lw * (100 - remain_val) / 100.0, 1)
old_used = spool.weight_used or 0
if round(old_used, 1) != new_used:
logger.info(
"AMS weight sync: spool %d weight_used %s -> %s (remain=%d%%)",
spool.id,
old_used,
new_used,
remain_val,
)
spool.weight_used = new_used
synced += 1
else:
skipped += 1
await db.commit()
return {"synced": synced, "skipped": skipped}
# ── Helpers ──────────────────────────────────────────────────────────────────