Lineare Warteschlange: nach position abarbeiten + Formatwechsel-Anforderung
- _naechste_jobs: alle queued Jobs der Maschine nach -priority,position,date_created,id (kein Format-Filter mehr); erster Job bestimmt das naechste Format - Hauptschleife: passt Format -> drucken; sonst machines.pending_format setzen und auf Board-Bestaetigung warten (kein Auto-Anschluss) - _sende_batch: nur der zusammenhaengende Lauf vom Anfang (gleiches Format+Platzierung), damit ein Format an spaeterer Position nicht vorgezogen wird - Maschinen-Fetch um pending_format erweitert; _set_pending-Helfer Braucht neue Directus-Felder/Rechte (Bootstrap zuerst laufen lassen). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
57
agent.py
57
agent.py
@@ -230,7 +230,7 @@ def main():
|
||||
pruefe_befehle(dx, machine_id, cfg)
|
||||
|
||||
maschine = dx.get(f"/items/machines/{machine_id}",
|
||||
fields="base_url,mid,username,password,active,current_format")
|
||||
fields="base_url,mid,username,password,active,current_format,pending_format")
|
||||
if not maschine or not maschine.get("active", True):
|
||||
beat("offline")
|
||||
time.sleep(poll)
|
||||
@@ -282,11 +282,24 @@ def main():
|
||||
# Nächsten Job nur senden, wenn nichts (mehr) läuft.
|
||||
if laufend is None:
|
||||
current_format = (maschine.get("current_format") or "").strip()
|
||||
# Format-Warteschlange: nur passendes Format, kein Auto-Anschluss.
|
||||
if current_format:
|
||||
jobs = _naechste_jobs(dx, machine_id, current_format)
|
||||
if jobs:
|
||||
pending_format = (maschine.get("pending_format") or "").strip()
|
||||
# Lineare Warteschlange: der nächste Job nach Position bestimmt das
|
||||
# Format. Stimmt es mit dem eingelegten Format überein → drucken.
|
||||
# Sonst Formatwechsel im Board anfordern (pending_format) und warten –
|
||||
# kein Auto-Anschluss ohne Bestätigung.
|
||||
jobs = _naechste_jobs(dx, machine_id)
|
||||
if jobs:
|
||||
next_format = (jobs[0].get("format") or "").strip()
|
||||
if next_format and next_format == current_format:
|
||||
if pending_format:
|
||||
_set_pending(dx, machine_id, None)
|
||||
laufend = _sende_batch(dx, plotter, jobs, KIND)
|
||||
elif pending_format != next_format:
|
||||
_set_pending(dx, machine_id, next_format)
|
||||
log(dx, machine_id, "info", "format",
|
||||
f"Formatwechsel noetig: bitte Format '{next_format}' einlegen und im Board bestaetigen.")
|
||||
elif pending_format:
|
||||
_set_pending(dx, machine_id, None)
|
||||
|
||||
time.sleep(poll)
|
||||
|
||||
@@ -371,21 +384,28 @@ def _heartbeat(dx, machine_id, status):
|
||||
pass
|
||||
|
||||
|
||||
def _naechste_jobs(dx, machine_id, current_format):
|
||||
"""ALLE eingereihten Jobs des aktuell eingelegten Formats – in stabiler
|
||||
Warteschlangen-Reihenfolge (Priorität, dann Erstellzeit, dann ID als
|
||||
eindeutiger Tiebreak). Diese Reihenfolge = Erstell-/Auftragsnummern-Reihenfolge
|
||||
(enqueue-bulk legt die Jobs nach Auftragsnummer an) und MUSS exakt erhalten
|
||||
bleiben, damit Schriftstücke, Kuverts und die Sammel-PDF zueinander passen."""
|
||||
def _set_pending(dx, machine_id, fmt):
|
||||
"""Angefordertes nächstes Format setzen/löschen (für Board-Bestätigung)."""
|
||||
try:
|
||||
dx.patch(f"/items/machines/{machine_id}", {"pending_format": fmt})
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def _naechste_jobs(dx, machine_id):
|
||||
"""ALLE eingereihten Jobs der Maschine – in der EXPLIZITEN Plan-Reihenfolge
|
||||
(Priorität für Direktdruck, dann die lineare Position, dann Erstellzeit/ID als
|
||||
Tiebreak). Der erste Job bestimmt das als Nächstes zu druckende Format; ein
|
||||
Format darf mehrfach an verschiedenen Positionen stehen. Diese Reihenfolge MUSS
|
||||
exakt erhalten bleiben, damit Schriftstücke, Kuverts und Sammel-PDF zusammenpassen."""
|
||||
return dx.get(
|
||||
"/items/jobs",
|
||||
**{
|
||||
"filter[machine][_eq]": machine_id,
|
||||
"filter[status][_eq]": "queued",
|
||||
"filter[format][_eq]": current_format,
|
||||
"sort": "-priority,date_created,id",
|
||||
"sort": "-priority,position,date_created,id",
|
||||
"limit": -1,
|
||||
"fields": "id,type,output_ref,params,numbers,spaltenweise,"
|
||||
"fields": "id,type,format,output_ref,params,numbers,spaltenweise,"
|
||||
"order.id,order.order_number,order.needs_envelope,"
|
||||
"template.width,template.height,"
|
||||
"template.xpos,template.ypos,template.scale,template.rotation",
|
||||
@@ -450,7 +470,14 @@ def _sende_batch(dx, plotter, jobs, KIND):
|
||||
Dokument). Markiert alle als „printing". Gibt einen Sammel-Kontext zum späteren
|
||||
Abschluss zurück (oder None, wenn nichts gesendet wurde)."""
|
||||
ref = _batch_key(jobs[0])
|
||||
batch = [j for j in jobs if _batch_key(j) == ref]
|
||||
ref_fmt = (jobs[0].get("format") or "").strip()
|
||||
# Nur der zusammenhängende Lauf VOM ANFANG mit gleichem Format + gleicher
|
||||
# Platzierung – an einer Format-/Platzierungsgrenze stoppen (lineare Reihenfolge).
|
||||
batch = []
|
||||
for j in jobs:
|
||||
if (j.get("format") or "").strip() != ref_fmt or _batch_key(j) != ref:
|
||||
break
|
||||
batch.append(j)
|
||||
tpl = _eff_tpl(batch[0])
|
||||
dateien = []
|
||||
infos = []
|
||||
|
||||
Reference in New Issue
Block a user