TRO-JSON v4: Slots je TRO und Staubereiche (jamAreas)
- model: Slot (separator/switch/scanner/drive + Rollen), JamArea (J<Separator>, Eingang eines TRO mit allen Vorgaengern), derive_slots, derive_jam_areas; Schema sps_skel-tro-v4, v3-Dateien werden weiter gelesen - scl_context: ein JamEntr je eigenem Staubereich statt je Vorgaenger (wie UH01-UH05), Ausgaenge nennen den Staubereich des Nachfolgers - Golden Files neu erzeugt, Tests fuer Slots/Staubereiche, Doku nachgezogen Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
dd2d98f2ee
commit
0115ef68b7
+50
-13
@@ -32,7 +32,7 @@ from typing import TYPE_CHECKING
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
from model import TroBase, TroDocument
|
||||
from model import JamArea, TroBase, TroDocument
|
||||
from tro_catalog import TroItem
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -132,17 +132,29 @@ class SclScanner(BaseModel):
|
||||
|
||||
|
||||
class SclJam(BaseModel):
|
||||
"""Ein Staubereich am Ein- oder Ausgang (JamEntr<n> / JamExit<n>)."""
|
||||
"""Ein Staubereich am Ein- oder Ausgang (JamEntr<n> / JamExit<n>).
|
||||
|
||||
Ein Eingang ist ein Staubereich des TRO selbst (TroDocument.jamAreas), ein
|
||||
Ausgang der Eingangs-Staubereich des Nachfolgers.
|
||||
"""
|
||||
|
||||
model_config = _CONFIG
|
||||
|
||||
n: int
|
||||
# Nachbar als Text fuer den Kommentar, SYSn als Station markiert
|
||||
# Kennung aus der TRO-JSON (J<Separator>); "" am Ausgang zu einer Station
|
||||
jam_id: str = ""
|
||||
# Eingang: die Vorgaenger, Ausgang: der Nachfolger - als Text fuer den
|
||||
# Kommentar, SYSn als Station markiert
|
||||
neighbour: str
|
||||
db: SclName
|
||||
# Stausensor des Ausgangs (stInSenJam<n>); None an Eingaengen
|
||||
sensor: SclName | None = None
|
||||
|
||||
@property
|
||||
def title(self) -> str:
|
||||
"""Fuer den Kommentar: 'Staubereich J0003' (ohne Kennung nur 'Staubereich')."""
|
||||
return f"Staubereich {self.jam_id}" if self.jam_id else "Staubereich"
|
||||
|
||||
|
||||
class SclTro(BaseModel):
|
||||
"""Alles, was eine REGION fuer einen TRO braucht."""
|
||||
@@ -314,14 +326,38 @@ def _separator(i: int, layout: str, eplan: EplanDocument | None) -> SclSeparator
|
||||
)
|
||||
|
||||
|
||||
def _entries(tro: TroBase, eigene: list[JamArea],
|
||||
alle: dict[str, TroBase], jam_db: str) -> list[SclJam]:
|
||||
"""Ein JamEntr je eigenem Staubereich - nicht je Vorgaenger: mehrere
|
||||
Vorgaenger fahren in denselben Staubereich ein (Referenzen UH01-UH05)."""
|
||||
eingaenge = []
|
||||
for area in eigene:
|
||||
von = ", ".join(_nachbar(v, alle) for v in area.predecessors) or "-"
|
||||
if area.note:
|
||||
von = f"{von} ({area.note})"
|
||||
eingaenge.append(SclJam(n=area.entry, jam_id=area.jam_id,
|
||||
neighbour=von, db=_offen(jam_db)))
|
||||
return eingaenge
|
||||
|
||||
|
||||
def _exit_area(tro_id: str, nach: str,
|
||||
bereiche: dict[str, list[JamArea]]) -> str:
|
||||
"""Kennung des Staubereichs, in den tro_id beim Nachfolger einfaehrt."""
|
||||
ziel = bereiche.get(nach, [])
|
||||
passend = [a for a in ziel if tro_id in a.predecessors] or ziel
|
||||
return passend[0].jam_id if passend else ""
|
||||
|
||||
|
||||
def _tro_context(tro: TroBase, alle: dict[str, TroBase],
|
||||
eplan: EplanDocument | None = None) -> SclTro:
|
||||
eplan: EplanDocument | None = None,
|
||||
bereiche: dict[str, list[JamArea]] | None = None) -> SclTro:
|
||||
items = tro.items
|
||||
n_sep = items.get(TroItem.SEPARATOR, 1)
|
||||
n_swi = items.get(TroItem.SWITCH, 0)
|
||||
n_scan = items.get(TroItem.SCANNER, 0)
|
||||
tro_id = tro.tro_id
|
||||
jam_db = '"DB_JamArea____".stJam____'
|
||||
bereiche = bereiche or {}
|
||||
|
||||
separators = [
|
||||
_separator(i, tro.separators[i - 1] if i <= len(tro.separators) else "?", eplan)
|
||||
@@ -371,15 +407,13 @@ def _tro_context(tro: TroBase, alle: dict[str, TroBase],
|
||||
for i in range(1, n_scan + 1)
|
||||
],
|
||||
storage_lines=items.get(TroItem.STORAGE_LINE, 0),
|
||||
# Staubereiche: je ankommender/abgehender Verbindung einer. Welche
|
||||
# DB-Struktur dahintersteht, ist eine Planungsentscheidung - hier steht
|
||||
# nur, WIE VIELE es sein muessen und zu welchem Nachbarn sie gehoeren.
|
||||
jam_entries=[
|
||||
SclJam(n=n, neighbour=_nachbar(vor, alle), db=_offen(jam_db))
|
||||
for n, vor in enumerate(tro.predecessors, start=1)
|
||||
],
|
||||
# Staubereiche aus der TRO-JSON (jamAreas): Eingaenge sind die eigenen,
|
||||
# Ausgaenge die Eingaenge der Nachfolger. Der DB-Name braucht die
|
||||
# Foerderernummer aus der Hardwareplanung und bleibt offen.
|
||||
jam_entries=_entries(tro, bereiche.get(tro_id, []), alle, jam_db),
|
||||
jam_exits=[
|
||||
SclJam(n=n, neighbour=_nachbar(nach, alle), db=_offen(jam_db),
|
||||
SclJam(n=n, jam_id=_exit_area(tro_id, nach, bereiche),
|
||||
neighbour=_nachbar(nach, alle), db=_offen(jam_db),
|
||||
sensor=_offen("cInBG____"))
|
||||
for n, nach in enumerate(tro.successors, start=2)
|
||||
],
|
||||
@@ -406,12 +440,15 @@ def build_context(document: TroDocument, source: str, start_id: str = "",
|
||||
alle Namen offen und die Ausgabe ist die bisherige.
|
||||
"""
|
||||
alle = {t.tro_id: t for t in document.tros}
|
||||
bereiche: dict[str, list[JamArea]] = {}
|
||||
for area in document.jam_areas_or_derived():
|
||||
bereiche.setdefault(area.tro, []).append(area)
|
||||
geordnet, startgrund = flow_order(document.tros, start_id)
|
||||
return SclFile(
|
||||
source=source,
|
||||
created=created or datetime.now().strftime("%Y-%m-%d %H:%M"),
|
||||
start_reason=startgrund,
|
||||
tros=[_tro_context(t, alle, eplan) for t in geordnet],
|
||||
tros=[_tro_context(t, alle, eplan, bereiche) for t in geordnet],
|
||||
eplan_source=(f"{eplan.eplan_file} (Zuordnung vom {eplan.created})"
|
||||
if eplan is not None else ""),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user