hw_import + merge_hw_layout: Hardwareplanung einlesen und mit dem Layout zusammenfuehren
Stufen 2 und 3 aus doc/Konzept_Layout_Hardware_SCL.md: - lib/hw_import.py: TIA-Import (*_TIA.xlsx, ohne openpyxl gelesen) + Positionsdatei (*_positionsconv.json) -> <projekt>_hw.json: je BMK Adresse, Index-Konstante, VERW, Station, Lage, Foerderer (K0102, #106 -> K0106); Antriebe MA/FC/GF; Gegenpruefung beider Quellen. - lib/merge_hw_layout.py: <csv>_tro.json + <projekt>_hw.json -> <csv>_anlage.json (model.AnlageDocument): bindings je TRO-ID + Slot + Rolle mit Konstante und Adresse, Foerderer per Mehrheit (Mubea: K0102 = Kreisel3, K0104 = Kreisel2, K0105 = Kreisel1), Handkorrekturen cfg/hw_overrides.ini. Zuordnungslogik aus e_planning.py hierher verschoben; e_planning re-exportiert sie, Ergebnis unveraendert. - TRO-JSON traegt optional `parts` (Lage/Huellbox, tro_flow --json), PinStore bekommt Slots line<n>. - Gespeicherter Lagebezug mit SHA-256 der Positionsdatei; Unterordner in Eingabenamen relativ zu SKEL_DATA. - Doku: Python_Scripts.md 5d/5e, Konzept, E-Planung_Bruecke (Abgleich mubea_layout.dxf / CSV / E-Planung). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c4122b4497
commit
df24cf5adb
+27
-2
@@ -50,6 +50,7 @@ neue Ermittlung.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import math
|
||||
from collections import Counter
|
||||
@@ -69,6 +70,7 @@ __all__ = [
|
||||
"load_transform",
|
||||
"save_transform",
|
||||
"registration_path",
|
||||
"file_fingerprint",
|
||||
]
|
||||
|
||||
# Rollen fuer den Lagebezug: CSV-Objektart -> Blocknamen im DXF, als Muster
|
||||
@@ -123,6 +125,10 @@ class Transform(BaseModel):
|
||||
csv_file: str = Field(default="")
|
||||
dxf_file: str = Field(default="")
|
||||
created: str = Field(default="")
|
||||
# Pruefsumme der Zeichnung/E-Datei beim Ermitteln ("" = unbekannt). Der
|
||||
# Schluessel enthaelt nur Dateinamen; ein neuer Stand gleichen Namens wird
|
||||
# daran erkannt (siehe load_transform).
|
||||
fingerprint: str = Field(default="")
|
||||
|
||||
# -- Anwenden ----------------------------------------------------------
|
||||
|
||||
@@ -329,8 +335,25 @@ def _key(csv_file: str, dxf_file: str) -> str:
|
||||
return f"{Path(csv_file).name}|{Path(dxf_file).name}"
|
||||
|
||||
|
||||
def load_transform(cfg_dir: Path, csv_file: str, dxf_file: str) -> Transform | None:
|
||||
"""Geprueften Lagebezug aus der Konfiguration lesen."""
|
||||
def file_fingerprint(path: Path) -> str:
|
||||
"""SHA-256 einer Datei (Hex) - Kennung des Planungsstands."""
|
||||
digest = hashlib.sha256()
|
||||
with path.open("rb") as handle:
|
||||
for chunk in iter(lambda: handle.read(1 << 20), b""):
|
||||
digest.update(chunk)
|
||||
return digest.hexdigest()
|
||||
|
||||
|
||||
def load_transform(cfg_dir: Path, csv_file: str, dxf_file: str,
|
||||
fingerprint: str = "") -> Transform | None:
|
||||
"""Geprueften Lagebezug aus der Konfiguration lesen.
|
||||
|
||||
Mit ``fingerprint``: nur verwenden, wenn der abgelegte Bezug fuer genau
|
||||
diesen Dateistand ermittelt wurde. Ein Eintrag ohne Pruefsumme (aeltere
|
||||
Ablage) oder mit anderer gilt als veraltet -> None, der Aufrufer ermittelt
|
||||
neu. Ohne ``fingerprint`` (z. B. tro_annotate) wie bisher nur ueber den
|
||||
Dateinamen.
|
||||
"""
|
||||
path = registration_path(cfg_dir)
|
||||
if not path.is_file():
|
||||
return None
|
||||
@@ -341,6 +364,8 @@ def load_transform(cfg_dir: Path, csv_file: str, dxf_file: str) -> Transform | N
|
||||
entry = data.get(_key(csv_file, dxf_file))
|
||||
if not entry:
|
||||
return None
|
||||
if fingerprint and entry.get("fingerprint", "") != fingerprint:
|
||||
return None
|
||||
transform = Transform.model_validate(entry)
|
||||
transform.source = "cfg"
|
||||
return transform
|
||||
|
||||
Reference in New Issue
Block a user