tro_annotate --anlage: Staubereiche in der Zeichnung, --read-jams zurueck
Mit --anlage <csv>_anlage.json zeichnet tro_annotate je Staubereich einen Block JAM_AREA (Layer TRO_JAM): Rechteck mit dem Namen Jam<NNNN>_<k> wie in der SCL, jam_versatz vor dem Separator Richtung Vorgaenger. Attribute CONVEYOR, NUMBER, TRO + ENTRY (stabiler Schluessel), AREA, AUTO. Doppelklick oeffnet den Dialog JAM_EDIT (dxfmakros). --read-jams uebernimmt im Dialog geaenderte Nummern aus der beschrifteten Zeichnung nach cfg/<csv>_jam_names.ini (nur Abweichungen von AUTO); scl_skeleton wendet die Datei mit der Anlagen-JSON an (scl_context: jam_numbers + Korrekturen, load/save_jam_overrides). Dematic: 25 Staubereiche gezeichnet; Rundreise TRO20 -> Jam0054_9 bis in die SCL geprueft. Gemeinsame Zeichnung mit --offset 0,0 beschriften (automatischer Lagebezug waehlte dy +360 mm). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+96
-8
@@ -33,9 +33,11 @@ Wert ersetzen, Merker loeschen.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import configparser
|
||||
import re
|
||||
from collections import deque
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
@@ -64,7 +66,13 @@ __all__ = [
|
||||
"HwSource",
|
||||
"build_context",
|
||||
"flow_order",
|
||||
"JAM_NAMES_SUFFIX",
|
||||
"jam_key",
|
||||
"jam_label",
|
||||
"jam_names",
|
||||
"jam_numbers",
|
||||
"load_jam_overrides",
|
||||
"save_jam_overrides",
|
||||
"reachable_via",
|
||||
]
|
||||
|
||||
@@ -631,10 +639,88 @@ def _jam_db(area: JamArea | None, hw: HwSource,
|
||||
return (f'"DB_JamArea{nr}".stJam{nr}_____' if nr else _JAM_DB), False
|
||||
|
||||
|
||||
def jam_names(document: TroDocument, geordnet: list[TroBase],
|
||||
hw: HwSource) -> dict[str, str]:
|
||||
JAM_NAMES_SUFFIX = "_jam_names.ini"
|
||||
# Wert in der Korrekturdatei: Foerderer und laufende Nummer, "0054_3"
|
||||
_JAM_WERT = re.compile(r"^(\d{4})_(\d+)$")
|
||||
|
||||
|
||||
def jam_key(area: JamArea) -> str:
|
||||
"""Stabiler Schluessel eines Staubereichs: TRO-ID + Eingang ("TRO17.1").
|
||||
|
||||
Die Kennung J<Separator> folgt der TeileId und aendert sich mit jedem
|
||||
CSV-Export; die TRO-ID bleibt (cfg/<csv>_tro_ids.ini).
|
||||
"""
|
||||
return f"{area.tro}.{area.entry}"
|
||||
|
||||
|
||||
def jam_label(nr: str, k: int) -> str:
|
||||
"""Kurzname fuer Zeichnung und Dialog: Jam0054_3."""
|
||||
return f"Jam{nr}_{k}"
|
||||
|
||||
|
||||
def load_jam_overrides(path: Path) -> dict[str, tuple[str, int]]:
|
||||
"""Korrekturen der Staubereichs-Nummern aus ``<csv>_jam_names.ini``.
|
||||
|
||||
Abschnitt [jam], je Zeile ``<TRO-ID>.<Eingang> = <NNNN>_<k>``
|
||||
(``TRO17.1 = 0054_3``). Geschrieben von tro_annotate --read-jams aus den
|
||||
im Dialog JAM_EDIT geaenderten Staubereichen; von Hand pflegbar.
|
||||
Fehlt die Datei, gibt es keine Korrekturen.
|
||||
"""
|
||||
if not path.is_file():
|
||||
return {}
|
||||
parser = configparser.ConfigParser(inline_comment_prefixes=(";", "#"),
|
||||
interpolation=None)
|
||||
parser.optionxform = str
|
||||
with path.open(encoding="utf-8") as fh:
|
||||
parser.read_file(fh)
|
||||
result: dict[str, tuple[str, int]] = {}
|
||||
if parser.has_section("jam"):
|
||||
for key, value in parser["jam"].items():
|
||||
m = _JAM_WERT.match(value.strip())
|
||||
if not m:
|
||||
raise ValueError(f"{path.name} [jam] {key} = {value!r}: erwartet "
|
||||
f"<NNNN>_<k>, z. B. 0054_3")
|
||||
result[key.strip()] = (m.group(1), int(m.group(2)))
|
||||
return result
|
||||
|
||||
|
||||
def save_jam_overrides(path: Path, overrides: dict[str, tuple[str, int]]) -> None:
|
||||
"""Korrekturdatei neu schreiben (sortiert nach TRO-ID); leer = Datei weg."""
|
||||
if not overrides:
|
||||
if path.is_file():
|
||||
path.unlink()
|
||||
return
|
||||
zeilen = [
|
||||
"; Staubereichs-Nummern, die von der Ableitung abweichen",
|
||||
"; (scl_context.jam_names). Geschrieben von tro_annotate --read-jams aus",
|
||||
"; dem Dialog JAM_EDIT; von Hand pflegbar.",
|
||||
"; <TRO-ID>.<Eingang> = <Foerderer NNNN>_<laufende Nummer k>",
|
||||
"",
|
||||
"[jam]",
|
||||
]
|
||||
zeilen += [f"{key} = {nr}_{k}" for key, (nr, k) in sorted(overrides.items())]
|
||||
path.write_text("\n".join(zeilen) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
def jam_names(document: TroDocument, geordnet: list[TroBase], hw: HwSource,
|
||||
overrides: dict[str, tuple[str, int]] | None = None) -> dict[str, str]:
|
||||
"""Staubereichs-Namen je Kennung (J0048 -> '"DB_JamArea0042".stJam0042_1').
|
||||
|
||||
Die abgeleiteten Nummern (jam_numbers), ersetzt durch ``overrides``
|
||||
(load_jam_overrides) fuer die dort genannten Staubereiche.
|
||||
"""
|
||||
nummern = jam_numbers(document, geordnet, hw)
|
||||
for area in document.jam_areas_or_derived():
|
||||
if overrides and jam_key(area) in overrides:
|
||||
nummern[area.jam_id] = overrides[jam_key(area)]
|
||||
return {jam_id: f'"DB_JamArea{nr}".stJam{nr}_{k}'
|
||||
for jam_id, (nr, k) in nummern.items()}
|
||||
|
||||
|
||||
def jam_numbers(document: TroDocument, geordnet: list[TroBase],
|
||||
hw: HwSource) -> dict[str, tuple[str, int]]:
|
||||
"""Abgeleitete Staubereichs-Nummern je Kennung (J0048 -> ("0042", 1)).
|
||||
|
||||
Regel der SPS-Programmierer (Dematic, 2026-10-22): <NNNN> ist der
|
||||
Foerderer, auf dem der Staubereich liegt (Nummer des Kreisel- bzw.
|
||||
Vario-Motors), <k> zaehlt auf diesem Foerderer in Fliessrichtung hoch.
|
||||
@@ -706,11 +792,11 @@ def jam_names(document: TroDocument, geordnet: list[TroBase],
|
||||
if nr:
|
||||
je_foerderer.setdefault(nr, []).append(area)
|
||||
nachfolger = {t.tro_id: list(t.successors) for t in geordnet}
|
||||
namen: dict[str, str] = {}
|
||||
nummern: dict[str, tuple[str, int]] = {}
|
||||
for nr, liste in je_foerderer.items():
|
||||
for k, area in enumerate(_entlang(liste, nachfolger), start=1):
|
||||
namen[area.jam_id] = f'"DB_JamArea{nr}".stJam{nr}_{k}'
|
||||
return namen
|
||||
nummern[area.jam_id] = (nr, k)
|
||||
return nummern
|
||||
|
||||
|
||||
def _entlang(areas: list[JamArea], nachfolger: dict[str, list[str]]) -> list[JamArea]:
|
||||
@@ -908,13 +994,15 @@ def _tro_context(tro: TroBase, alle: dict[str, TroBase],
|
||||
def build_context(document: TroDocument, source: str, start_id: str = "",
|
||||
created: str | None = None,
|
||||
eplan: EplanDocument | None = None,
|
||||
anlage: AnlageDocument | None = None) -> SclFile:
|
||||
anlage: AnlageDocument | None = None,
|
||||
jam_overrides: dict[str, tuple[str, int]] | None = None) -> SclFile:
|
||||
"""TroDocument -> SclFile (TROs in Fliessrichtung).
|
||||
|
||||
anlage: Anlagen-JSON (merge_hw_layout) - ihr Layout ist ``document``,
|
||||
ihre Zuordnungen liefern die Namen. eplan: alte Zuordnung Layout ->
|
||||
E-Planung (e_planning.py), nur ohne ``anlage``. Ohne beide bleiben alle
|
||||
Namen offen und die Ausgabe ist die bisherige.
|
||||
Namen offen und die Ausgabe ist die bisherige. jam_overrides: Korrekturen
|
||||
der Staubereichs-Nummern (load_jam_overrides).
|
||||
"""
|
||||
if anlage is not None and eplan is not None:
|
||||
raise ValueError("anlage und eplan schliessen sich aus")
|
||||
@@ -924,7 +1012,7 @@ def build_context(document: TroDocument, source: str, start_id: str = "",
|
||||
for area in document.jam_areas_or_derived():
|
||||
bereiche.setdefault(area.tro, []).append(area)
|
||||
geordnet, startgrund = flow_order(document.tros, start_id)
|
||||
namen = jam_names(document, geordnet, hw)
|
||||
namen = jam_names(document, geordnet, hw, jam_overrides)
|
||||
return SclFile(
|
||||
source=source,
|
||||
created=created or datetime.now().strftime("%Y-%m-%d %H:%M"),
|
||||
|
||||
Reference in New Issue
Block a user