validate_anlage, stabiler TRO-Schluessel, Verbindungen aus BricsCAD, Zeichnung aus der Anlagen-JSON

- validate_anlage.py (+ bin-Wrapper): Pruefung vor der SCL fuer beide Wege
  (Struktur, Zuordnungen, Aktualitaet der JSON, Korrekturen ohne Ziel);
  scl_skeleton ruft sie auf (Warnung, --strict bricht ab)
- DerivedTro.key: stabiler Schluessel (ID der ID-Datei); hw_overrides.ini,
  <csv>_jam_names.ini und tro_overrides.ini greifen ueber ID oder Schluessel,
  eine Umbenennung in TRO_EDIT laesst sie bestehen; JAM_AREA traegt KEY
- --read-tros liest die CONNECTION_ARROW-Bloecke mit -> [<csv>.edit_connections];
  tro_flow.apply_connection_edits wendet sie nach link_tros an
- tro_annotate --anlage zeichnet Marker/Verbindungen aus der Anlagen-JSON
- INI-Korrekturen auch mit BOM lesbar (utf-8-sig)
- Ablauf CSV/DXF+TIA -> Anlagen-JSON -> (BricsCAD) -> SCL in doc/Python_Scripts.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-27 14:32:10 +01:00
parent 6c8c235287
commit 1ac17b95e2
13 changed files with 1100 additions and 48 deletions
+23 -1
View File
@@ -332,6 +332,12 @@ class DerivedTro(TroBase):
"""
label: str
# Stabiler Schluessel: die ID aus <csv>_tro_ids.ini (bzw. die Kennung eines
# in BricsCAD angelegten TRO). Weicht von ``tro_id`` ab, wenn der TRO im
# Dialog TRO_EDIT umbenannt wurde. Handkorrekturen (hw_overrides.ini,
# <csv>_jam_names.ini, tro_overrides.ini) gelten ueber ID *oder* Schluessel,
# damit sie eine Umbenennung ueberleben. "" in Dateien vor 2026-10-27.
key: str = ""
hosts: list[str]
scanners: list[str]
# Weichen-Bauteile (Ausschleuselement oder ILS Weiche), Reihenfolge wie die
@@ -351,6 +357,11 @@ class DerivedTro(TroBase):
def connected(self) -> bool:
return bool(self.successors or self.predecessors or self.colocated)
@property
def stable_key(self) -> str:
"""Schluessel fuer Handkorrekturen (``key``, sonst die ID)."""
return self.key or self.tro_id
class Connection(BaseModel):
"""Gerichtete Verbindung zwischen zwei TROs/Stationen (JSON: from/to/kind)."""
@@ -451,7 +462,9 @@ class TroDocument(BaseModel):
traegt und nicht erst das Rendern sie kennt. ``parts`` (Lage der
Layout-Bauteile) gibt tro_flow aus dem CSV mit.
"""
tros = [t.model_copy(update={"slots": derive_slots(t)}) for t in analysis.tros]
tros = [t.model_copy(update={"slots": derive_slots(t),
"key": analysis.edit_key(t.tro_id)})
for t in analysis.tros]
return cls(
source=source,
note=note,
@@ -490,6 +503,15 @@ class TroDocument(BaseModel):
return tro
return None
def resolve(self, name: str) -> DerivedTro | None:
"""TRO zu einer ID oder - nach einer Umbenennung - zu seinem Schluessel.
Die ID geht vor: ein neuer TRO darf die alte Kennung eines umbenannten
tragen, dann meint ein Eintrag mit dieser Kennung den neuen.
"""
return self.by_id(name) or next(
(t for t in self.tros if t.key and t.key == name), None)
# ---------------------------------------------------------------------------
# Anlagen-JSON: Layout + Zuordnungen der Hardwareplanung (merge_hw_layout)