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:
+55
-4
@@ -56,6 +56,11 @@ anders als die laufenden Nummern, an denen die alten Abschnitte veraltet sind.
|
||||
|
||||
[<csv>.edit_add.<ID>] neuer TRO (TRO_INSERT), Schluessel wie oben
|
||||
|
||||
[<csv>.edit_connections] Verbindungen, im Plan (CONNECTION_*) geaendert
|
||||
c01 = + TRO05 -> TRO07 | transfer dazu (Art optional, Standard transfer)
|
||||
c02 = - TRO05 -> TRO01 weg
|
||||
Enden sind die stabilen Schluessel der TROs
|
||||
|
||||
Stehen Slots im Abschnitt, gelten sie vollstaendig (fehlende Slots des Typs
|
||||
bleiben leer); stehen keine, bleiben die Bauteile wie abgeleitet. Die Lage
|
||||
hinter der TeileId macht den Eintrag exportfest: passt die TeileId im neuen
|
||||
@@ -220,6 +225,33 @@ class TroEdit:
|
||||
or self.slots is not None or self.lines is not None)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ConnectionEdit:
|
||||
"""Eine im Plan hinzugefuegte (add) oder entfernte Verbindung zwischen
|
||||
zwei TROs, Enden als stabile Schluessel (DerivedTro.key)."""
|
||||
|
||||
add: bool
|
||||
src: str
|
||||
dst: str
|
||||
kind: str = ""
|
||||
|
||||
def render(self) -> str:
|
||||
text = f"{'+' if self.add else '-'} {self.src} -> {self.dst}"
|
||||
return f"{text} | {self.kind}" if self.add and self.kind else text
|
||||
|
||||
@classmethod
|
||||
def parse(cls, raw: str) -> ConnectionEdit:
|
||||
text = raw.strip()
|
||||
if not text or text[0] not in "+-":
|
||||
raise ValueError(f"'{raw}': erwartet '+ <von> -> <nach> [| Art]' oder "
|
||||
f"'- <von> -> <nach>'")
|
||||
pfeil, _, kind = text[1:].partition("|")
|
||||
src, sep, dst = (t.strip() for t in pfeil.partition("->"))
|
||||
if not sep or not src or not dst:
|
||||
raise ValueError(f"'{raw}': erwartet '<von> -> <nach>'")
|
||||
return cls(add=text[0] == "+", src=src, dst=dst, kind=kind.strip())
|
||||
|
||||
|
||||
@dataclass
|
||||
class Overrides:
|
||||
"""Alle Korrekturen zu einer CSV-Datei.
|
||||
@@ -237,6 +269,8 @@ class Overrides:
|
||||
candidates: list[TroCandidate] = field(default_factory=list)
|
||||
# Handkorrekturen aus BricsCAD in Dateireihenfolge (tro_flow.apply_edits)
|
||||
edits: list[TroEdit] = field(default_factory=list)
|
||||
# Verbindungen aus BricsCAD (tro_flow.apply_connection_edits)
|
||||
connection_edits: list[ConnectionEdit] = field(default_factory=list)
|
||||
# Protokoll der tatsaechlich angewandten Korrekturen (fuer die Doku)
|
||||
applied: list[str] = field(default_factory=list)
|
||||
warnings: list[str] = field(default_factory=list)
|
||||
@@ -278,7 +312,8 @@ def load_overrides(csv_name: str, cfg_dir: Path | None = None) -> Overrides:
|
||||
|
||||
parser = configparser.ConfigParser(inline_comment_prefixes=(";",))
|
||||
# Schluessel sind Kleinschreibung, Sektionsnamen bleiben wie geschrieben.
|
||||
parser.read(path, encoding="utf-8")
|
||||
# utf-8-sig: von Hand (Editor, PowerShell) gespeichert oft mit BOM
|
||||
parser.read(path, encoding="utf-8-sig")
|
||||
|
||||
prefix = csv_name.lower()
|
||||
for section in parser.sections():
|
||||
@@ -297,6 +332,14 @@ def load_overrides(csv_name: str, cfg_dir: Path | None = None) -> Overrides:
|
||||
Connection(src=src, dst=dst, kind=rest.strip())
|
||||
)
|
||||
continue
|
||||
# [<csv>.edit_connections] - Verbindungen aus BricsCAD
|
||||
if section.lower() == f"{prefix}.edit_connections":
|
||||
for key, raw in parser[section].items():
|
||||
try:
|
||||
result.connection_edits.append(ConnectionEdit.parse(raw))
|
||||
except ValueError as exc:
|
||||
result.warnings.append(f"[{section}] {key}: {exc}")
|
||||
continue
|
||||
|
||||
parts = section.split(".")
|
||||
# <csv>.<art>.<name> - der CSV-Name kann selbst einen Punkt enthalten
|
||||
@@ -475,8 +518,10 @@ def render_edit(csv_name: str, edit: TroEdit) -> str:
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def save_edits(csv_name: str, edits: list[TroEdit], cfg_dir: Path | None = None) -> Path:
|
||||
"""Alle edit-/edit_add-Abschnitte zu `csv_name` durch `edits` ersetzen.
|
||||
def save_edits(csv_name: str, edits: list[TroEdit], cfg_dir: Path | None = None,
|
||||
connections: list[ConnectionEdit] | None = None) -> Path:
|
||||
"""Alle edit-/edit_add-Abschnitte und [<csv>.edit_connections] zu
|
||||
`csv_name` durch `edits` bzw. `connections` ersetzen.
|
||||
|
||||
Der Rest der Datei (von Hand gepflegt, mit Kommentaren) bleibt Zeile fuer
|
||||
Zeile erhalten; der neue Block steht am Ende. Kommentarzeilen direkt vor
|
||||
@@ -488,6 +533,8 @@ def save_edits(csv_name: str, edits: list[TroEdit], cfg_dir: Path | None = None)
|
||||
head = _EDIT_HEAD.format(csv=csv_name).lower()
|
||||
|
||||
def ist_edit(section: str) -> bool:
|
||||
if section.lower() == f"{prefix}.edit_connections":
|
||||
return True
|
||||
parts = section.split(".")
|
||||
return (len(parts) >= 3 and parts[-2].lower() in ("edit", "edit_add")
|
||||
and ".".join(parts[:-2]).lower() == prefix)
|
||||
@@ -519,13 +566,17 @@ def save_edits(csv_name: str, edits: list[TroEdit], cfg_dir: Path | None = None)
|
||||
|
||||
while keep and not keep[-1].strip():
|
||||
keep.pop()
|
||||
if edits:
|
||||
if edits or connections:
|
||||
if keep:
|
||||
keep += ["", ""]
|
||||
keep.append(_EDIT_HEAD.format(csv=csv_name)
|
||||
+ f" - tro_annotate --read-tros, {datetime.now():%Y-%m-%d}")
|
||||
for edit in edits:
|
||||
keep += [render_edit(csv_name, edit), ""]
|
||||
if connections:
|
||||
keep.append(f"[{csv_name}.edit_connections]")
|
||||
keep += [f"c{n:02d} = {c.render()}" for n, c in enumerate(connections, start=1)]
|
||||
keep.append("")
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text("\n".join(keep).rstrip("\n") + "\n", encoding="utf-8")
|
||||
return path
|
||||
|
||||
Reference in New Issue
Block a user