Globale Deklarationen zur Skeletterzeugung aus der Config laden

This commit is contained in:
2026-07-07 09:20:21 +02:00
parent b6103e205b
commit cbed41da66
3 changed files with 49 additions and 25 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
REM ================================================================ REM ================================================================
REM HundM_Fortna - Skeleton-Generator aufrufen REM HundM_Fortna - Skeleton-Generator aufrufen
REM REM
REM Liest die Eingabelisten (%PV_EINGABEN%) und erzeugt je Steuerung REM Liest die Eingabelisten (%PV_DATA%) und erzeugt je Steuerung
REM ein Skeleton der JSON-Zwischendatei sowie ein SCL-Grundgeruest REM ein Skeleton der JSON-Zwischendatei sowie ein SCL-Grundgeruest
REM nach %PV_RESULTS%. REM nach %PV_RESULTS%.
REM ================================================================ REM ================================================================
+1 -1
View File
@@ -1182,7 +1182,7 @@ Nicht aus den Listen ableitbar bleiben: Timings, Priority-Manager, Release-Ausdr
#### 14.5 Skeleton-Generator #### 14.5 Skeleton-Generator
Das Skript [lib/create_skel.py](../lib/create_skel.py) (Aufruf ueber `bin\create_skel.bat`) liest die Eingabelisten und erzeugt je Steuerung ein Skeleton der JSON-Zwischendatei (`results/skeleton_UH0x.json`) sowie ein SCL-Grundgeruest. Die SCL-Aufruf-Templates sind als globale Definitionen im Skript hinterlegt und koennen spaeter in eine `.cfg` ausgelagert werden. Das Skript [lib/create_skel.py](../lib/create_skel.py) (Aufruf ueber `bin\create_skel.bat`) liest die Eingabelisten und erzeugt je Steuerung ein Skeleton der JSON-Zwischendatei (`results/skeleton_UH0x.json`) sowie ein SCL-Grundgeruest. Die globalen Definitionen (Dateinamen, `VERW`-Vokabular, FB-Typ-Regeln, SCL-Aufruf-Templates) sind als JSON in [cfg/skel.cfg](../cfg/skel.cfg) ausgelagert und werden beim Programmstart aus `PV_CFG` geladen; ohne diese Datei laufen die im Skript eingebauten Defaults weiter (Cold-Start-faehig).
--- ---
+47 -23
View File
@@ -7,8 +7,11 @@ Datenquellen (Pfade ueber Umgebungsvariablen aus bin\\setenv.bat):
ST500592_10_5-14_ILS-<n>_TIA.xlsx (PLC Tags + Constants) ST500592_10_5-14_ILS-<n>_TIA.xlsx (PLC Tags + Constants)
ST500592_10_5-9_ILS_positions.json (Positionen, VERW, mappings) ST500592_10_5-9_ILS_positions.json (Positionen, VERW, mappings)
PV_RESULTS Zielordner fuer die erzeugten Dateien PV_RESULTS Zielordner fuer die erzeugten Dateien
PV_CFG optional: create_skel.cfg ueberschreibt die globalen PV_CFG Ordner mit skel.cfg (JSON) — enthaelt die globalen
Definitionen (Templates, Vokabular) Definitionen (Dateinamen, Vokabular, FB-Typ-Regeln,
SCL-Templates). Wird beim Programmstart geladen und
ersetzt die eingebauten Defaults vollstaendig, wenn
vorhanden. Ohne skel.cfg laufen die Defaults unten weiter.
Erzeugt je Steuerung UH01..UH05: Erzeugt je Steuerung UH01..UH05:
skeleton_UH0x.json JSON-Zwischendatei-Skeleton (Kap. 14 im skeleton_UH0x.json JSON-Zwischendatei-Skeleton (Kap. 14 im
@@ -20,7 +23,6 @@ Aufruf: bin\\create_skel.bat [--uh 1..5] [--no-scl]
""" """
import argparse import argparse
import configparser
import json import json
import os import os
import re import re
@@ -34,16 +36,22 @@ except ImportError:
sys.exit("openpyxl fehlt — bitte bin\\install_py.bat ausfuehren.") sys.exit("openpyxl fehlt — bitte bin\\install_py.bat ausfuehren.")
# ============================================================================ # ============================================================================
# GLOBALE DEFINITIONEN # GLOBALE DEFINITIONEN (eingebaute Defaults)
# Alle folgenden Bloecke sind bewusst als Modul-Konstanten definiert, damit # Alle folgenden Bloecke sind bewusst als Modul-Konstanten definiert. Sie
# sie spaeter unveraendert in eine .cfg (PV_CFG\create_skel.cfg) ausgelagert # sind zugleich der Inhalt von cfg\\skel.cfg (JSON) — load_cfg() liest diese
# werden koennen. load_cfg() ueberschreibt sie, wenn die Datei existiert. # Datei aus PV_CFG beim Programmstart und ersetzt die Defaults hier 1:1
# durch ihren Inhalt. Ohne skel.cfg (z.B. Erststart, Datei geloescht) bleiben
# die Defaults unten aktiv, das Skript funktioniert also auch dann.
# ============================================================================ # ============================================================================
#: Dateinamen der Eingabelisten ({n} = ILS-Nummer 1..5) #: Dateinamen der Eingabelisten ({n} = ILS-Nummer 1..5)
FILES = { FILES = {
"tia_xlsx": "ST500592_10_5-14_ILS-{n}_TIA.xlsx", "tia_xlsx": "ST500592_10_5-14_ILS-{n}_TIA.xlsx",
"positions_json": "ST500592_10_5-9_ILS_positions.json", "positions_json": "ST500592_10_5-9_ILS_positions.json",
# Routing / Zusammenhalt der TROs (hmf-connect-v1, extrahiert aus
# doc/TRO_Graph_UH01-UH05.dot) — fuer die kuenftige Topologie-Auswertung
"connect_json": "connect.json",
"connect_ini": "connect.ini",
} }
#: VERW-Vokabular (Positions-JSON) -> Signalrolle #: VERW-Vokabular (Positions-JSON) -> Signalrolle
@@ -270,29 +278,45 @@ FBTYPE_TEMPLATE = {
# Ende der globalen Definitionen # Ende der globalen Definitionen
# ============================================================================ # ============================================================================
#: Schluessel in skel.cfg -> Modul-Konstante, die beim Laden ersetzt wird
_CFG_KEYS = {
"files": "FILES",
"verw_roles": "VERW_ROLES",
"comment_roles": "COMMENT_ROLES",
"fbtype_rules": "FBTYPE_RULES",
"unit_re": "UNIT_RE",
"area_res": "AREA_RES",
"scl_templates": "SCL_TEMPLATES",
"fbtype_template": "FBTYPE_TEMPLATE",
}
def load_cfg(): def load_cfg():
"""Ueberschreibt die globalen Definitionen aus PV_CFG\\create_skel.cfg. """Laedt cfg\\skel.cfg (JSON) aus PV_CFG und ersetzt die globalen
Definitionen (FILES, VERW_ROLES, ..., SCL_TEMPLATES) durch ihren Inhalt.
Unterstuetzte Sektionen: [files], [verw_roles], [scl_templates]. Fehlt PV_CFG oder die Datei, bleiben die eingebauten Defaults oben aktiv
Werte in [scl_templates] sind mehrzeilige Raw-Strings. (Cold-Start-Faehigkeit ohne Konfigurationsdatei).
""" """
cfg_dir = os.environ.get("PV_CFG") cfg_dir = os.environ.get("PV_CFG", Path(__file__).resolve().parent.parent / "cfg")
if not cfg_dir: cfg_file = Path(cfg_dir) / "skel.cfg"
return
cfg_file = Path(cfg_dir) / "create_skel.cfg"
if not cfg_file.exists(): if not cfg_file.exists():
print(f"Hinweis: {cfg_file} nicht gefunden — verwende eingebaute Defaults.")
return return
print(f"Lade Konfiguration: {cfg_file}") print(f"Lade Konfiguration: {cfg_file}")
cp = configparser.ConfigParser(interpolation=None) data = json.loads(cfg_file.read_text(encoding="utf-8"))
cp.read(cfg_file, encoding="utf-8")
if cp.has_section("files"): globals_ = globals()
FILES.update(cp["files"]) for cfg_key, const_name in _CFG_KEYS.items():
if cp.has_section("verw_roles"): if cfg_key not in data:
VERW_ROLES.update(cp["verw_roles"]) continue
if cp.has_section("scl_templates"): value = data[cfg_key]
for key, val in cp["scl_templates"].items(): # Listen von Listen (comment_roles, fbtype_rules, area_res) als
SCL_TEMPLATES[key] = val.replace("\\n", "\n") # Tupel normalisieren, damit das Unpacking im Code unveraendert bleibt
if const_name in ("COMMENT_ROLES", "AREA_RES"):
value = [tuple(item) for item in value]
globals_[const_name] = value
def project_paths(): def project_paths():