Compare commits

...

10 Commits

7 changed files with 413 additions and 527 deletions
+22 -19
View File
@@ -1,37 +1,40 @@
# Konfigurationsdatei, welche das Einlesen / Ignorieren bestimmter Blöcke anhand der Betriebsmittelkennzeichnung (BMK) steuert
# Configuration file that controls the reading / ignoring of certain blocks based on the equipment identification (BMK)
# Kürzel die im Routing Prozess eingebunden werden sollen
# Prefixes, that should be included in Routing-Process
[Routing-Include]
MA # Motor
MB # Ventil
QM # Ventil
BG # Stauesensor
BP # Duckluftschalter
BX # Scanner
MA
MB
QM
BG
BP
BX
# Prefixes, that should be ignored in Routing-Process
# Kürzel die im Routing Prozess ignoriert werden sollen, zum Beispiel bauteile innerhalb der Schaltschränke
# Prefixes, that should be ignored in Routing-Process, for example Equipment in Control-Cabinets
[Routing-Ignore]
FC # Motorschutzschalter
PF # Leuchtmelder
DI # Feedback von Gerät
QA # Hauptschütz
SF # Drucktaster an Schaltschrank
FC
PF
DI
QA
SF
# Mapping of Equipment-Prefixes to Cable Types found in kabel.cfg
# Zuordnung von Kürzeln zu Kabeltypen in kabel.cfg (ier zugewiesene Kabel-Sektion muss in kabel.cfg vorhanden sein und SIVAS-Nummern enthalten!)
# Mapping of Equipment-Prefixes to Cable Types found in kabel.cfg (Cable-Section must be included in kabel.cfg!!)
[Cable-Mapping]
# Format: PREFIX = Cabel-Sekcion[, Section2, ...]
# Format: PREFIX = Cable-Section[, Section2, ...]
MA = MA
MB = WD_Q
QM = WD_Q
BG = WD_I
BG-829422026 = WD_I-829422026 # Spezialfall für Sensor mit ArtiNr: 829422026
BG-720002003 = WD_I-720002003 # Spezialfall für Sensor mit ArtiNr: 720002003
BX = WF_B, WD_I # Scanner mit zwei benötigten Kabeln
BG-829422026 = WD_I-829422026
BG-720002003 = WD_I-720002003
BX = WF_B, WD_I
# Anpassung von berechneter kabellänge um Betrag x aufgrund von z.b. an Sensor existierenden Kabelschwänzen
# Adjustment of Cable-Lenght's due to for example existing connection cables on sensor
[Length-Adjustments]
# Format: PREFIX = Length (m) to subtract
+23 -4
View File
@@ -1,4 +1,9 @@
# Layernamen, auf denen Pritschen liegen
# Allgemeine Konfigurationsdatei, welche die einzulesenden Layer, sowie geometrische Abhängigkeiten steuert.
# General Config-File, that controls the Layers being read while processing a certain dxf file
# Layernamen der Kabeltrassen
# Layernames of Racks
[GetPos-Layer_Racks]
PRITSCHE_100-60-SCHRAFF
PRITSCHE_200-60
@@ -15,6 +20,9 @@ PRITSCHE_200-60_OMNIFLO
0-0_Omniflo_Pritsche_200-60_AMR
0-0_Omniflo_Pritsche_200-60_Highway
# Layernamen der Unterverteiler
# Layernames of Subdistributors
[GetPos-Layer_Distributors]
Busverteiler-Kennzeichnung
#0-0_ILS_Bereich-Busverteiler
@@ -24,9 +32,14 @@ Busverteiler-Kennzeichnung
UNTERVERTEILER
0-0_Omniflo_Busverteiler-Kennzeichnung
# Layernamen der Tunnel
# Layernames of Tunnels
[GetPos-Layer_Tunnel]
Busverteiler-Kennzeichnung
# Layernamen des Equipments (Sensoren, Motoren, etc.)
# Layernames of Equipment (Sensors, Motors, etc.)
[GetPos-Layer_Equipment]
0
REALE_POSITION_IO
@@ -47,16 +60,22 @@ MOTOR
# Hoehe = 350
# not used!
# Geometrische Infomationen des Markers, um exakte Mitte zu bestimmen
# Geometric Infomation of Sensor-Marker to determine exact center
[GetPos-Geom-Sensor]
Breite = 80
Hoehe = 90
# Vorgaben für die Toleranzen
# bei den Kabelpritschen
# Geometrische Toleranz bei der Verbindung zweier Racks zueinander
# Geometric tolerance for the connection (Snapping) of two adjacent racks
[Racks]
SnapTolerances=200.
# bei den Sensoren
# Geometrische Toleranz bei der Verbindung eines Sensors / Motors / etc. zu einem naheliegenden Rack
# Geometric tolerance for the connection of a Sensor / Motor / etc. to an adjacent rack
[Sensoren]
ConnectionTolerances=3000.
+12 -1
View File
@@ -1,8 +1,14 @@
# Konfigurationsdatei, welche die Zuweisung von längenabhängigen SIVAS-Nummern der einzelnen Kabelkategorien beinhaltet
# Config-File that includes length-dependet SIVAS-numbers to its cable-prefix
# Kabel für die Motoren
# General Motor-Cables
[MA]
100.0=725000015
# Kabel für die Ventile
# Cables for valves
[WD_Q]
1.0=722001300
2.0=722001301
@@ -19,6 +25,7 @@
50.0=722001312
# Kabel für Default Sensoren
# Cables for default sensors
[WD_I]
1.0=722001330
2.0=722001331
@@ -35,6 +42,7 @@
50.0=722001342
# Kabel für Sensor 829422026
# cables for sensor 829422026
[WD_I-829422026]
2.5=722001358
3.0=722001352
@@ -47,6 +55,7 @@
# Kabel für Sensor 720002003
# cables for sensor 720002003
[WD_I-720002003]
2.5=722001358
3.0=722001352
@@ -57,7 +66,8 @@
30.0=722001357
40.0=722001359
# Daten-Kabel für Scanner (Patchkabel)
# Daten-Kabel für Scanner (Patchkabel gruen)
# Data-cable for scanners (Patchcable green)
[WF_B]
0.25=726001062
0.5=726001040
@@ -83,6 +93,7 @@
# Bezeichner jeder Verbindungsleitung (gekürzt)
# Name of every cable (shortened)
[Sivasnummern]
725000015=4G1,5mm², Steuerleitung
722001300=M12 St-0°/ M8 Bu-0° 1m
+273 -22
View File
@@ -1,13 +1,36 @@
- [Anwenderdoku zur Ermittlung der Kabellängen](#anwenderdoku-zur-ermittlung-der-kabellängen)
- [Installation des Programmes und Schnellstart-Guide](#installation-des-programmes-und-schnellstart-guide)
- [Installation](#installation)
- [Schnellstart und Vewendung des Programms](#schnellstart-und-vewendung-des-programms)
- [Standardmäßige Ausgabe des Programms](#standardmäßige-ausgabe-des-programms)
- [Detaillierte Informationen und Programmablauf](#detaillierte-informationen-und-programmablauf)
- [Zweck des Programms](#zweck-des-programms)
- [Allgemeiner Programmablauf](#allgemeiner-programmablauf)
- [Aufruf des Programms](#aufruf-des-programms)
- [Ausgabe des Toolsets](#ausgabe-des-toolsets)
# Anwenderdoku zur Ermittlung der Kabellängen <!-- omit in toc -->
- [Installation des Programmes und Schnellstart-Guide](#installation-des-programmes-und-schnellstart-guide)
- [Installation](#installation)
- [Schnellstart und Vewendung des Programms](#schnellstart-und-vewendung-des-programms)
- [Standardmäßige Ausgabe des Programms](#standardmäßige-ausgabe-des-programms)
- [.dxf-Datei: dxfdatei\_cables.dxf](#dxf-datei-dxfdatei_cablesdxf)
- [Excel-Datei: xxx\_cables.xlsx](#excel-datei-xxx_cablesxlsx)
- [Anpassung des Verhaltens des Programms:](#anpassung-des-verhaltens-des-programms)
- [Verwendete Konfigurationsdateien](#verwendete-konfigurationsdateien)
- [Zusammenfassung und Struktur der Konfigurationsdateien](#zusammenfassung-und-struktur-der-konfigurationsdateien)
- [allgemein.cfg](#allgemeincfg)
- [`[GetPos-Layer_Racks]`](#getpos-layer_racks)
- [`[GetPos-Layer_Distributors]`](#getpos-layer_distributors)
- [`[GetPos-Layer_Tunnel]`](#getpos-layer_tunnel)
- [`[GetPos-Layer_Equipment]`](#getpos-layer_equipment)
- [`[GetPos-Geom-Sensor]`](#getpos-geom-sensor)
- [`[Racks]`](#racks)
- [`[Sensoren]`](#sensoren)
- [BMK.cfg](#bmkcfg)
- [`[Routing-Include]`](#routing-include)
- [`[Routing-Ignore]`](#routing-ignore)
- [`[Cable-Mapping]`](#cable-mapping)
- [`[Length-Adjustments]`](#length-adjustments)
- [kabel.cfg](#kabelcfg)
- [Kabelgruppen (Beispiel: `[WD_Q]`, `[WD_I]`, `[WF_B]`)](#kabelgruppen-beispiel-wd_q-wd_i-wf_b)
- [Sensorspezifische Gruppen](#sensorspezifische-gruppen)
- [`[Sivasnummern]`](#sivasnummern)
- [Detaillierte Informationen zum Programmablauf und Code-Struktur](#detaillierte-informationen-zum-programmablauf-und-code-struktur)
- [Zweck des Programms](#zweck-des-programms)
- [Allgemeiner Programmablauf](#allgemeiner-programmablauf)
- [Aufruf des Programms](#aufruf-des-programms)
- [Ausgabe des Toolsets](#ausgabe-des-toolsets)
- [Informationen zu den Einzelprogrammen](#informationen-zu-den-einzelprogrammen)
- [Details zu `getpositions.py`](#details-zu-getpositionspy)
- [Details zu `routing.py`](#details-zu-routingpy)
@@ -18,12 +41,9 @@
- [Warum verbindet das Programm den Sensor mit genau dieser Kabeltrasse?](#warum-verbindet-das-programm-den-sensor-mit-genau-dieser-kabeltrasse)
- [Ideen für "Umbau" der Programme](#ideen-für-umbau-der-programme)
# Installation des Programmes und Schnellstart-Guide
# Anwenderdoku zur Ermittlung der Kabellängen
## Installation des Programmes und Schnellstart-Guide
### Installation
## Installation
Das Programm mit allen Quellen befindet sich auf dem hauseigenen git Server und kann mit einen beliebigen git client auf einem Anwenderrechner über ``` git clone http://gitea.schoenenberger.de/mistangl/kabellaengen.git``` geholt werden.
Dieser Ordner kann auch einfach mit allen Unterordnern gezippt und auf einem anderen Rechner entpackt werden.
@@ -35,7 +55,7 @@ Zur Installation des Kabeltools muss in dem geclonten Ordner `kabellaengen\bin`
Ist Python installiert, werden per Doppelklick automatisch auf die `bin\install_py.bat` alle nötigen python Package heruntergeladen. Diese werden dann automatisch aus dem Netz in den .venv kopiert.
### Schnellstart und Vewendung des Programms
## Schnellstart und Vewendung des Programms
Im auf dem Desktop erzeugten Ordner findet sich das eigentliche Programm *create_cables*. Um das Programm auszuführen, genügt es die zu verarbeitende .**dxf-Datei** per *Drag and Drop* auf das Programm zu ziehen. Das öffnen der *Command-Shell* bestätigt den Start des Programms und der Anwender wird über den Ablauf informiert.
@@ -70,7 +90,8 @@ Drücken sie eine beliebige Taste . . .
Das Drücken einer beliebigen Taste beendet das Programm und die Ausgabe kann verwendet werden.
### Standardmäßige Ausgabe des Programms
## Standardmäßige Ausgabe des Programms
In den Ordner auf dem Desktop in dem das Kabeltool liegt werden nach Beendigung der Berechnungen die Ausgabedateien abgelegt. Standardmäßig sind dies fünf Dateien, wovon letztlich drei für den Anwender bestimmt sind. In der nachfolgenden Liste steht der name *dxfdatei* stellvertretend für die eingegebene Datei des Benutzers.
| Dateiname | Details |
@@ -81,10 +102,240 @@ In den Ordner auf dem Desktop in dem das Kabeltool liegt werden nach Beendigung
| `dxfdatei_positions` | **Zwischendatei** (nicht für Endnutzer bestimmt) |
| `dxfdatei_todraw` | **Zwischendatei** (nicht für Endnutzer bestimmt) |
### .dxf-Datei: dxfdatei_cables.dxf
## Detaillierte Informationen und Programmablauf
Die standardmäßig erstellte und abgelegte Ausgabedatei `dxfdatei_cables.dxf` enthält die Kabelwege aller während des Programmablaufs behandelten Kabelverbindungen und kann beispielsweise als neues Layer in die .dxf-Datei der Anlage importiert werden. Neben den Kabelwegen werden auch die Kurzbezeichnungen (z.b. MA0060, BG3240, ...) sowie die Kürzel der Unterverteiler auf jeweils separaten Layern in die Zeichnungsdatei exportiert und ermöglichen damit die in sich schlüssige Verwendung dieser Datei.
### Zweck des Programms
### Excel-Datei: xxx_cables.xlsx
Die standardmäßig erstellte und abgelegte Ausgabedatei `dxfdatei_cables.xlsx` enthält im fehlerfreien Fall zwei Worksheets:
1. **Length by ID**: zeigt die Kabel-ID, die tatsächliche Länge des Kabels, die Kabel-Atikelnummer und zuletzt den zugeörigen (aber gekürzten Bezeicher) für das Kabel:
> | Cable-ID | True Length (m) | Cable-ArtNr | Cable-Name (short) |
> |-----------------|------------------|-------------|----------------------------------|
> | UC0101-BG3241 | 2,9213 | 722001332 | M12 St-0°/ M12 Bu-90° 3m |
> | UC0101-BG3240 | 7,1784 | 722001334 | M12 St-0°/ M12 Bu-90° 10m |
> | UC0101-BG3270 | 15,4686 | 722001336 | M12 St-0°/ M12 Bu-90° 20m |
> | UC0101-BG3260 | 27,4471 | 722001339 | M12 St-0°/ M12 Bu-90° 30m |
> | UH01-MA0062 | 10,3015 | 725000015 | 4G1,5mm², Steuerleitung |
2. **Cables SIVAS**: zeigt die SIVAS-Nummer der Kabel und daneben die benötigte Anzahl an Kabeln in diesem Layout bzw. (für den Fall von Kabeln als Meterware, z.b. bei Motoren) die kummulierte benötigte Länge:
> | Cable-ArtNr | Amount (pcs) | Cumm. Length (m) |
> |-------------|--------------|------------------|
> | 722001332 | 1 | |
> | 722001334 | 1 | |
> | 722001336 | 1 | |
> | 722001339 | 1 | |
> | 725000015 | | 11 |
Für den Fall, dass während des Programmablaufs Fehler auftreten bzw. Fehler im Layout erkannt werden, werden diese in weitere Worksheets geschrieben. Diese Worksheets tragen das Präfix *ERR*
- ERR-Equipment-Connection:
- Zeigt alle nicht mit den Kabeltrassen verbundenen Elemente (Sensoren / Aktoren / Unterverteiler) an
- Gibt neben dem Typen, den Bezeichner und die x, y-Koordinate des Elements zurück
- Verbindungsfehler möglicherweise aufgrund zu großen Abstandes zur nächsten Kabeltrasse
- ERR-Routing:
- Zeigt alle fehlgeschlagenen Kabelverbindungen an
- Fallunterscheidung:
- Unterverteiler nicht in Layout vorhanden: Unterverteiler ist in der Kennzeichnung der Sensor-Blöcke im Layout erwähnt aber nicht im Layout selbst positioniert. Es wird nur der betroffene Unterverteiler angezeigt. Keine explizite Auflistung aller damit ebenfalls nicht verbundenen Sensoren / Aktoren
- Unterverteiler **und** Sensor / Aktor nicht angebunden: Sowohl Sensor als auch Aktor sind nicht mit den Kabeltrassen verbunden. Beide damit auch in *ERR-Equipment-Conncetion* aufgeführt
- Unterverteiler nicht angebunden: siehe oben.
- Sensor / Aktor nicht angebunden siehe oben.
- ERR-Attributes:
- Zeigt alle Blöcke an, welche Fehler in deren Attributen aufweisen
- Mögliche Fehler:
- Kein Attribut "KENNZEICHNUNG": keine Zuweisung zu Unterverteiler möglich. Element wird nicht verkabelt und nicht gezeichnet.
- Ungültiger Pfad in "KENNZEICHNUNG": Eingegebenes Attribut in Kennzeichnung entspricht nicht dem normalen Muster. Element wird nicht verkabelt und nicht gezeichnet.
# Anpassung des Verhaltens des Programms:
## Verwendete Konfigurationsdateien
Zum aktuellen Zeitpunkt verwendet bzw. berücksichtigt das Programm **drei** Konfigurationsdateien (Dateiendung .cfg). Diese steuern das verhalten des Programms und **können vom Nutzer bei Bedarf geändert** werden bzw. **müssen vom Nutzer im Falle von betrieblichen Ändeurngen aktualisiert werden** (z.B Änderung von Sachnummern), um die Funktion des Programms zu gewährleisten. In der folgenden Tabelle sind die Aufgaben bzw. inhalte der einzelnen Konfigurationsdateien aufgezeigt und in den darauffolgenden Abschnitten der jeweilige Aufbau und besonderheiten erläutert.
| Datei | Inhalt |
|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| allgemein.cfg | Layernamen der Kabelpritschen<br>Layenamen der Unterverteiler<br>Layernamen der Tunnel<br>Layernamen der Sensoren / Aktoren<br>Toleranz der Verbindung zw. Sensor und Kabeltrasse<br>Toleranz des "Anpinnens" zweier Kabeltrassen untereinander |
| BMK.cfg | Betriebsmittelkennzeichnung der Elemente, die im Routing berücksichtigt bzw. ignoriert werden sollen<br>Zuweisung der Kabelkennzeichnungen zur jeweiligen Betriebsmittelkennzeichnung<br>Längenanpassungen für einzelne Kabelkennzeichnungen |
| kabel.cfg | SIVAS-Nummern für die einzelnen längenabhängigen Kabel der jeweiligen Kabelkennzeichnung<br>Bezeichner für die jeweilige SIVAS-Nummer |
| | |
## Zusammenfassung und Struktur der Konfigurationsdateien
Nachfolgende Aufzählung zeigt zeigt den Aufbau und Zweck der `.cfg`-Dateien für das Routing-Tool. Jeder Abschnitt ist dokumentiert mit:
- Konfigurations-Block (Abschnittsname)
- Beschreibung der Funktion
- Beispielhafte Einträge
### allgemein.cfg
Diese Datei steuert das Einlesen von Layern und definiert geometrische Toleranzen.
#### `[GetPos-Layer_Racks]`
**Was?** Layernamen, in denen Kabelpritschen (Racks) enthalten sind.
| Layername (Beispiel) |
|----------------------------------------|
| PRITSCHE_200-60_OMNIFLO |
| 0-0_ILS_Pritsche_200-60_Inbound |
| 0-0_Omniflo_Pritsche_200-60_AMR |
---
#### `[GetPos-Layer_Distributors]`
**Was?** Layernamen, die Unterverteiler beinhalten.
| Layername (Beispiel) |
|----------------------------------|
| 0-0_ILS_UNTERVERTEILER |
| UNTERVERTEILER |
---
#### `[GetPos-Layer_Tunnel]`
**Was?** Layernamen für Tunnel, oft identisch mit Distributor-Markern.
| Layername (Beispiel) |
|-----------------------------|
| Busverteiler-Kennzeichnung |
---
#### `[GetPos-Layer_Equipment]`
**Was?** Layernamen von Sensoren, Motoren, IOs etc.
| Layername (Beispiel) |
|------------------------------|
| 0-0_ILS_MOTOR |
| MOTOR |
| REALE_POSITION_IO |
---
#### `[GetPos-Geom-Sensor]`
**Was?** Geometrische Maße von Sensor-Markern zur Mittelpunktsberechnung.
| Attribut | Wert (Beispiel) |
|----------|-----------------|
| Breite | 80 |
| Hoehe | 90 |
---
#### `[Racks]`
**Was?** Maximale Distanz (Toleranz) zwischen benachbarten Racks zum "Snappen".
| Attribut | Wert (Beispiel) |
|------------------|-----------------|
| SnapTolerances | 200 |
---
#### `[Sensoren]`
**Was?** Maximale Distanz zwischen Sensoren/Motoren und Racks für Verknüpfung.
| Attribut | Wert (Beispiel) |
|----------------------|-----------------|
| ConnectionTolerances | 3000 |
---
### BMK.cfg
Diese Datei steuert, **welche Betriebsmittelkennzeichen (BMK)** beim Routing berücksichtigt werden und welche **Kabeltypen** zugewiesen sind.
#### `[Routing-Include]`
**Was?** BMK-Kürzel, die beim Routing **berücksichtigt** werden.
| Kürzel | Bedeutung / Beispiel |
|--------|----------------------|
| MA | Motoren |
| QM | Ventile |
| BX | Scanner |
---
#### `[Routing-Ignore]`
**Was?** BMKs, die ignoriert werden (z.B. Schaltschrank-Innenleben).
| Kürzel | Beispielkomponente |
|--------|----------------------------|
| FC | Frequenzumrichter |
| QA | Sicherungen / Schütze |
---
#### `[Cable-Mapping]`
**Was?** Verknüpfung von BMKs zu Kabelgruppen (aus `kabel.cfg`).
| BMK | Zugewiesene Kabelgruppe(n) |
|-------------|--------------------------------|
| MA | MA |
| MB | WD_Q |
| BX | WF_B, WD_I |
| BG-829422026| WD_I-829422026 |
---
#### `[Length-Adjustments]`
**Was?** Korrektur von Kabellängen (z.B. vorkonfektionierte Sensorleitungen).
| BMK | Abzuziehende Länge (m) |
|-----|------------------------|
| BX | 4 |
---
### kabel.cfg
Diese Datei enthält die **SIVAS-Nummern je Kabellänge und -typ**, sowie die **Bezeichnungen** der SIVAS-Nummern.
#### Kabelgruppen (Beispiel: `[WD_Q]`, `[WD_I]`, `[WF_B]`)
**Was?** Zuordnung von Kabellängen zu SIVAS-Sachnummern.
| Länge (m) | SIVAS-Nr. | Beispielgruppe |
|-----------|------------|----------------|
| 1.0 | 722001300 | WD_Q (Ventile) |
| 2.5 | 722001338 | WD_I (Sensoren)|
| 5.0 | 726001045 | WF_B (Scanner) |
---
#### Sensorspezifische Gruppen
**Was?** Besondere Kabellisten für spezifische Sensor-Artikelnummern.
| Gruppe | Länge (m) | SIVAS-Nr. |
|---------------------|-----------|-------------|
| WD_I-829422026 | 5.0 | 722001353 |
| WD_I-720002003 | 10.0 | 722001354 |
---
#### `[Sivasnummern]`
**Was?** Menschlich lesbare Bezeichnungen der SIVAS-Nummern.
| SIVAS-Nr. | Bezeichnung |
|-----------|----------------------------------|
| 722001303 | M12 St-0°/ M8 Bu-0° 5m |
| 726001041 | Patchkabel 2xRJ45 1,0m |
| 725000015 | 4G1,5mm², Steuerleitung |
---
**Hinweis:**
Die Einträge in den `.cfg`-Dateien müssen **laufend gepflegt** werden, wenn sich:
- Layernamen in CAD-Dateien ändern
- Neue BMK-Kürzel eingeführt werden
- Neue SIVAS-Artikel hinzukommen
Nur so kann eine korrekte automatische Kabelberechnung und Zuordnung gewährleistet werden.
# Detaillierte Informationen zum Programmablauf und Code-Struktur
## Zweck des Programms
Dieses Toolset dient der **automatisierten** und **komfortablen** Ermittlung von Kabellängen zwischen Unterverteilern und deren zugeordneten Sensoren/Aktoren entlang definierter Kabeltrassen. Als **Eingabe** dient eine 2D-Layout-Zeichnung im `.dxf`-Format. **Ausgaben** sind u.a.:
@@ -93,7 +344,7 @@ Dieses Toolset dient der **automatisierten** und **komfortablen** Ermittlung von
- eine weitere .dxf-Datei mit einem reduzierten Layout (Kabeltrassen + Kabel + Unterverteiler)
- zukünftig: tabellarische Aufbereitung der Kabellängen mit SIVAS-Nummern (z.B. `.xlsx`)
### Allgemeiner Programmablauf
## Allgemeiner Programmablauf
Das Toolset besteht aus drei zentralen Skripten, die automatisiert über **ein** *Batch-Skript* aufgerufen werden. Der interne Programmablauf ist folgender:
@@ -101,7 +352,7 @@ Das Toolset besteht aus drei zentralen Skripten, die automatisiert über **ein**
Das erste Programm extrahiert aus der .dxf-Datei sämtliche Informationen über die Positionen von Sensoren / Aktoren und Unterverteilern sowie den Kabeltrassen. Das zweite Programm baut aus den Informationen ein Modell der Anlage auf und verknüpft die Elemente entlang der kürzesten Wege. Das letzte Programm zeichnet eine neue .dxf-Datei, in welcher die Kabelwege von den Unterverteilern zu den Sensoren dargestellt sind.
### Aufruf des Programms
## Aufruf des Programms
Der einfachste Weg, das Toolset zu starten, ist per *Drag-and-Drop*. Hierfür muss lediglich die .dxf-Datei, für die die Kabelführung und -auswertung durchgeführt werden soll, auf die Verknüpfung namens *Kabeltool* gezogen werden. Es öffnet sich eine sogenannte *Command-Shell*, die den Benutzer über den aktuellen Zustand des Programmablaufs informiert.
@@ -120,7 +371,7 @@ done
done
```
### Ausgabe des Toolsets
## Ausgabe des Toolsets
Alle drei oben genannten Teilprogramme erzeugen eine eigene Ausgabedatei. Die Ergebnisse der ersten beiden Programme dienen als Eingabe für die folgenden. Jedes der genutzten Programme besitzt eine eingebaute Hilfe, wenn man das Programm mit dem Schalter --help aufruft.
+33 -17
View File
@@ -273,7 +273,7 @@ def export_excel(plines, out_path):
def write_excel_from_json(plines:Polylines, outpath:str):
wb = Workbook()
sens2cable = map_sensor_to_cable(plines)
sens2cable = map_sensor_to_cable_cfg(plines)
# Dicts für Anzahl bzw kummulierte Länge
count_summary = defaultdict(int)
length_summary = defaultdict(float)
@@ -283,11 +283,16 @@ def write_excel_from_json(plines:Polylines, outpath:str):
ws1.title = "Length by ID"
ws1.append(["Cable-ID", "True Length (m)", "Cable-ArtNr", "Cable-Name (short)"])
ws1.column_dimensions['A'].width = 18
ws1.column_dimensions['B'].width = 15
ws1.column_dimensions['C'].width = 15
ws1.column_dimensions['D'].width = 25
for pl in plines.kabel:
length = pl.length /1000 # Umrechnung von mm in m
for artnr in sens2cable[pl.id]:
cable_name = ""
if artnr != "Kabel länger als max. Kabellänge":
if artnr.isdigit():
cable_name = cable_cfg["Sivasnummern"][artnr]
ws1.append([pl.id, length, artnr, cable_name])
@@ -301,6 +306,10 @@ def write_excel_from_json(plines:Polylines, outpath:str):
ws2 = wb.create_sheet("Cables SIVAS")
ws2.append(["Cable-ArtNr", "Amount (pcs)", "Cumm. Length (m)"])
ws2.column_dimensions['A'].width = 20
ws2.column_dimensions['B'].width = 12
ws2.column_dimensions['C'].width = 15
all_artnrs = set(count_summary.keys()) | set(length_summary.keys())
for artnr in sorted(all_artnrs):
@@ -315,6 +324,9 @@ def write_excel_from_json(plines:Polylines, outpath:str):
# Worksheet 3 - Nicht an Racks gekoppeltes Equipment
ws3 = wb.create_sheet("ERR-Equipment-Connection")
ws3.append(["Type", "ID", "x", "y"])
ws3.column_dimensions['A'].width = 20
# nicht angebundene Sensoren
for error in plines.errors_sensors:
ws3.append(["Sensor / Actuator", error.name, error.coords.x, error.coords.y])
@@ -328,6 +340,8 @@ def write_excel_from_json(plines:Polylines, outpath:str):
ws4 = wb.create_sheet("ERR-Routing")
ws4.append(["Subdistributor", "Sensor / Actuator", "Details"])
ws4.column_dimensions['C'].width = 35
nicht_angebunden = set(e.name for e in plines.errors_sensors + plines.errors_dists)
for routing_error in plines.errors_routing:
@@ -357,6 +371,7 @@ def write_excel_from_json(plines:Polylines, outpath:str):
# Worksheet 5 - Fehlende Attribute -> kein Routing
ws5 = wb.create_sheet("ERR-Attributes")
ws5.append(["ID", "Error Detail"])
ws5.column_dimensions['B'].width = 35
for sname, err_msg in plines.errors_missing_attributes.items():
ws5.append([sname, err_msg])
@@ -434,20 +449,21 @@ def copy_layers_into_dxf_by_filter(dxf_source: ezdxf.document.Drawing, dxf_targe
def get_cable_artnr(section, length):
"""
Sucht in der angegebenen Config-Section die passende Kabel-Artikelnr. für die gegebene Länge.
Übergibt bei Treffer True, artnr
bei Fehler: False, errmsg
"""
# Existiert über BMK vergebene Kabel-Kennzeichnung in kabel.cfg?
if section not in cable_cfg:
return None
return False, f"Keine Kabelkennzeichnung '{section}' in kabel.cfg"
entries = cable_cfg[section]
# Alle Einträge der Form: "5" = "123456789"
length_keys = sorted([float(k) for k in entries.keys()])
for l in length_keys:
if length <= l:
return entries[str(l)] # Annahme: Keys sind ganze Zahlen in Metern
return True, entries[str(l)]
return None
return False, f"Kabel länger als max. Kabellänge in Sektion '{section}'"
def map_sensor_to_cable(plines):
sens2cable = defaultdict(list)
@@ -499,34 +515,34 @@ def map_sensor_to_cable_cfg(plines):
for pl in plines.kabel:
sensor_name = pl.id.split('-')[-1]
cable_length = pl.length/1000
cable_length = round(pl.length/1000, 1)
sensor_artinr = pl.s_artinr
name_prefix = sensor_name[:2]
# Suche nach Key in der BMK-Config
key_with_artnr = f"{name_prefix}-{sensor_artinr}"
key_with_artnr = f"{name_prefix}-{sensor_artinr}" # Spezialfälle über "Key mit Artikelnummer" abgleichen
if key_with_artnr in mapping:
section_list = mapping[key_with_artnr]
elif name_prefix in mapping:
elif name_prefix in mapping: # Standardzuweisung
section_list = mapping[name_prefix]
else:
sens2cable[pl.id].append("Kein Kabeltyp zugewiesen")
sens2cable[pl.id].append("Kein Kabeltyp zugewiesen (BMK.cfg)")
# Liste aus evtl. mehreren Sektionen erzeugen
sections = [s.strip for s in section_list.split(",")]
sections = [s.strip() for s in section_list.split(",")]
# Evtl. Kabelkürzung durchführen, fall Kabelschwanz vorhanden
# Evtl. Kabelkürzung durchführen, falls Kabelschwanz vorhanden
if config_BMK.has_section("Length-Adjustments") and config_BMK.has_option("Length-Adjustments", name_prefix):
length_reduction = float(config_BMK.get("Length-Adjustments", name_prefix))
cable_length = max(0.0, cable_length-length_reduction)
# Kabel-Atikelnummer innerhalb der Sektion der kabel.cfg bestimmen
for section in sections:
cable_artnr = get_cable_artnr(section, cable_length)
if cable_artnr is None:
sens2cable[pl.id].append(f"Kabel länger als max. Kabellänge")
sucess, result = get_cable_artnr(section, cable_length)
if not sucess:
sens2cable[pl.id].append(result)
else:
sens2cable[pl.id].append(cable_artnr)
sens2cable[pl.id].append(result)
return sens2cable
+50 -3
View File
@@ -83,6 +83,9 @@ def get_type_of_name_cfg(name):
return "unknown"
def get_attributes_of_insert(insert):
'''
Hier in Zukunft weniger Abfragen: IO und B und Reale_Position wird überflüssig wenn jeder Sensor nur noch eiun Block mit allen Attributen!
'''
id = ""
ld = dict()
typ = 'unknown'
@@ -95,7 +98,7 @@ def get_attributes_of_insert(insert):
ld[attr_tag] = attr_text
if attr_tag == "IO":
typ = get_type_of_name(attr_text)
typ = get_type_of_name_cfg(attr_text)
id = attr_text
#print(f"-- coord io {id}--: {attrib.dxf.insert}") # position des Blocks
pos = attrib.dxf.insert #Position aufzeichnen und bei Bedarf später mit REAL_POS überschreiben
@@ -103,7 +106,7 @@ def get_attributes_of_insert(insert):
if attr_tag == "B":
# Suche nach Sensoren
typ = get_type_of_name(attr_text)
typ = get_type_of_name_cfg(attr_text)
id = attr_text
pos = attrib.dxf.insert #Position aufzeichnen und bei Bedarf später mit REAL_POS überschreiben
ld["pos"] = (round(pos.x, 1), round(pos.y, 1))
@@ -155,7 +158,7 @@ def get_input_positions(msp) -> tuple:
def get_input_positions_iter(dxf_path) -> tuple:
return extract_input_positions(iterdxf.modelspace(dxf_path))
def create_mappings(positions:dict) -> dict:
def create_mappings(positions:dict) -> tuple:
unterverteiler_pfad = ""
dnamen = dict()
# sammle die Sensoren mit ihren zugehörigen Unterverteilern
@@ -415,6 +418,43 @@ def dxf_is_binary(dxf_path):
header = f.read(22)
return b'AutoCAD Binary DXF' in header
def validate_configs():
errors= []
print("Validating given configs: Checking for inconsistency.")
# 1. Alle Prefixes aus Routing_include müssen in Cable_Mapping stehen (nur BMK.cfg)
if config_BMK.has_section("Routing-Include") and config_BMK.has_section("Cable-Mapping"):
for prefix in config_BMK.options("Routing-Include"):
if prefix not in config_BMK["Cable-Mapping"]:
errors.append(f"No Cable-Mapping for Prefix '{prefix}' within 'Routing-Include'")
# 2. Jeder Eintrag in Cable-Mapping → Sektionen in kabel.cfg prüfen (Abgleich BMK.cfg und kabel.cfg)
if config_BMK.has_section("Cable-Mapping"):
for mapping_key, value in config_BMK.items("Cable-Mapping"):
sections = [s.strip() for s in value.split(",")]
for section in sections:
if not config_cables.has_section(section):
errors.append(f"Cable-Section '{section}' from Cable-Mapping ({mapping_key}) missing in kabel.cfg")
# 3. Länge in Length-Adjustments muss float >= 0 sein
if config_BMK.has_section("Length-Adjustments"):
for prefix, value in config_BMK.items("Length-Adjustments"):
try:
f = float(value)
if f < 0:
errors.append(f"Negative Value in Length-Adjustments for {prefix}: {value}")
except ValueError:
errors.append(f"Invalid Value in Length-Adjustments for {prefix}: {value}")
if errors:
print("Inconsistencies found:")
for e in errors:
print(f"- {e}")
print("continuing")
else:
print ("No inconsistencies found")
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='fetches the x/y positions from a dxf file', prog='getpositions')
@@ -460,6 +500,13 @@ if __name__ == '__main__':
config_BMK = configparser.ConfigParser(allow_no_value=True, delimiters=("="))
config_BMK.optionxform = lambda option: option # preserve case for letters
config_BMK.read(os.path.join(config_dir, "BMK.cfg"))
# Kabel-Config laden
config_cables = configparser.ConfigParser(allow_no_value=True, delimiters=("="))
config_cables.optionxform = lambda option: option
config_cables.read(os.path.join(config_dir, "kabel.cfg"))
validate_configs()
output_results = dict()
-461
View File
@@ -1,461 +0,0 @@
{
"kabel": [
{
"id": "UC0101-BG3241",
"coords": [
{
"x": 0.0,
"y": 4162.8
},
{
"x": 0.1,
"y": 3777.6
},
{
"x": 0.1,
"y": 1280.2
},
{
"x": 38.8,
"y": 1280.2
}
],
"length": 2921.3,
"tunnel_indices": []
},
{
"id": "UC0101-BG3240",
"coords": [
{
"x": 0.0,
"y": 4162.8
},
{
"x": 0.1,
"y": 3777.6
},
{
"x": 2866.6,
"y": 3777.6
},
{
"x": 4946.5,
"y": 3777.6
},
{
"x": 4946.5,
"y": 3879.4
},
{
"x": 4946.5,
"y": 5609.0
},
{
"x": 4700.0,
"y": 5609.0
}
],
"length": 7178.4,
"tunnel_indices": []
},
{
"id": "UC0101-BG3270",
"coords": [
{
"x": 0.0,
"y": 4162.8
},
{
"x": 0.1,
"y": 3777.6
},
{
"x": 2866.6,
"y": 3777.6
},
{
"x": 4946.5,
"y": 3777.6
},
{
"x": 4946.5,
"y": 3879.4
},
{
"x": 4946.5,
"y": 5609.0
},
{
"x": 4946.5,
"y": 8072.5
},
{
"x": 4946.5,
"y": 12968.1
},
{
"x": 5893.0,
"y": 12968.1
}
],
"length": 15468.6,
"tunnel_indices": []
},
{
"id": "UC0101-BG3272",
"coords": [
{
"x": 0.0,
"y": 4162.8
},
{
"x": 0.1,
"y": 3777.6
},
{
"x": 2866.6,
"y": 3777.6
},
{
"x": 4946.5,
"y": 3777.6
},
{
"x": 4946.5,
"y": 3879.4
},
{
"x": 4946.5,
"y": 5609.0
},
{
"x": 4946.5,
"y": 8072.5
},
{
"x": 4946.5,
"y": 12968.1
},
{
"x": 5893.0,
"y": 12968.1
}
],
"length": 15468.6,
"tunnel_indices": []
},
{
"id": "UC0101-BG3271",
"coords": [
{
"x": 0.0,
"y": 4162.8
},
{
"x": 0.1,
"y": 3777.6
},
{
"x": 2866.6,
"y": 3777.6
},
{
"x": 4946.5,
"y": 3777.6
},
{
"x": 4946.5,
"y": 3879.4
},
{
"x": 4946.5,
"y": 5609.0
},
{
"x": 4946.5,
"y": 8072.5
},
{
"x": 4946.5,
"y": 12968.1
},
{
"x": 5893.0,
"y": 12968.1
}
],
"length": 15468.6,
"tunnel_indices": []
},
{
"id": "UC0101-BG3260",
"coords": [
{
"x": 0.0,
"y": 4162.8
},
{
"x": 0.1,
"y": 3777.6
},
{
"x": 2866.6,
"y": 3777.6
},
{
"x": 4946.5,
"y": 3777.6
},
{
"x": 8866.1,
"y": 3777.6
},
{
"x": 8866.1,
"y": 3878.4
},
{
"x": 8866.1,
"y": 9000.0
},
{
"x": 9800.0,
"y": 9000.0
},
{
"x": 21282.5,
"y": 9295.2
},
{
"x": 20282.5,
"y": 9295.2
},
{
"x": 20282.5,
"y": 14141.3
},
{
"x": 22355.3,
"y": 14141.3
},
{
"x": 22355.3,
"y": 13524.1
}
],
"length": 27443.6,
"tunnel_indices": [
7,
8
]
},
{
"id": "UC0101-BG3261",
"coords": [
{
"x": 0.0,
"y": 4162.8
},
{
"x": 0.1,
"y": 3777.6
},
{
"x": 2866.6,
"y": 3777.6
},
{
"x": 4946.5,
"y": 3777.6
},
{
"x": 8866.1,
"y": 3777.6
},
{
"x": 8866.1,
"y": 3878.4
},
{
"x": 8866.1,
"y": 9000.0
},
{
"x": 9800.0,
"y": 9000.0
},
{
"x": 21282.5,
"y": 9295.2
},
{
"x": 20282.5,
"y": 9295.2
},
{
"x": 20282.5,
"y": 14141.3
},
{
"x": 22355.3,
"y": 14141.3
},
{
"x": 22355.3,
"y": 13524.1
}
],
"length": 27443.6,
"tunnel_indices": [
7,
8
]
},
{
"id": "UH01-MA0062",
"coords": [
{
"x": 7000.0,
"y": 16300.0
},
{
"x": 7000.0,
"y": 15865.5
},
{
"x": 4946.5,
"y": 15865.5
},
{
"x": 4946.5,
"y": 15774.4
},
{
"x": 4946.5,
"y": 12968.1
},
{
"x": 4946.5,
"y": 8072.5
},
{
"x": 4967.0,
"y": 8072.5
}
],
"length": 10301.5,
"tunnel_indices": []
},
{
"id": "UH01-MA0061",
"coords": [
{
"x": 7000.0,
"y": 16300.0
},
{
"x": 7000.0,
"y": 15865.5
},
{
"x": 4946.5,
"y": 15865.5
},
{
"x": 4946.5,
"y": 15774.4
},
{
"x": 4946.5,
"y": 12968.1
},
{
"x": 4946.5,
"y": 8072.5
},
{
"x": 4967.0,
"y": 8072.5
}
],
"length": 10301.5,
"tunnel_indices": []
},
{
"id": "UH01-MA0063",
"coords": [
{
"x": 7000.0,
"y": 16300.0
},
{
"x": 7000.0,
"y": 15865.5
},
{
"x": 4946.5,
"y": 15865.5
},
{
"x": 4946.5,
"y": 15774.4
},
{
"x": 4946.5,
"y": 12968.1
},
{
"x": 4946.5,
"y": 8072.5
},
{
"x": 4967.0,
"y": 8072.5
}
],
"length": 10301.5,
"tunnel_indices": []
},
{
"id": "UH01-FC0062",
"coords": [
{
"x": 7000.0,
"y": 16300.0
},
{
"x": 7000.0,
"y": 15865.5
},
{
"x": 4946.5,
"y": 15865.5
},
{
"x": 4946.5,
"y": 15774.4
},
{
"x": 4946.5,
"y": 12968.1
},
{
"x": 4946.5,
"y": 8072.5
},
{
"x": 4973.9,
"y": 8072.5
}
],
"length": 10308.4,
"tunnel_indices": []
}
],
"errors_routing": [],
"errors_sensors": [],
"errors_dists": [],
"errors_tunnels": [],
"errors_existing_dists": [],
"errors_existing_sensors": []
}