Compare commits
436 Commits
99bf7303bc
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| cd6b9dc31f | |||
| f4dac5677e | |||
| 8d0915b97e | |||
| 4a4cdcacc6 | |||
| db9653286d | |||
| 50609f80cf | |||
| 8c11d15494 | |||
| b6ab35d8be | |||
| eca5a82644 | |||
| 046bcf7290 | |||
| a1d86500f2 | |||
| bed533e66b | |||
| 64506684a2 | |||
| e157acf77e | |||
| 5e7880a3ad | |||
| 45c8973975 | |||
| 594abb8b2e | |||
| d1ab663ff5 | |||
| 437c6d23fd | |||
| cfe1104c5c | |||
| 78d6edd6a8 | |||
| 4956525f24 | |||
| 676429c053 | |||
| f868032b67 | |||
| 8c98f99d39 | |||
| e07968981b | |||
| b0af6f73dc | |||
| 143d790a1d | |||
| 28dc81d21f | |||
| e3be04ec39 | |||
| 75f6e8dca8 | |||
| c572496f3d | |||
| cc7cd3c331 | |||
| 41811cc827 | |||
| f9fd2a0069 | |||
| 4d5aeb5596 | |||
| ace2eb2dd9 | |||
| f58ad8a6bc | |||
| 0ec0f75a05 | |||
| e34526b2dd | |||
| 161a940a3b | |||
| 309e2f615e | |||
| 32e5a67fbb | |||
| 5574d1c8d7 | |||
| d7fcc2d89a | |||
| acc70e0307 | |||
| 7d3cfc423a | |||
| 1dad277073 | |||
| 10caa9d07f | |||
| 7ec65d6c77 | |||
| 20b36cea9b | |||
| be1864c4d8 | |||
| 6b7eaa43df | |||
| 04d73b78c4 | |||
| 71cf567b8d | |||
| b2f93da92b | |||
| 0067b8bf7d | |||
| 2ea1042792 | |||
| aba46bd13a | |||
| ff6ba900c6 | |||
| a3a37003b6 | |||
| 554f1f3c1f | |||
| 1872ea90f3 | |||
| 4dc6119768 | |||
| bb9eab77f2 | |||
| a916151e63 | |||
| e29a5d1534 | |||
| 0bb00183d4 | |||
| a54885eef3 | |||
| de2720af45 | |||
| 163332f86c | |||
| 4b7bc5e2ee | |||
| a79db3f116 | |||
| 58a70aaf5d | |||
| 28cd3c630e | |||
| 002b5e0bf1 | |||
| 46e2d8663b | |||
| 5cbd290a16 | |||
| beb84c0bf9 | |||
| e1725df45a | |||
| 4a676b6316 | |||
| 3694028854 | |||
| dd978515ee | |||
| 939b8fbe62 | |||
| 07648a9193 | |||
| 7661363553 | |||
| da5edd8075 | |||
| 3a33fc969c | |||
| 83879fb753 | |||
| 3836a8806d | |||
| b0549c7bb5 | |||
| e6dafcbf1d | |||
| 8b18de6a31 | |||
| b7d98cbf14 | |||
| e600dfbae8 | |||
| 31084defdb | |||
| 3ef1fe1f19 | |||
| 0f16f1cfba | |||
| 18d4f62d24 | |||
| 246692b4e6 | |||
| f6d39afe29 | |||
| 95b41960b8 | |||
| eb2da07947 | |||
| e6c7e53459 | |||
| dfed66d94e | |||
| fdf975e661 | |||
| 8d98e28240 | |||
| 919091dc6e | |||
| 222a2efbf6 | |||
| 09ffb5d7b2 | |||
| ae82736960 | |||
| c4ef6e28f4 | |||
| 0a2e7bb2ef | |||
| 0587cfea36 | |||
| ba02f69f0f | |||
| e087b65359 | |||
| e214e9d21e | |||
| b82c751ba9 | |||
| 657d0d99f7 | |||
| 56e4e8ca85 | |||
| 42393e457e | |||
| 48a5b1f971 | |||
| 1cb0ce8442 | |||
| 89ea433d45 | |||
| 84f8751eff | |||
| d55d71d623 | |||
| 3a964b9139 | |||
| 3deebb81f3 | |||
| 37208f61b1 | |||
| 34838ccf02 | |||
| abba70b6ca | |||
| 21b3feeca9 | |||
| 9b9d3a8f7c | |||
| a731889561 | |||
| 57765706f7 | |||
| b89525556b | |||
| 45a56287b8 | |||
| 5939879e23 | |||
| 60ba962faa | |||
| 6524a76c2a | |||
| ccbfcafb63 | |||
| 627c3f52c8 | |||
| 912893691e | |||
| 6af399f593 | |||
| f1800072c5 | |||
| 78254b688a | |||
| 08633e15b7 | |||
| 4c212ea701 | |||
| afd5da4bbb | |||
| bbc30a05ad | |||
| 85fc641da7 | |||
| 4434a106c7 | |||
| 9f6406c52c | |||
| 182d7f37d1 | |||
| 1260edf5ce | |||
| f327b8011c | |||
| 9471f9919c | |||
| e6c1739df8 | |||
| 308dc8bfc4 | |||
| a499180848 | |||
| 29fc432e29 | |||
| 4e7e218db4 | |||
| 308da2dcf7 | |||
| 1685e06b0e | |||
| 7d52a4773f | |||
| a6f813dd25 | |||
| 8af0d35f25 | |||
| bf45f70e7c | |||
| b10bd78b79 | |||
| cb588c9ccc | |||
| 418882e78f | |||
| b9d45e6be0 | |||
| 955bb0a0cc | |||
| 12cb8fd99c | |||
| a967e2e35e | |||
| b883e8afa1 | |||
| 56979938f5 | |||
| ed416a5315 | |||
| f7f8aca5f1 | |||
| 17902ec8dc | |||
| c5f4aafcca | |||
| a869b52406 | |||
| c7af3b34ba | |||
| 113d303adf | |||
| 4893902e48 | |||
| 19035fc85a | |||
| 219badf0bb | |||
| c7e4379cc5 | |||
| f784db5cef | |||
| fbe7f6b7cb | |||
| bf2b62575f | |||
| 4d1d2940c7 | |||
| 7b7ed50e2c | |||
| 9365b2d71e | |||
| bf3a03837e | |||
| 49db3d0042 | |||
| 811f0db82c | |||
| 2e66d28e76 | |||
| 6a645fc6e7 | |||
| 984b84776c | |||
| cc655aaf9b | |||
| 5b1a6ac333 | |||
| fa8643b376 | |||
| 22bb2ad163 | |||
| 93b10b1f78 | |||
| e1f863c9a2 | |||
| 4a415afea8 | |||
| 72b72087e1 | |||
| 62dcfa31b2 | |||
| 03e67c93df | |||
| 0084c08f20 | |||
| ffba29b41b | |||
| 032527e4aa | |||
| d0462bdd4b | |||
| 2202a7202c | |||
| 069a74dfb9 | |||
| 2553d8c614 | |||
| f521d857e5 | |||
| ccbcf0c6e5 | |||
| 8fc4d9a746 | |||
| 4c1c01f790 | |||
| b8c1e7413a | |||
| cae3047bac | |||
| ec6d903515 | |||
| b9bbcb4f78 | |||
| 79b795da65 | |||
| 76ae8ed22a | |||
| b39235ba70 | |||
| 0a3fe7dda8 | |||
| c805b7fcfe | |||
| 5ea5b4de1c | |||
| c022a9240c | |||
| 93cc4e1801 | |||
| be36aedd0b | |||
| 22debeb3ab | |||
| 4d441a24ba | |||
| 1e89b5904a | |||
| f593d0082d | |||
| 0e56527387 | |||
| 47cda8dc80 | |||
| 71f9d10461 | |||
| c465708398 | |||
| 9000164b6e | |||
| 2d0f44fbf3 | |||
| 55da6645c6 | |||
| 56aa84f225 | |||
| 002c16f7e6 | |||
| bbab952927 | |||
| 71affd1f81 | |||
| 7dce25327b | |||
| 8b40b64695 | |||
| 136cdef6db | |||
| 303baa0dd3 | |||
| e2721c5097 | |||
| e1a2229d5d | |||
| 244898547e | |||
| 20a3cdf761 | |||
| b3d222afa1 | |||
| ad1c053af3 | |||
| 51ecd84d67 | |||
| 50f00a8fa9 | |||
| a007f22819 | |||
| 3a68ae9022 | |||
| d7c98a2b5f | |||
| 95f8f6722b | |||
| a2d22500c4 | |||
| 455ad888f2 | |||
| 7c1827908e | |||
| 024819df5c | |||
| 610c7027bd | |||
| 6969e8c366 | |||
| a39390c1d1 | |||
| acbe3c2f9b | |||
| 08a9800002 | |||
| 20025a8327 | |||
| 9cff95a396 | |||
| 1983696644 | |||
| 0b98271ebc | |||
| 0679186a6e | |||
| 8cce5dea26 | |||
| f7c1ab2fe6 | |||
| eca97bc59e | |||
| 754c2ece57 | |||
| 6d12697029 | |||
| dc2c2973f7 | |||
| 783a964711 | |||
| f69de7ea16 | |||
| afea7b38c1 | |||
| 343e2e5b00 | |||
| d0bda8c38a | |||
| 304a103a78 | |||
| a2414eac89 | |||
| 54a92672e5 | |||
| 0a3685970f | |||
| 0b7b8480ce | |||
| c958e9c461 | |||
| 19dee3bf56 | |||
| d9908ddf87 | |||
| d98b7434ec | |||
| 8f5e99632e | |||
| ef9a07c40e | |||
| 6b0b3fea04 | |||
| c13b72891f | |||
| f858dca377 | |||
| 3b9b6c2fd4 | |||
| fd6388f482 | |||
| 61ffcaa271 | |||
| 54645a0772 | |||
| c495ff7b2a | |||
| c65e21c61d | |||
| e71398fd50 | |||
| ea807c5365 | |||
| 3aee069460 | |||
| 6a298afe41 | |||
| adbc25ee05 | |||
| ea7da269e1 | |||
| 80b96da6b6 | |||
| ca2831ea23 | |||
| e329dc9f3a | |||
| aa8f67e27b | |||
| c881423352 | |||
| 709703e397 | |||
| c5d638cf51 | |||
| d1f3f4d847 | |||
| 6510587453 | |||
| 3f6594065d | |||
| 6cffc9ae31 | |||
| 72490df3c2 | |||
| 54e6400bf4 | |||
| 4b18a9005f | |||
| 745b6df6de | |||
| 7c2e171f7d | |||
| 8389164e5d | |||
| affc98d907 | |||
| e5ca9561dd | |||
| 5258457851 | |||
| 24fd45e6ae | |||
| 20b4812f68 | |||
| b6962bc96b | |||
| 3f359486f9 | |||
| 812c39b00d | |||
| e75779cfcb | |||
| 0524e4e6dc | |||
| 2e6f0b2350 | |||
| e0af4c3c95 | |||
| 73dad69083 | |||
| 32db6ca4ca | |||
| 09d597f627 | |||
| bd46fd44e8 | |||
| bed9000f60 | |||
| ebdde0e86f | |||
| a6f0739ce2 | |||
| 23e6bf77d6 | |||
| e6729b68a0 | |||
| a74b774ad2 | |||
| 4626984ede | |||
| 371fe6241e | |||
| ee9f1b8dae | |||
| ae78724127 | |||
| c2485849a6 | |||
| 764954a619 | |||
| 2f982bf5f4 | |||
| ab06d46bc5 | |||
| a3e0a15b0e | |||
| 9a9455be7e | |||
| ba03bcb866 | |||
| 655e2b6ab6 | |||
| 09e5d2708a | |||
| fa1c26368a | |||
| fb1232b0f8 | |||
| 7cd0578c8c | |||
| 8e653aca20 | |||
| dc1b5387a8 | |||
| a78ac861bc | |||
| b6040d5ebc | |||
| 50d45ac489 | |||
| de2dd8077e | |||
| ec52557197 | |||
| 141220596d | |||
| 01d14e7fc2 | |||
| cf98e71a22 | |||
| 9dd11261d0 | |||
| 9bd38708ff | |||
| 15187ab85f | |||
| 68d1519853 | |||
| 85ae4f17f4 | |||
| b950573b93 | |||
| 2657117c24 | |||
| cc36734790 | |||
| 10d794e9ce | |||
| 09d8bbd63a | |||
| eb58a54b19 | |||
| 731dd3dda6 | |||
| 4eb574b39c | |||
| 89932f6436 | |||
| 4e58b1b911 | |||
| e72ca4610f | |||
| 4f06c198db | |||
| 2d29705d4a | |||
| 7733b50609 | |||
| 4ad8357a7e | |||
| dbf3a6450d | |||
| 47ab065387 | |||
| 6ffb9c72d5 | |||
| 5c7c234fab | |||
| 96dd2495ce | |||
| f2a6f0e35d | |||
| 92a6922b9e | |||
| 1285742eeb | |||
| f08ee5cb02 | |||
| e1920937ca | |||
| 9ad0c9ca8e | |||
| ef329c0a9a | |||
| ff70278ca5 | |||
| b72c01768e | |||
| a0e7fdfa5b | |||
| a3656faf6d | |||
| d928f858ba | |||
| a385d579c3 | |||
| 58b7f38df6 | |||
| fbf5657244 | |||
| 7af1a77585 | |||
| 36f13a736e | |||
| c0f8025a92 | |||
| 13c648c502 | |||
| 3e7f2c0a38 | |||
| c0d25f1eff | |||
| 96be91bc91 | |||
| cbeb8345af | |||
| 0c9ad629c2 | |||
| 4b1002ff7e | |||
| 32750e8e7c | |||
| 86d209b428 | |||
| eed412fb34 | |||
| 62ec6ac22d | |||
| 7658d058d0 |
@@ -165,3 +165,5 @@ cython_debug/
|
||||
/data
|
||||
/work
|
||||
/log
|
||||
work/easy.dxf
|
||||
work/easy_todraw_edit.json
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "Python Debugger: Current File",
|
||||
"type": "debugpy",
|
||||
@@ -23,6 +24,16 @@
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"name": "create_numbers with Nummerierung1.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"Nummerierung1.dxf" ]
|
||||
},
|
||||
{
|
||||
"name": "getpositions with easy.dxf",
|
||||
"type": "debugpy",
|
||||
@@ -39,6 +50,165 @@
|
||||
"easy_positions.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getpositions with easy_3tunnels.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"easy_3tunnels.dxf",
|
||||
"--sensors",
|
||||
"--rack",
|
||||
"--console",
|
||||
"--write",
|
||||
"easy_3tunnels_positions.json",
|
||||
"--error",
|
||||
"easy_3tunnels_errors.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getpositions with easyn.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"easyn.dxf",
|
||||
"--sensors",
|
||||
"--rack",
|
||||
"--console",
|
||||
"--write",
|
||||
"easyn_positions.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getpositions with easyhoehe.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"easyhoehe.dxf",
|
||||
"--sensors",
|
||||
"--rack",
|
||||
"--console",
|
||||
"--write",
|
||||
"easyhoehe_positions.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getpositions with easysps.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"easysps.dxf",
|
||||
"--sensors",
|
||||
"--rack",
|
||||
"--console",
|
||||
"--write",
|
||||
"easysps_positions.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getpositions with easy_hdiff_nb.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"easy_hdiff_nb.dxf",
|
||||
"--sensors",
|
||||
"--rack",
|
||||
"--console",
|
||||
"--write",
|
||||
"easy_hdiff_nb_positions.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getpositions with PR500592_10_5.13_POT_20251216.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"PR500592_10_5.13_POT_20251216.dxf",
|
||||
"--sensors",
|
||||
"--rack",
|
||||
"--console",
|
||||
"--write",
|
||||
"PR500592_10_5.13_POT_20251216_positions.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getpositions with POT_ST1_ST6_12.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"POT_ST1_ST6_12.dxf",
|
||||
"--sensors",
|
||||
"--rack",
|
||||
"--console",
|
||||
"--write",
|
||||
"POT_ST1_ST6_12_positions.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "portalexport with ST500592_Omniflo.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"ST500592_Omniflo_positions.json",
|
||||
"--outname",
|
||||
"ST500592_Omniflo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getpositions with ST-Fortna.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"ST-Fortna.dxf",
|
||||
"--sensors",
|
||||
"--rack",
|
||||
"--console",
|
||||
"--write",
|
||||
"ST-Fortna_positions.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getpositions with ST-Fortna_ASCII.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"ST-Fortna_ASCII.dxf",
|
||||
"--sensors",
|
||||
"--rack",
|
||||
"--console",
|
||||
"--write",
|
||||
"ST-Fortna_ASCII_positions.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getpositions with HundM.dxf",
|
||||
"type": "debugpy",
|
||||
@@ -52,7 +222,23 @@
|
||||
"--rack",
|
||||
"--console",
|
||||
"--write",
|
||||
"easy"
|
||||
"HundM"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getpositions with 500622-Erdungslayout.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"500622-Erdungslayout.dxf",
|
||||
"--sensors",
|
||||
"--rack",
|
||||
"--console",
|
||||
"--write",
|
||||
"500622-Erdungslayout"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -76,41 +262,46 @@
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"ST_6300_Steuerungstestlayout1_neueBloecke.dxf",
|
||||
"--filename", "ST_6300_Steuerungstestlayout1_neueBloecke.dxf",
|
||||
"-s",
|
||||
"-d",
|
||||
"-r"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "draw cable dxf with copied layers from easy_todraw.json",
|
||||
"name": "draw cable dxf with copied layers from easy_todraw_edit.json",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"easy_todraw.json",
|
||||
"--new",
|
||||
"easy_cables.dxf",
|
||||
"--copy_layer",
|
||||
"easy_layer_copy.dxf",
|
||||
"--origin",
|
||||
"easy.dxf"
|
||||
"--filename", "easy_todraw_edit.json",
|
||||
"--new", "easy_cables.dxf",
|
||||
"--copy_layer","easy_reduziert.dxf",
|
||||
"--origin", "easy.dxf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "draw cable dxf from easy.json to new layer",
|
||||
{
|
||||
"name": "draw cables from ST-Fortna_todraw",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--json",
|
||||
"easy.json",
|
||||
"--dxf",
|
||||
"easy.dxf"
|
||||
"--filename", "ST-Fortna_ASCII_todraw.json",
|
||||
"-n", "ST-Fortna_ASCII_cables.dxf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "draw cables for test.json",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename", "test_todraw.json",
|
||||
"-n", "test_cables.dxf",
|
||||
"-x", "test_cables.xlsx"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -120,10 +311,8 @@
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"easy_positions.json",
|
||||
"-w",
|
||||
"easy_todraw.json"
|
||||
"--filename", "easy_positions.json",
|
||||
"-w", "easy_todraw.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -132,12 +321,88 @@
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename", "HundM_coords.json",
|
||||
"-w", "HundM_cables.json",
|
||||
"-g"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "routing for test_positionsdraw.json",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename",
|
||||
"HundM_coords.json",
|
||||
"test_positionsdraw.json",
|
||||
"-w",
|
||||
"HundM_cables.json"
|
||||
"test_draw.json",
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "run_tests.py with easy_3tunnels.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--file", "easy_3tunnels.dxf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "run_tests.py with all tests",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": []
|
||||
},
|
||||
{
|
||||
"name": "translate.py ST500592_10_5-13_ILS.dxf.py with BGMG.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename", "ST500592_10_5-13_ILS.dxf",
|
||||
"--extract", "-t", "json,text",
|
||||
"--outname", "ST500592_10_5-13_ILS_texts.json",
|
||||
"--translate", "CS"
|
||||
]
|
||||
},{
|
||||
"name": "create_numbers.py with Nummerierung1.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename", "Nummerierung1.dxf",
|
||||
"--errorfile", "Nummerierung1_errors.json",
|
||||
"--info", "Nummerierung1_symbols.json"
|
||||
]
|
||||
}, {
|
||||
"name": "create_numbers.py with BGMG-UndefSymbols.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename", "BGMG-UndefSymbols.dxf",
|
||||
"--errorfile", "BGMG-UndefSymbols_errors.json",
|
||||
"--info", "BGMG-UndefSymbols_symbols.json"
|
||||
]
|
||||
}, {
|
||||
"name": "create_numbers.py with POT.dxf",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"--filename", "POT.dxf",
|
||||
"--errorfile", "POT_errors.json",
|
||||
"--info", "POT_symbols.json"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"python.languageServer": "Pylance",
|
||||
"python.languageServer": "None",
|
||||
"cSpell.words": [
|
||||
"DXFATTRIBS",
|
||||
"ezdxf"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Overview
|
||||
|
||||
This is a Python-based cable routing automation tool for industrial plant layouts. The system reads DXF files containing equipment positions and cable trays, calculates optimal cable paths using graph algorithms, and generates cable lists with SIVAS article numbers for procurement.
|
||||
|
||||
## Architecture
|
||||
|
||||
The codebase follows a modular three-stage pipeline:
|
||||
|
||||
1. **Position Extraction** ([getpositions.py](lib/getpositions.py)) - Extracts equipment positions and cable tray geometries from DXF files
|
||||
2. **Route Calculation** ([routing.py](lib/routing.py)) - Builds graph models and calculates shortest paths between equipment and distributors
|
||||
3. **Output Generation** ([drawdxf.py](lib/drawdxf.py)) - Creates DXF files with cable paths and Excel lists with cable specifications
|
||||
|
||||
### Pipeline Data Flow
|
||||
|
||||
```
|
||||
DXF file
|
||||
→ getpositions.py → *_positionsdraw.json (positions, racks, distributors, mappings)
|
||||
→ routing.py → *_todraw.json (cable routes with coordinates and lengths)
|
||||
→ drawdxf.py → *.dxf + *.xlsx + BOM (final output files)
|
||||
```
|
||||
|
||||
The JSON intermediate files serve as interfaces between stages and are valuable for debugging. Each stage can be run independently.
|
||||
|
||||
### Workflow Modes
|
||||
|
||||
The system supports four primary workflows:
|
||||
|
||||
1. **Full Cable Routing** (`getexdraw.bat`) - Complete pipeline from DXF input to cable paths and BOMs
|
||||
2. **I/O Conversion** (`ioconverter.bat`) - Converts DXF equipment data to Excel formats for TIA, WSCAD, and other systems
|
||||
3. **Text Extraction** (`extract.bat`) - Extracts all TEXT and MTEXT objects from DXF files to multiple formats (Excel, JSON, Text) for translation purposes
|
||||
4. **Translation** (`tr2dxf.bat`, `tr2dxf_cs.bat`, etc.) - Translates DXF text content into target languages (Czech, English, French, Italian, Spanish)
|
||||
|
||||
### Core Modules
|
||||
|
||||
- **[plant.py](lib/plant.py)** - Main business logic containing the `Anlage` class that models industrial plants, manages equipment connections, and implements graph-based routing algorithms
|
||||
- **[model.py](lib/model.py)** - Data classes for points, equipment, distributors, and cable trays using dataclasses and dacite
|
||||
- **[graphbuild.py](lib/graphbuild.py)** - Graph construction utilities for network topology
|
||||
- **[linesweep.py](lib/linesweep.py)** - Geometric algorithms for line intersection detection
|
||||
|
||||
### Utility Modules
|
||||
|
||||
- **[error_collector.py](lib/error_collector.py)** - Centralized error/warning collection system with two severity levels; used across getpositions and drawdxf
|
||||
- **[utils.py](lib/utils.py)** - Common utility functions: file I/O, environment variable checks, JSON operations, DXF file handling, dictionary merging
|
||||
- **[updateconfignames.py](lib/updateconfignames.py)** - Updates SIVAS article descriptions in `bezeichner.cfg` from external SIVAS database exports (CSV files in `data/`)
|
||||
- **[flags.py](lib/flags.py)** - Icon/flag generation using PIL for language flags (EN, FR, IT, ES, CS)
|
||||
|
||||
### Export & Conversion Modules
|
||||
|
||||
- **[portalexport.py](lib/portalexport.py)** - Exports equipment I/O data to Excel formats for TIA Portal and WSCAD
|
||||
- **[ioconverter.py](lib/ioconverter.py)** - `ExcelConverter` class for converting I/O lists with input/output identifier mappings
|
||||
- **[translate.py](lib/translate.py)** - Comprehensive text extraction/translation: extracts TEXT, MTEXT, and block attributes from DXF/DWG files; supports Excel, JSON, Text export formats
|
||||
|
||||
### DXF Utility Modules
|
||||
|
||||
- **[create_dxf_symbols.py](lib/create_dxf_symbols.py)** - Creates DXF symbol blocks (grounding, switchboard, subdistribution, motor symbols)
|
||||
- **[create_example.py](lib/create_example.py)** - `TestDataGenerator` for generating synthetic test DXF files with defined layouts
|
||||
- **[create_numbers.py](lib/create_numbers.py)** - Generates/updates numbered symbols in DXF files based on RENAMER layer configuration
|
||||
|
||||
### Configuration System
|
||||
|
||||
The system uses configuration files in `cfg/`:
|
||||
|
||||
- **`BMK.cfg`** - Equipment identification codes, cable type mappings, routing inclusion/exclusion rules, cabinet/tunnel patterns, length adjustments
|
||||
- **`kabel.cfg`** - SIVAS article number mappings for different cable types and lengths (sections like `[MA]`, `[WD_Q]`, `[WD_I]`, etc.)
|
||||
- **`allgemein.cfg`** - Layer names for racks/distributors/tunnels, geometric tolerances, connection parameters
|
||||
- **`bezeichner.cfg`** - Article number descriptions, auto-populated from SIVAS database
|
||||
- **`translator.cfg`** - Text filtering for translation (wildcard and regex ignore patterns)
|
||||
- **`enumerate.cfg`** - Symbol enumeration settings (RENAMER layers, polyline distances)
|
||||
- **`translation/CS.cfg`** - Czech language translation key mappings
|
||||
|
||||
**Important**: When adding a new equipment prefix, it must be added to **both** `[Routing-Include]` and `[Cable-Mapping]` in `BMK.cfg`, and the corresponding cable section must exist in `kabel.cfg`.
|
||||
|
||||
**Article-specific mappings**: `[Cable-Mapping]` supports article-number-specific entries like `MB-929012603 = WD_Q-929012603` alongside generic prefix mappings like `MA = MA`. The specific entry takes precedence when the sensor's article number matches.
|
||||
|
||||
**Current prefixes in `[Routing-Include]`**: MA, MB, QM, BG, BP, BX, PO, SF, PF, GF
|
||||
|
||||
## Common Commands
|
||||
|
||||
### Main Execution
|
||||
|
||||
```bash
|
||||
# Process a DXF file for cable routing (drag-and-drop onto desktop shortcut in production)
|
||||
bin\getexdraw.bat <filename.dxf>
|
||||
|
||||
# Convert DXF to I/O lists for TIA Portal, WSCAD, etc.
|
||||
bin\ioconverter.bat <filename.dxf>
|
||||
|
||||
# Extract text from DXF files for translation
|
||||
bin\extract.bat <filename.dxf>
|
||||
|
||||
# Translate DXF to Czech (also: tr2dxf_en, tr2dxf_fr, tr2dxf_it, tr2dxf_es)
|
||||
bin\tr2dxf_cs.bat <filename.dxf>
|
||||
|
||||
# PowerShell alternative for getexdraw
|
||||
bin\getexdraw.ps1 <filename.dxf>
|
||||
|
||||
# Manual execution of pipeline stages
|
||||
bin\getpositions.bat --filename <file.dxf> -s -r -w <output.json>
|
||||
bin\routing.bat --filename <positions.json> -w <todraw.json>
|
||||
bin\draw_dxf.bat --filename <todraw.json> --new <output.dxf> -x <output.xlsx>
|
||||
bin\portalexport.bat --filename <positions.json> --outname <basename>
|
||||
bin\translate.bat --filename <file.dxf> --extract --export-type excel,json --outname <output>
|
||||
```
|
||||
|
||||
**Note**: All `.bat` scripts have corresponding `.sh` equivalents for Linux/macOS systems.
|
||||
|
||||
### Development and Testing
|
||||
|
||||
```bash
|
||||
# Install Python dependencies
|
||||
bin\install_py.bat
|
||||
|
||||
# Run automated test suite (all test files)
|
||||
bin\run_tests.bat
|
||||
|
||||
# Run test for a single file (most common for development)
|
||||
bin\run_test.bat <testname>
|
||||
bin\run_test.bat easy
|
||||
bin\run_test.bat easy --clean
|
||||
|
||||
# Run tests for specific file (alternative syntax)
|
||||
bin\run_tests.bat --file <testname>
|
||||
|
||||
# Run tests in different modes
|
||||
bin\run_test.bat <testname> --ioconverter
|
||||
bin\run_test.bat <testname> --translation
|
||||
bin\run_tests.bat --ioconverter
|
||||
|
||||
# Create reference files from current outputs
|
||||
bin\run_tests.bat --create-references
|
||||
|
||||
# Clean up work folders after tests
|
||||
bin\run_tests.bat --clean
|
||||
|
||||
# Run unit tests
|
||||
bin\run_unittests.bat
|
||||
|
||||
# Individual component testing
|
||||
python lib\getpositions.py --help
|
||||
python lib\routing.py --graph # Shows visual graph
|
||||
python lib\drawdxf.py --help
|
||||
```
|
||||
|
||||
### Production Deployment
|
||||
|
||||
```bash
|
||||
# Create desktop shortcuts with drag-and-drop icons for all tools
|
||||
bin\dropItem_create.bat
|
||||
|
||||
# Remove desktop shortcuts
|
||||
bin\dropItem_remove.bat
|
||||
```
|
||||
|
||||
### Configuration Management
|
||||
|
||||
```bash
|
||||
# Update SIVAS article descriptions
|
||||
python lib\updateconfignames.py
|
||||
|
||||
# Convert between formats
|
||||
python lib\ioconverter.py
|
||||
```
|
||||
|
||||
## Development Guidelines
|
||||
|
||||
### Code Style
|
||||
|
||||
- Use German comments and variable names for consistency with existing codebase
|
||||
- Follow dataclass patterns established in [model.py](lib/model.py)
|
||||
- Maintain separation between geometric operations (Shapely) and graph algorithms (NetworkX)
|
||||
|
||||
### Configuration Changes
|
||||
|
||||
- Always update corresponding `.cfg` files when adding new equipment types or cable categories
|
||||
- A new equipment prefix needs entries in: `[Routing-Include]`, `[Cable-Mapping]` (both in `BMK.cfg`), and a matching section in `kabel.cfg`
|
||||
- Test configuration changes with sample DXF files in [testdata/](testdata/) directory
|
||||
- Configuration files use Windows INI format with specific section naming conventions
|
||||
|
||||
### Error Handling
|
||||
|
||||
The system uses [error_collector.py](lib/error_collector.py) for centralized error/warning collection with two severity levels:
|
||||
|
||||
- **Errors** (critical issues that affect output correctness):
|
||||
- Equipment connection failures (distance tolerances)
|
||||
- Missing SIVAS article numbers
|
||||
- Invalid DXF block attributes
|
||||
- Graph routing failures
|
||||
- Missing or overdefined tunnel positions
|
||||
- Duplicate equipment IDs
|
||||
|
||||
- **Warnings** (potential issues, processing continues):
|
||||
- Missing or incomplete block attributes
|
||||
- Invalid KENNZEICHNUNG format
|
||||
- Missing tunnel length specifications
|
||||
|
||||
All issues are collected in the `warnings` section of output JSON files (e.g., `*_positionsdraw.json`). Critical errors also generate separate `*_errors.json` files. See [doc/Anwenderdoku_kurz.md](doc/Anwenderdoku_kurz.md) for detailed error descriptions and resolution steps.
|
||||
|
||||
### Config Validation
|
||||
|
||||
On startup, `getpositions.py` validates configuration consistency and reports:
|
||||
- Prefixes in `[Routing-Include]` without a `[Cable-Mapping]` entry
|
||||
- Cable sections referenced in `[Cable-Mapping]` that are missing from `kabel.cfg`
|
||||
|
||||
### Testing
|
||||
|
||||
The project includes a comprehensive automated test suite:
|
||||
|
||||
- Test DXF files stored in [testdata/](testdata/) (e.g., `easy.dxf`, `easy_sps.dxf`, `easy_hoehe.dxf`, `easy_3tunnels.dxf`, `Erdungsbsp.dxf`)
|
||||
- Reference JSON outputs stored alongside test DXF files
|
||||
- Test runner ([run_tests.py](lib/run_tests.py)) compares generated outputs against references with diff reporting
|
||||
- Supports `getexdraw`, `ioconverter`, and `translate` workflow testing
|
||||
- Visual graph debugging available with `--graph` flag in routing
|
||||
- Test cases cover: standard routing, SPS integration, height differences, tunnel overdefinition, grounding, duplicate IDs, translation
|
||||
- Unit tests in `lib/` (`error_collector_test.py`, `utils_test.py`, `flags_test.py`, `create_numbers_test.py`, `getpositions_test.py`)
|
||||
- Additional edge case tests in [tests/](tests/) directory (e.g., `test_ioconverter_errors.py`)
|
||||
|
||||
## File Structure
|
||||
|
||||
```text
|
||||
bin/ # Batch scripts (.bat) and shell scripts (.sh) for all workflows
|
||||
cfg/ # Configuration files (BMK, cable mappings, tolerances, translation filters)
|
||||
cfg/translation/# Language-specific translation configs (CS.cfg)
|
||||
lib/ # Python modules (core pipeline, utilities, tests)
|
||||
work/ # Working directory for processing results (generated output)
|
||||
testdata/ # Test DXF files and reference outputs for automated testing
|
||||
tests/ # Additional test files and edge case test data
|
||||
doc/ # Comprehensive German documentation (Markdown + PDF)
|
||||
doc/img/Icons/ # Icons for desktop shortcuts
|
||||
data/ # SIVAS article number CSV reference files (auto-populated)
|
||||
translation/ # Translation configurations
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
Key Python packages (see [lib/requirements.txt](lib/requirements.txt)):
|
||||
|
||||
- `ezdxf` - DXF file reading/writing
|
||||
- `shapely` - Geometric operations
|
||||
- `networkx` - Graph algorithms
|
||||
- `openpyxl` - Excel output generation
|
||||
- `pandas` - Data manipulation
|
||||
- `matplotlib` - Graph visualization
|
||||
- `dacite` - Dataclass conversion utilities
|
||||
- `PyMuPDF` - PDF processing capabilities
|
||||
- `pillow` - Image processing (flag/icon generation)
|
||||
- `pytest` - Testing framework
|
||||
|
||||
## Output Files
|
||||
|
||||
### Cable Routing Workflow (getexdraw)
|
||||
|
||||
- `*_cables.dxf` - DXF with drawn cable paths
|
||||
- `*_cables.xlsx` - Cable list with lengths and SIVAS numbers
|
||||
- `*_BOM.xlsx` - Complete bill of materials
|
||||
- `*_positionsdraw.json` - Intermediate position data with routing info
|
||||
- `*_todraw.json` - Intermediate routing data for drawing
|
||||
- `*_errors.json` - Error report (if validation fails)
|
||||
|
||||
### I/O Conversion Workflow (ioconverter)
|
||||
|
||||
- `*-TIA.xlsx` - Excel export for TIA Portal
|
||||
- `*-WSCAD.xlsx` - Excel export for WSCAD
|
||||
- `*_positionsconv.json` - Intermediate position data for conversion
|
||||
- `*_errors.json` - Error report (if validation fails)
|
||||
|
||||
### Text Extraction Workflow (extract)
|
||||
|
||||
- `*_texts.xlsx` - Excel file with all TEXT and MTEXT entities from DXF for translation
|
||||
|
||||
### Translation Workflow (tr2dxf)
|
||||
|
||||
- Translated DXF files with text replaced in target language
|
||||
|
||||
## Environment Variables
|
||||
|
||||
The system uses environment variables defined in [bin/setenv.bat](bin/setenv.bat):
|
||||
|
||||
- `PROJECT` - Root directory of the project
|
||||
- `PROJECT_BIN` - Binary/script directory
|
||||
- `PROJECT_CFG` - Configuration directory
|
||||
- `PROJECT_DOC` - Documentation directory
|
||||
- `PROJECT_LIB` - Python library directory
|
||||
- `PROJECT_DATA` - SIVAS reference data directory
|
||||
- `PROJECT_WORK` - Working directory for outputs
|
||||
- `PROJECT_TEST` - Test data directory (testdata/)
|
||||
- `PROJECT_LOG` - Log directory
|
||||
- `PROJECT_TRANSLATION` - Translation directory
|
||||
- `PROJECT_IO_RESULTS` - Network location for I/O converter results
|
||||
- `PROJECT_BOM_RESULTS` - Network location for BOM results
|
||||
- `SIVAS_TEILESTAMM` - Path to SIVAS parts database export tool
|
||||
- `SIVAS_EXCEL_EXPORT_DIR` - Output directory for SIVAS data exports
|
||||
- `INSTALL_DIR` - Desktop shortcut installation location
|
||||
|
||||
Local overrides can be placed in `bin/_setenv.bat` (not tracked in git).
|
||||
@@ -0,0 +1,114 @@
|
||||
# Kabeltool - Automatisierte Kabellängenermittlung
|
||||
|
||||
Automatisiertes Toolset zur Ermittlung von Kabellängen in industriellen Anlagenlayouts. Aus einer DXF-Zeichnung werden Gerätepositionen und Kabeltrassen extrahiert, optimale Kabelwege berechnet und Stücklisten mit SIVAS-Artikelnummern erzeugt.
|
||||
|
||||
Die Übersetzungswerkzeuge ermöglichen den einfachen Transfer der .dxf Dateien in eine andere Sprache.
|
||||
|
||||
## Liste der vorhandenen Werkzeuge
|
||||
|
||||
| | Workflow | Skript | Beschreibung | Ausgabe |
|
||||
|---|----------|--------|--------------|---------|
|
||||
| <img src="doc/img/Icons/Icon_getex.png" width="128"> | **Cable Routing** | `getexdraw.bat` | Vollständige Kabelberechnung mit Wegführung und Stücklisten | `*_cables.dxf`, `*_cables.xlsx`, `*_BOM.xlsx` |
|
||||
| <img src="doc/img/Icons/Icon_portal.png" width="128"> | **I/O Conversion** | `ioconverter.bat` | Export von Gerätelisten für TIA Portal, WSCAD u.a. | `*-TIA.xlsx`, `*-WSCAD.xlsx` |
|
||||
| <img src="doc/img/Icons/dxf2txt.png" width="128"> | **Text Extraction** | `extract.bat` | Textextraktion aus DXF für Übersetzung | `*_texts.xlsx`, `*_texts.json` |
|
||||
| <img src="doc/img/Icons/dxfCs.png" width="128"> | **Translation** | `tr2dxf_<lang>.bat` | Übersetzung von DXF-Texten (CS, EN, FR, IT, ES) | `*_<lang>.dxf` |
|
||||
|
||||
## Verwendung
|
||||
|
||||
DXF-Datei per **Drag & Drop** auf die Desktop-Verknüpfung ziehen (erstellt via `bin\dropItem_create.bat`) oder direkt aufrufen:
|
||||
|
||||
```bash
|
||||
bin\getexdraw.bat <meine_anlage.dxf>
|
||||
```
|
||||
|
||||
## Pipelines
|
||||
|
||||
### Cable Routing (`getexdraw.bat`)
|
||||
|
||||
```text
|
||||
DXF-Datei
|
||||
1. getpositions.py --> Positionen extrahieren --> *_positionsdraw.json
|
||||
2. routing.py --> Kabelwege berechnen --> *_todraw.json
|
||||
3. drawdxf.py --> DXF + Excel erzeugen --> *_cables.dxf, *_cables.xlsx, *_BOM.xlsx
|
||||
```
|
||||
|
||||
### I/O Conversion (`ioconverter.bat`)
|
||||
|
||||
```text
|
||||
DXF-Datei
|
||||
1. getpositions.py --> Positionen extrahieren --> *_positionsconv.json
|
||||
2. portalexport.py --> Excel-Export erzeugen --> *-TIA.xlsx, *-WSCAD.xlsx, *-EA.xlsx
|
||||
```
|
||||
|
||||
### Text Extraction & Translation (`extract.bat` / `tr2dxf_<lang>.bat`)
|
||||
|
||||
```text
|
||||
DXF-Datei
|
||||
1. translate.py --extract --> Texte extrahieren --> *_texts.xlsx, *_texts.json
|
||||
2. translate.py --translate --> Texte übersetzen --> *_<lang>.dxf
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
# Repository klonen
|
||||
git clone http://gitea.schoenenberger.de/mistangl/kabellaengen.git
|
||||
|
||||
# Python-Abhängigkeiten installieren
|
||||
bin\install_py.bat
|
||||
|
||||
# Desktop-Verknüpfungen erstellen
|
||||
bin\dropItem_create.bat
|
||||
```
|
||||
|
||||
**Voraussetzung**: Python 3.x (lokal installiert oder via `NETWORK_INTERPRETER_PATH` Umgebungsvariable).
|
||||
|
||||
## Konfiguration
|
||||
|
||||
Konfigurationsdateien in `cfg/` steuern das Verhalten:
|
||||
|
||||
| Datei | Zweck |
|
||||
|-------|-------|
|
||||
| `allgemein.cfg` | Layernamen, geometrische Toleranzen |
|
||||
| `BMK.cfg` | Betriebsmittelkennzeichnung, Kabeltyp-Zuordnung, Routing-Regeln |
|
||||
| `kabel.cfg` | SIVAS-Artikelnummern je Kabeltyp und Kabellänge |
|
||||
| `bezeichner.cfg` | Artikelnummern-Bezeichner (automatisch aus SIVAS ergänzt) |
|
||||
|
||||
> **Hinweis**: Neuer BMK-Prefix muss in `BMK.cfg` unter `[Routing-Include]` **und** `[Cable-Mapping]` eingetragen werden. Die zugewiesene Kabel-Sektion muss in `kabel.cfg` existieren.
|
||||
|
||||
## Tests
|
||||
|
||||
```bash
|
||||
# Alle Tests
|
||||
bin\run_tests.bat
|
||||
|
||||
# Einzeltest
|
||||
bin\run_test.bat easy
|
||||
|
||||
# Unit-Tests
|
||||
bin\run_unittests.bat
|
||||
```
|
||||
|
||||
## Projektstruktur
|
||||
|
||||
```text
|
||||
bin/ Batch- und Shell-Skripte
|
||||
cfg/ Konfigurationsdateien
|
||||
lib/ Python-Module
|
||||
work/ Arbeitsverzeichnis (Ausgabedateien)
|
||||
testdata/ Test-DXF-Dateien und Referenzdaten
|
||||
data/ SIVAS-Artikeldaten (CSV)
|
||||
doc/ Dokumentation (Deutsch)
|
||||
```
|
||||
|
||||
## Dokumentation
|
||||
|
||||
- [Anwenderdokumentation](doc/Anwenderdoku.md) - Vollständige Anleitung mit Fehlerbehandlung
|
||||
- [Kurzanleitung / Fehlerfälle](doc/Anwenderdoku_kurz.md) - Kompakte Referenz
|
||||
- [I/O Converter](doc/Anwenderdoku_ioconverter.md) - EA-Listen und TIA-Portal/WSCAD-Export
|
||||
- [Übersetzungsworkflow](doc/translate.md) - Dokumentation zum Textextraktions- und Übersetzungssystem
|
||||
- [Symbole](doc/Symbole_und_Benennungen.md) - Beschreibung des Aufbaus und Attribute der zu verwendenden Symbole, damit die Erkennung funktioniert
|
||||
|
||||
## Lizenz
|
||||
|
||||
Intern - Schoenenberger
|
||||
@@ -0,0 +1,15 @@
|
||||
@echo off
|
||||
CALL manage_interpreter.bat activate
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to activate Python environment
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
pushd "%PROJECT%"
|
||||
|
||||
"%VIRTUAL_ENV%\Scripts\python.exe" -m lib.create_example %*
|
||||
set PYTHON_EXIT=%ERRORLEVEL%
|
||||
|
||||
popd
|
||||
CALL manage_interpreter.bat deactivate
|
||||
exit /b %PYTHON_EXIT%
|
||||
@@ -0,0 +1,15 @@
|
||||
@echo off
|
||||
CALL manage_interpreter.bat activate
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to activate Python environment
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
pushd "%PROJECT%"
|
||||
|
||||
"%VIRTUAL_ENV%\Scripts\python.exe" -m lib.create_numbers %*
|
||||
set PYTHON_EXIT=%ERRORLEVEL%
|
||||
|
||||
popd
|
||||
CALL manage_interpreter.bat deactivate
|
||||
exit /b %PYTHON_EXIT%
|
||||
@@ -1,4 +1,15 @@
|
||||
@echo off
|
||||
CALL manage_interpreter.bat activate_interpreter
|
||||
python %PROJECT_LIB%\drawdxf.py %*
|
||||
CALL manage_interpreter.bat deactivate_interpreter
|
||||
CALL manage_interpreter.bat activate
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to activate Python environment
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
pushd "%PROJECT%"
|
||||
|
||||
"%VIRTUAL_ENV%\Scripts\python.exe" -m lib.drawdxf %*
|
||||
set PYTHON_EXIT=%ERRORLEVEL%
|
||||
|
||||
popd
|
||||
CALL manage_interpreter.bat deactivate
|
||||
exit /b %PYTHON_EXIT%
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/manage_interpreter.sh" activate
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Failed to activate Python environment"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pushd "$PROJECT" > /dev/null
|
||||
|
||||
"$VIRTUAL_ENV/bin/python" -m lib.drawdxf "$@"
|
||||
PYTHON_EXIT=$?
|
||||
|
||||
popd > /dev/null
|
||||
source "$SCRIPT_DIR/manage_interpreter.sh" deactivate
|
||||
exit $PYTHON_EXIT
|
||||
@@ -0,0 +1,66 @@
|
||||
@echo off
|
||||
|
||||
call setenv.bat
|
||||
|
||||
mkdir %INSTALL_DIR%
|
||||
|
||||
set SHORTCUT1=%INSTALL_DIR%\create_cables.lnk
|
||||
set TARGET1=%PROJECT_BIN%\getexdraw.bat
|
||||
set ICON1=%PROJECT_DOC%\img\Icons\Icon_getex.ico
|
||||
|
||||
set SHORTCUT2=%INSTALL_DIR%\IOconverter.lnk
|
||||
set TARGET2=%PROJECT_BIN%\ioconverter.bat
|
||||
set ICON2=%PROJECT_DOC%\img\Icons\Icon_portal.ico
|
||||
|
||||
set SHORTCUT3=%INSTALL_DIR%\tr_dxf2txt.lnk
|
||||
set TARGET_TRTXT=%PROJECT_BIN%\tr2txt.bat
|
||||
set ICON3=%PROJECT_DOC%\img\Icons\dxf2txt.ico
|
||||
|
||||
set SHORTCUT_CS=%INSTALL_DIR%\tr_dxf2CS.lnk
|
||||
set TARGET_CS=%PROJECT_BIN%\tr2dxf_cs.bat
|
||||
set ICON_CS=%PROJECT_DOC%\img\Icons\dxfCS.ico
|
||||
|
||||
set SHORTCUT_EN=%INSTALL_DIR%\tr_dxf2EN.lnk
|
||||
set TARGET_EN=%PROJECT_BIN%\tr2dxf_en.bat
|
||||
set ICON_EN=%PROJECT_DOC%\img\Icons\dxfEN.ico
|
||||
|
||||
set SHORTCUT_FR=%INSTALL_DIR%\tr_dxf2FR.lnk
|
||||
set TARGET_FR=%PROJECT_BIN%\tr2dxf_fr.bat
|
||||
set ICON_FR=%PROJECT_DOC%\img\Icons\dxfFR.ico
|
||||
|
||||
set SHORTCUT_IT=%INSTALL_DIR%\tr_dxf2IT.lnk
|
||||
set TARGET_IT=%PROJECT_BIN%\tr2dxf_it.bat
|
||||
set ICON_IT=%PROJECT_DOC%\img\Icons\dxfIT.ico
|
||||
|
||||
set SHORTCUT_ES=%INSTALL_DIR%\tr_dxf2ES.lnk
|
||||
set TARGET_ES=%PROJECT_BIN%\tr2dxf_es.bat
|
||||
set ICON_ES=%PROJECT_DOC%\img\Icons\dxfES.ico
|
||||
|
||||
REM ersetze die Zeile mit setenv.bat durch die mit dem neuen Pfad
|
||||
powershell -Command "(Get-Content getexdraw.bat) -replace '^.*setenv.bat$', 'call %PROJECT_BIN%\setenv.bat' | Set-Content getexdraw.bat"
|
||||
powershell -Command "(Get-Content ioconverter.bat) -replace '^.*setenv.bat$', 'call %PROJECT_BIN%\setenv.bat' | Set-Content ioconverter.bat"
|
||||
powershell -Command "(Get-Content tr2txt.bat) -replace '^.*setenv.bat$', 'call %PROJECT_BIN%\setenv.bat' | Set-Content tr2txt.bat"
|
||||
|
||||
powershell -Command "(Get-Content tr2dxf_cs.bat) -replace '^.*setenv.bat$', 'call %PROJECT_BIN%\setenv.bat' | Set-Content tr2dxf_cs.bat"
|
||||
powershell -Command "(Get-Content tr2dxf_en.bat) -replace '^.*setenv.bat$', 'call %PROJECT_BIN%\setenv.bat' | Set-Content tr2dxf_en.bat"
|
||||
powershell -Command "(Get-Content tr2dxf_fr.bat) -replace '^.*setenv.bat$', 'call %PROJECT_BIN%\setenv.bat' | Set-Content tr2dxf_fr.bat"
|
||||
powershell -Command "(Get-Content tr2dxf_it.bat) -replace '^.*setenv.bat$', 'call %PROJECT_BIN%\setenv.bat' | Set-Content tr2dxf_it.bat"
|
||||
powershell -Command "(Get-Content tr2dxf_es.bat) -replace '^.*setenv.bat$', 'call %PROJECT_BIN%\setenv.bat' | Set-Content tr2dxf_es.bat"
|
||||
|
||||
REM Icon1 anlegen für getexdraw
|
||||
powershell -Command "$s=(New-Object -COM WScript.Shell).CreateShortcut('%SHORTCUT1%');$s.TargetPath='%TARGET1%';$s.IconLocation='%ICON1%';$s.Save()"
|
||||
REM Icon2 anlegen für Ioconverter
|
||||
powershell -Command "$s=(New-Object -COM WScript.Shell).CreateShortcut('%SHORTCUT2%');$s.TargetPath='%TARGET2%';$s.IconLocation='%ICON2%';$s.Save()"
|
||||
|
||||
REM Icon für Txt Extraktion anlegen
|
||||
powershell -Command "$s=(New-Object -COM WScript.Shell).CreateShortcut('%SHORTCUT3%');$s.TargetPath='%TARGET_TRTXT%';$s.IconLocation='%ICON3%';$s.Save()"
|
||||
|
||||
REM Icon für Übersetzungen anlegen
|
||||
powershell -Command "$s=(New-Object -COM WScript.Shell).CreateShortcut('%SHORTCUT_CS%');$s.TargetPath='%TARGET_CS%';$s.IconLocation='%ICON_CS%';$s.Save()"
|
||||
powershell -Command "$s=(New-Object -COM WScript.Shell).CreateShortcut('%SHORTCUT_EN%');$s.TargetPath='%TARGET_EN%';$s.IconLocation='%ICON_EN%';$s.Save()"
|
||||
powershell -Command "$s=(New-Object -COM WScript.Shell).CreateShortcut('%SHORTCUT_FR%');$s.TargetPath='%TARGET_FR%';$s.IconLocation='%ICON_FR%';$s.Save()"
|
||||
powershell -Command "$s=(New-Object -COM WScript.Shell).CreateShortcut('%SHORTCUT_IT%');$s.TargetPath='%TARGET_IT%';$s.IconLocation='%ICON_IT%';$s.Save()"
|
||||
powershell -Command "$s=(New-Object -COM WScript.Shell).CreateShortcut('%SHORTCUT_ES%');$s.TargetPath='%TARGET_ES%';$s.IconLocation='%ICON_ES%';$s.Save()"
|
||||
|
||||
REM Öffne den Ordner damit man sieht ob es geklappt hat
|
||||
explorer.exe %INSTALL_DIR%
|
||||
@@ -0,0 +1,25 @@
|
||||
@echo on
|
||||
|
||||
call setenv.bat
|
||||
|
||||
DEL /Q %INSTALL_DIR%\create_cables.lnk
|
||||
DEL /Q %INSTALL_DIR%\IOconverter.lnk
|
||||
DEL /Q %INSTALL_DIR%\tr_dxf2txt.lnk
|
||||
DEL /Q %INSTALL_DIR%\tr_dxf2CS.lnk
|
||||
DEL /Q %INSTALL_DIR%\tr_dxf2EN.lnk
|
||||
DEL /Q %INSTALL_DIR%\tr_dxf2FR.lnk
|
||||
DEL /Q %INSTALL_DIR%\tr_dxf2IT.lnk
|
||||
DEL /Q %INSTALL_DIR%\tr_dxf2ES.lnk
|
||||
RD /Q %INSTALL_DIR%
|
||||
|
||||
git checkout %PROJECT_BIN%\getexdraw.bat
|
||||
git checkout %PROJECT_BIN%\ioconverter.bat
|
||||
git checkout %PROJECT_BIN%\tr2txt.bat
|
||||
|
||||
git checkout %PROJECT_BIN%\tr2dxf_cs.bat
|
||||
git checkout %PROJECT_BIN%\tr2dxf_en.bat
|
||||
git checkout %PROJECT_BIN%\tr2dxf_fr.bat
|
||||
git checkout %PROJECT_BIN%\tr2dxf_it.bat
|
||||
git checkout %PROJECT_BIN%\tr2dxf_es.bat
|
||||
|
||||
pause
|
||||
@@ -0,0 +1,54 @@
|
||||
@echo off
|
||||
|
||||
if [%1]==[] goto usage
|
||||
for %%i in ("%~1") do (
|
||||
set "FILENAME=%%~ni"
|
||||
set "EXT=%%~xi"
|
||||
set "DIR=%%~dpi"
|
||||
)
|
||||
call c:\kabellaengen\bin\setenv.bat
|
||||
|
||||
REM echo Dateiname ohne Erweiterung: %FILENAME%
|
||||
REM echo Erweiterung: %EXT%
|
||||
REM echo Verzeichnis: %DIR%
|
||||
REM
|
||||
REM Namen der auf dem RENAMER Layer gefundenen Symbole, die überschrieben werden sollen
|
||||
set JSON_SYMBOLS=%FILENAME%_symbols.json
|
||||
|
||||
REM Fehlerdatei
|
||||
set ERROR_FILE=%FILENAME%_errors.json
|
||||
|
||||
|
||||
if exist "%~dp0_setenv.bat" (
|
||||
echo Lade lokale Umgebungseinstellungen aus _setenv.bat...
|
||||
call "%~dp0_setenv.bat"
|
||||
)
|
||||
REM Zielverzeichnis
|
||||
set TARGET_DIR="%PROJECT_IO_RESULTS%\%FILENAME%"
|
||||
mkdir "%TARGET_DIR%"
|
||||
REM lösche alte Fehlermeldungen
|
||||
del "%PROJECT_WORK%\%ERROR_FILE%"
|
||||
|
||||
|
||||
|
||||
echo === Creating enriched dxf file ===
|
||||
call create_numbers.bat --filename %1 --errorfile %PROJECT_WORK%\%ERROR_FILE% --write %PROJECT_WORK%\%JSON_SYMBOLS%
|
||||
if exist "%PROJECT_WORK%\%ERROR_FILE%" (
|
||||
@echo -failed- errors found during processing!
|
||||
pause
|
||||
move %PROJECT_WORK%\%ERROR_FILE% %TARGET_DIR%
|
||||
move %PROJECT_WORK%\%JSON_SYMBOLS% %TARGET_DIR%
|
||||
goto :eof
|
||||
)
|
||||
echo move %PROJECT_WORK%\%FILENAME%_* %TARGET_DIR%
|
||||
move %PROJECT_WORK%\%FILENAME%_* %TARGET_DIR%
|
||||
pause
|
||||
goto :eof
|
||||
|
||||
|
||||
:usage
|
||||
@echo Usage: %0 ^<dxfinWorkOrdner.dxf^>
|
||||
exit /B 1
|
||||
goto :eof
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
@echo off
|
||||
|
||||
if [%1]==[] goto usage
|
||||
for %%i in ("%~1") do (
|
||||
set "FILENAME=%%~ni"
|
||||
set "EXT=%%~xi"
|
||||
set "DIR=%%~dpi"
|
||||
)
|
||||
call C:\10-develop\gitea\kabellaengen\bin\setenv.bat
|
||||
|
||||
REM echo Dateiname ohne Erweiterung: %FILENAME%
|
||||
REM echo Erweiterung: %EXT%
|
||||
REM echo Verzeichnis: %DIR%
|
||||
REM
|
||||
REM Namen der Ergebnisdateien
|
||||
set RESULT_JSON=%FILENAME%_texts.json
|
||||
|
||||
if exist "%~dp0_setenv.bat" (
|
||||
echo Lade lokale Umgebungseinstellungen aus _setenv.bat...
|
||||
call "%~dp0_setenv.bat"
|
||||
)
|
||||
REM Zielverzeichnis
|
||||
set TARGET_DIR=%PROJECT_WORK%
|
||||
mkdir "%TARGET_DIR%"
|
||||
|
||||
echo.
|
||||
echo === Extracting TEXT and MTEXT from DXF ===
|
||||
call translate.bat --filename %FILENAME%%EXT% --extract -t json --outname %RESULT_JSON%
|
||||
if not exist "%PROJECT_WORK%\%RESULT_JSON%
|
||||
" (
|
||||
@echo == failed: extracting texts
|
||||
pause
|
||||
goto :eof
|
||||
)
|
||||
echo.
|
||||
echo === Translation file created: %PROJECT_WORK%\%RESULT_JSON% ===
|
||||
pause
|
||||
goto :eof
|
||||
|
||||
|
||||
:usage
|
||||
@echo Usage: %0 ^<dxfinWorkOrdner.dxf^>
|
||||
exit /B 1
|
||||
goto :eof
|
||||
|
||||
|
||||
@@ -1,15 +1,70 @@
|
||||
@echo off
|
||||
|
||||
if [%1]==[] goto usage
|
||||
for /F %%i in ("%1") do set FILENAME=%%~ni
|
||||
for %%i in ("%~1") do (
|
||||
set "FILENAME=%%~ni"
|
||||
set "EXT=%%~xi"
|
||||
set "DIR=%%~dpi"
|
||||
)
|
||||
call C:\kabellaengen\bin\setenv.bat
|
||||
|
||||
echo --hole Positionen
|
||||
call getpositions.bat --filename %1 -s -r -w %1
|
||||
echo --erzeuge Graph mit Routing
|
||||
call routing.bat --filename %FILENAME%.json -w todraw.json
|
||||
echo --zeichne Kabel in dxf Datei
|
||||
call draw_dxf.bat --filename todraw.json --new %FILENAME%_cables.dxf -x %FILENAME%_cables.xlsx --copy_layer %FILENAME%_reduziert.dxf --origin %1
|
||||
goto :eof
|
||||
REM echo Dateiname ohne Erweiterung: %FILENAME%
|
||||
REM echo Erweiterung: %EXT%
|
||||
REM echo Verzeichnis: %DIR%
|
||||
REM
|
||||
REM Namen der Zwischenergebnis Dateien
|
||||
set JSON_POS=%FILENAME%_positionsdraw.json
|
||||
set JSON_TODRAW=%FILENAME%_todraw.json
|
||||
REM Namen der Ergebnisdateien
|
||||
set ERROR_DOUBLE=%FILENAME%_errors.json
|
||||
set EXCEL_RES=%FILENAME%_cables.xlsx
|
||||
set DXF_RES=%FILENAME%_cables.dxf
|
||||
|
||||
if exist "%~dp0_setenv.bat" (
|
||||
echo Lade lokale Umgebungseinstellungen aus _setenv.bat...
|
||||
call "%~dp0_setenv.bat"
|
||||
)
|
||||
REM Zielverzeichnis
|
||||
set TARGET_DIR=%PROJECT_BOM_RESULTS%\%FILENAME%
|
||||
mkdir "%TARGET_DIR%"
|
||||
REM lösche alte Fehlermeldungen
|
||||
del "%PROJECT_WORK%\%ERROR_DOUBLE%"
|
||||
|
||||
echo.
|
||||
echo === Fetching Positions ===
|
||||
call getpositions.bat --filename %1 -s -r -w %JSON_POS% -e %ERROR_DOUBLE%
|
||||
if exist "%PROJECT_WORK%\%ERROR_DOUBLE%" (
|
||||
@echo -failed- errors found, e.g. duplicate IDs in given layout
|
||||
pause
|
||||
move %PROJECT_WORK%\%ERROR_DOUBLE% %TARGET_DIR%
|
||||
move %PROJECT_WORK%\%JSON_TODRAW% %TARGET_DIR%
|
||||
goto :eof
|
||||
)
|
||||
if not exist "%PROJECT_WORK%\%JSON_POS%" (
|
||||
@echo -failed- getpositions
|
||||
pause
|
||||
goto :eof
|
||||
)
|
||||
echo.
|
||||
echo === Creating Graph for Routing ===
|
||||
call routing.bat --filename %JSON_POS% -w %JSON_TODRAW%
|
||||
if not exist "%PROJECT_WORK%\%JSON_TODRAW%" (
|
||||
@echo -failed- routing
|
||||
pause
|
||||
goto :eof
|
||||
)
|
||||
echo.
|
||||
echo === Writing Output Files ===
|
||||
call draw_dxf.bat --filename %JSON_TODRAW% --new %DXF_RES% -x %EXCEL_RES%
|
||||
if not exist "%PROJECT_WORK%\%EXCEL_RES%" (
|
||||
@echo -failed- draw_dxf
|
||||
pause
|
||||
goto :eof
|
||||
)
|
||||
echo.
|
||||
|
||||
move %PROJECT_WORK%\%FILENAME%_* %TARGET_DIR%
|
||||
pause
|
||||
|
||||
|
||||
:usage
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 <dxfinWorkOrdner.dxf>"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
INPUT_FILE="$1"
|
||||
FILENAME=$(basename "$INPUT_FILE" .dxf)
|
||||
DIR=$(dirname "$INPUT_FILE")
|
||||
|
||||
# Namen der Zwischenergebnis Dateien
|
||||
JSON_POS="${FILENAME}_positionsdraw.json"
|
||||
JSON_TODRAW="${FILENAME}_todraw.json"
|
||||
# Namen der Ergebnisdateien
|
||||
ERROR_DOUBLE="${FILENAME}_errors.json"
|
||||
EXCEL_RES="${FILENAME}_cables.xlsx"
|
||||
DXF_RES="${FILENAME}_cables.dxf"
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/setenv.sh"
|
||||
|
||||
echo
|
||||
echo "=== Fetching Positions ==="
|
||||
"$SCRIPT_DIR/getpositions.sh" --filename "$1" -s -r -w "$JSON_POS" -e "$ERROR_DOUBLE"
|
||||
|
||||
if [ -f "$PROJECT_WORK/$ERROR_DOUBLE" ]; then
|
||||
echo "-failed- duplicate IDs in given layout"
|
||||
read -p "Press any key to continue..."
|
||||
mv "$PROJECT_WORK/$ERROR_DOUBLE" "$PROJECT_BOM_RESULTS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$PROJECT_WORK/$JSON_POS" ]; then
|
||||
echo "-failed- getpositions"
|
||||
read -p "Press any key to continue..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "=== Creating Graph for Routing ==="
|
||||
"$SCRIPT_DIR/routing.sh" --filename "$JSON_POS" -w "$JSON_TODRAW"
|
||||
|
||||
if [ ! -f "$PROJECT_WORK/$JSON_TODRAW" ]; then
|
||||
echo "-failed- routing"
|
||||
read -p "Press any key to continue..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "=== Writing Output Files ==="
|
||||
"$SCRIPT_DIR/draw_dxf.sh" --filename "$JSON_TODRAW" --new "$DXF_RES" -x "$EXCEL_RES"
|
||||
|
||||
if [ ! -f "$PROJECT_WORK/$EXCEL_RES" ]; then
|
||||
echo "-failed- draw_dxf"
|
||||
read -p "Press any key to continue..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
mkdir -p "$PROJECT_BOM_RESULTS/$FILENAME"
|
||||
mv "$PROJECT_WORK/${FILENAME}_"* "$PROJECT_BOM_RESULTS/$FILENAME"
|
||||
read -p "Press any key to continue..."
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
@echo off
|
||||
CALL manage_interpreter.bat activate_interpreter
|
||||
python %PROJECT_LIB%\getpositions.py %*
|
||||
CALL manage_interpreter.bat deactivate_interpreter
|
||||
CALL manage_interpreter.bat activate
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to activate Python environment
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
pushd "%PROJECT%"
|
||||
|
||||
"%VIRTUAL_ENV%\Scripts\python.exe" -m lib.getpositions %*
|
||||
set PYTHON_EXIT=%ERRORLEVEL%
|
||||
|
||||
popd
|
||||
CALL manage_interpreter.bat deactivate
|
||||
exit /b %PYTHON_EXIT%
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
# getpositions.sh
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/manage_interpreter.sh" activate
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Failed to activate Python environment"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pushd "$PROJECT" > /dev/null
|
||||
|
||||
"$VIRTUAL_ENV/bin/python" -m lib.getpositions "$@"
|
||||
PYTHON_EXIT=$?
|
||||
|
||||
popd > /dev/null
|
||||
source "$SCRIPT_DIR/manage_interpreter.sh" deactivate
|
||||
exit $PYTHON_EXIT
|
||||
@@ -1,7 +1,7 @@
|
||||
call setenv.bat
|
||||
if not exist %PROJECT%\.venv (
|
||||
ECHO Initialisiere Python virtual environment...
|
||||
python -m venv %PROJECT%\.venv --upgrade-deps
|
||||
py -m venv %PROJECT%\.venv --upgrade-deps
|
||||
ECHO Erfolgreich.
|
||||
|
||||
call %PROJECT%\.venv\Scripts\activate.bat
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/setenv.sh"
|
||||
|
||||
if [ ! -d "$PROJECT/.venv" ]; then
|
||||
echo "Initialisiere Python virtual environment..."
|
||||
python3 -m venv "$PROJECT/.venv" --upgrade-deps
|
||||
echo "Erfolgreich."
|
||||
|
||||
source "$PROJECT/.venv/bin/activate"
|
||||
echo "Installiere erforderliche Python Packages..."
|
||||
pip install -r "$PROJECT_LIB/requirements.txt" -q
|
||||
echo "Erfolgreich"
|
||||
deactivate
|
||||
else
|
||||
echo "Erforderliche Python Packages bereits installiert!"
|
||||
fi
|
||||
@@ -0,0 +1,68 @@
|
||||
@echo off
|
||||
|
||||
if [%1]==[] goto usage
|
||||
for %%i in ("%~1") do (
|
||||
set "FILENAME=%%~ni"
|
||||
set "EXT=%%~xi"
|
||||
set "DIR=%%~dpi"
|
||||
)
|
||||
call C:\kabellaengen\bin\setenv.bat
|
||||
|
||||
REM echo Dateiname ohne Erweiterung: %FILENAME%
|
||||
REM echo Erweiterung: %EXT%
|
||||
REM echo Verzeichnis: %DIR%
|
||||
REM
|
||||
REM Namen der Zwischenergebnis Dateien
|
||||
set JSON_POS=%FILENAME%_positionsconv.json
|
||||
set JSON_TODRAW=%FILENAME%_todraw.json
|
||||
REM Namen der Ergebnisdateien
|
||||
set ERROR_DOUBLE=%FILENAME%_errors.json
|
||||
set RESULT_TIA=%FILENAME%-*_TIA.xlsx
|
||||
|
||||
if exist "%~dp0_setenv.bat" (
|
||||
echo Lade lokale Umgebungseinstellungen aus _setenv.bat...
|
||||
call "%~dp0_setenv.bat"
|
||||
)
|
||||
REM Zielverzeichnis
|
||||
set TARGET_DIR=%PROJECT_IO_RESULTS%\%FILENAME%
|
||||
mkdir "%TARGET_DIR%"
|
||||
REM lösche alte Fehlermeldungen
|
||||
del "%PROJECT_WORK%\%ERROR_DOUBLE%"
|
||||
|
||||
|
||||
|
||||
echo.
|
||||
echo === Fetching Positions ===
|
||||
call getpositions.bat --filename %1 -s -r -w %JSON_POS% -e %ERROR_DOUBLE%
|
||||
if exist "%PROJECT_WORK%\%ERROR_DOUBLE%" (
|
||||
@echo == failed: errors, e.g. duplicate IDs in given layout
|
||||
pause
|
||||
move %PROJECT_WORK%\%ERROR_DOUBLE% %TARGET_DIR%
|
||||
move %PROJECT_WORK%\%JSON_TODRAW% %TARGET_DIR%
|
||||
|
||||
goto :eof
|
||||
)
|
||||
if not exist "%PROJECT_WORK%\%JSON_POS%" (
|
||||
@echo == failed: getpositions
|
||||
pause
|
||||
goto :eof
|
||||
)
|
||||
echo === Creating Excel Files for TIA, WSCAD, .. ===
|
||||
call portalexport.bat --filename %JSON_POS% --outname %FILENAME%
|
||||
if not exist "%PROJECT_WORK%\%RESULT_TIA%" (
|
||||
@echo == failed: creating .xlsx files
|
||||
pause
|
||||
goto :eof
|
||||
)
|
||||
echo move %PROJECT_WORK%\%FILENAME%-* %TARGET_DIR%
|
||||
move %PROJECT_WORK%\%FILENAME%-* %TARGET_DIR%
|
||||
pause
|
||||
goto :eof
|
||||
|
||||
|
||||
:usage
|
||||
@echo Usage: %0 ^<dxfinWorkOrdner.dxf^>
|
||||
exit /B 1
|
||||
goto :eof
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 <dxfinWorkOrdner.dxf>"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
INPUT_FILE="$1"
|
||||
FILENAME=$(basename "$INPUT_FILE" .dxf)
|
||||
DIR=$(dirname "$INPUT_FILE")
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/setenv.sh"
|
||||
|
||||
# Namen der Zwischenergebnis Dateien
|
||||
JSON_POS="${FILENAME}_positionsconv.json"
|
||||
JSON_TODRAW="${FILENAME}_todraw.json"
|
||||
# Namen der Ergebnisdateien
|
||||
ERROR_DOUBLE="${FILENAME}_errors.json"
|
||||
RESULT_TIA="${FILENAME}-*_TIA.xlsx"
|
||||
|
||||
echo
|
||||
echo "=== Fetching Positions ==="
|
||||
"$SCRIPT_DIR/getpositions.sh" --filename "$1" -s -r -w "$JSON_POS" -e "$ERROR_DOUBLE"
|
||||
|
||||
if [ -f "$PROJECT_WORK/$ERROR_DOUBLE" ]; then
|
||||
echo "== failed: duplicate IDs in given layout"
|
||||
read -p "Press any key to continue..."
|
||||
mv "$PROJECT_WORK/$ERROR_DOUBLE" "$PROJECT_IO_RESULTS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$PROJECT_WORK/$JSON_POS" ]; then
|
||||
echo "== failed: getpositions"
|
||||
read -p "Press any key to continue..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Creating Excel Files for TIA, WSCAD, .. ==="
|
||||
"$SCRIPT_DIR/portalexport.sh" --filename "$JSON_POS" --outname "$FILENAME"
|
||||
|
||||
if [ ! -f "$PROJECT_WORK/$RESULT_TIA" ]; then
|
||||
echo "== failed: creating .xlsx files"
|
||||
read -p "Press any key to continue..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$PROJECT_IO_RESULTS/$FILENAME"
|
||||
echo "move $PROJECT_WORK/${FILENAME}-* $PROJECT_IO_RESULTS/$FILENAME"
|
||||
mv "$PROJECT_WORK/${FILENAME}"-* "$PROJECT_IO_RESULTS/$FILENAME"
|
||||
read -p "Press any key to continue..."
|
||||
@@ -1,28 +1,35 @@
|
||||
@echo off
|
||||
CALL setenv.bat
|
||||
IF DEFINED NETWORK_INTERPRETER_PATH (
|
||||
goto %~1_network
|
||||
|
||||
IF /I "%1"=="activate" GOTO activate
|
||||
IF /I "%1"=="deactivate" GOTO deactivate
|
||||
IF /I "%1"=="activate_interpreter" GOTO activate
|
||||
IF /I "%1"=="deactivate_interpreter" GOTO deactivate
|
||||
GOTO :eof
|
||||
|
||||
|
||||
:activate
|
||||
REM Interpreter wählen
|
||||
IF DEFINED NETWORK_PYTHON (
|
||||
SET PYTHON_EXE=%NETWORK_PYTHON%\python.exe
|
||||
) ELSE (
|
||||
goto %~1_local
|
||||
SET PYTHON_EXE=python
|
||||
)
|
||||
|
||||
:activate_interpreter_local
|
||||
IF NOT EXIST %PROJECT%\.venv CALL %PROJECT_BIN%\install_py.bat
|
||||
CALL %PROJECT%\.venv\Scripts\activate.bat
|
||||
goto :eof
|
||||
REM venv sicherstellen
|
||||
IF NOT EXIST "%PROJECT%\.venv" (
|
||||
"%PYTHON_EXE%" -m venv "%PROJECT%\.venv"
|
||||
)
|
||||
|
||||
:deactivate_interpreter_local
|
||||
deactivate
|
||||
goto :eof
|
||||
REM venv aktivieren
|
||||
CALL "%PROJECT%\.venv\Scripts\activate.bat"
|
||||
|
||||
:activate_interpreter_network
|
||||
SET OLD_PATH=%PATH%
|
||||
SET PATH=%NETWORK_INTERPRETER_PATH%;%PATH%
|
||||
goto :eof
|
||||
REM Interpreter festnageln
|
||||
SET VIRTUAL_ENV_PYTHON=%PYTHON_EXE%
|
||||
GOTO :eof
|
||||
|
||||
:deactivate_interpreter_network
|
||||
SET PATH=%OLD_PATH%
|
||||
SET OLD_PATH=
|
||||
SET NETWORK_INTERPRETER_PATH=
|
||||
goto :eof
|
||||
|
||||
:deactivate
|
||||
CALL "%PROJECT%\.venv\Scripts\deactivate.bat"
|
||||
SET VIRTUAL_ENV_PYTHON=
|
||||
GOTO :eof
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Source setenv.sh if not already loaded
|
||||
if [ -z "$PROJECT" ]; then
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/setenv.sh"
|
||||
fi
|
||||
|
||||
activate() {
|
||||
# Choose Python interpreter
|
||||
if [ -n "$NETWORK_PYTHON" ]; then
|
||||
PYTHON_EXE="$NETWORK_PYTHON/bin/python"
|
||||
else
|
||||
PYTHON_EXE="python3"
|
||||
fi
|
||||
|
||||
# Ensure venv exists
|
||||
if [ ! -d "$PROJECT/.venv" ]; then
|
||||
echo "Creating virtual environment..."
|
||||
"$PYTHON_EXE" -m venv "$PROJECT/.venv"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Failed to create virtual environment"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Activate venv
|
||||
if [ -f "$PROJECT/.venv/bin/activate" ]; then
|
||||
source "$PROJECT/.venv/bin/activate"
|
||||
# Pin the interpreter
|
||||
export VIRTUAL_ENV_PYTHON="$PYTHON_EXE"
|
||||
else
|
||||
echo "ERROR: Virtual environment activation script not found"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
deactivate() {
|
||||
if [ -n "$VIRTUAL_ENV" ]; then
|
||||
deactivate 2>/dev/null || true
|
||||
unset VIRTUAL_ENV_PYTHON
|
||||
fi
|
||||
}
|
||||
|
||||
# Call function based on argument
|
||||
case "$1" in
|
||||
activate|activate_interpreter)
|
||||
activate
|
||||
;;
|
||||
deactivate|deactivate_interpreter)
|
||||
deactivate
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {activate|deactivate|activate_interpreter|deactivate_interpreter}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,15 @@
|
||||
@echo off
|
||||
CALL manage_interpreter.bat activate
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to activate Python environment
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
pushd "%PROJECT%"
|
||||
|
||||
"%VIRTUAL_ENV%\Scripts\python.exe" -m lib.portalexport %*
|
||||
set PYTHON_EXIT=%ERRORLEVEL%
|
||||
|
||||
popd
|
||||
CALL manage_interpreter.bat deactivate
|
||||
exit /b %PYTHON_EXIT%
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/manage_interpreter.sh" activate
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Failed to activate Python environment"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pushd "$PROJECT" > /dev/null
|
||||
|
||||
"$VIRTUAL_ENV/bin/python" -m lib.portalexport "$@"
|
||||
PYTHON_EXIT=$?
|
||||
|
||||
popd > /dev/null
|
||||
source "$SCRIPT_DIR/manage_interpreter.sh" deactivate
|
||||
exit $PYTHON_EXIT
|
||||
@@ -1,4 +1,15 @@
|
||||
@echo off
|
||||
CALL manage_interpreter.bat activate_interpreter
|
||||
python %PROJECT_LIB%\routing.py %*
|
||||
CALL manage_interpreter.bat deactivate_interpreter
|
||||
CALL manage_interpreter.bat activate
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to activate Python environment
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
pushd "%PROJECT%"
|
||||
|
||||
"%VIRTUAL_ENV%\Scripts\python.exe" -m lib.routing %*
|
||||
set PYTHON_EXIT=%ERRORLEVEL%
|
||||
|
||||
popd
|
||||
CALL manage_interpreter.bat deactivate
|
||||
exit /b %PYTHON_EXIT%
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/manage_interpreter.sh" activate
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Failed to activate Python environment"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pushd "$PROJECT" > /dev/null
|
||||
|
||||
"$VIRTUAL_ENV/bin/python" -m lib.routing "$@"
|
||||
PYTHON_EXIT=$?
|
||||
|
||||
popd > /dev/null
|
||||
source "$SCRIPT_DIR/manage_interpreter.sh" deactivate
|
||||
exit $PYTHON_EXIT
|
||||
@@ -0,0 +1,117 @@
|
||||
@echo off
|
||||
REM ============================================================================
|
||||
REM run_test.bat - Führt Tests für eine einzelne DXF-Datei aus
|
||||
REM
|
||||
REM Usage:
|
||||
REM run_test.bat <filename> - Führt getexdraw Test aus
|
||||
REM run_test.bat <filename> --clean - Führt Test aus und räumt auf
|
||||
REM run_test.bat <filename> --ioconverter - Führt ioconverter Test aus
|
||||
REM run_test.bat <filename> --translation - Führt translation Test aus
|
||||
REM
|
||||
REM Der Dateiname kann mit oder ohne .dxf Erweiterung angegeben werden.
|
||||
REM Die Datei wird standardmäßig im testdata Ordner gesucht.
|
||||
REM ============================================================================
|
||||
|
||||
if [%1]==[] goto usage
|
||||
|
||||
REM Umgebungsvariablen laden
|
||||
call "%~dp0setenv.bat"
|
||||
|
||||
if exist "%~dp0_setenv.bat" (
|
||||
echo Lade lokale Umgebungseinstellungen aus _setenv.bat...
|
||||
call "%~dp0_setenv.bat"
|
||||
)
|
||||
|
||||
REM Dateinamen extrahieren (ohne Pfad und ohne .dxf Erweiterung)
|
||||
set "FILENAME=%~n1"
|
||||
|
||||
REM Prüfe ob Datei im testdata Ordner existiert
|
||||
if not exist "%PROJECT_TEST%\%FILENAME%.dxf" (
|
||||
echo Fehler: Datei %FILENAME%.dxf nicht gefunden in %PROJECT_TEST%
|
||||
echo.
|
||||
goto usage
|
||||
)
|
||||
|
||||
REM Sammle zusätzliche Parameter für run_tests.py
|
||||
set "TEST_PARAMS=--file %FILENAME%"
|
||||
|
||||
REM Prüfe auf zusätzliche Flags
|
||||
:parse_args
|
||||
if "%2"=="" goto run_test
|
||||
if /i "%2"=="--clean" (
|
||||
set "TEST_PARAMS=%TEST_PARAMS% --clean"
|
||||
shift
|
||||
goto parse_args
|
||||
)
|
||||
if /i "%2"=="--ioconverter" (
|
||||
set "TEST_PARAMS=%TEST_PARAMS% --ioconverter"
|
||||
shift
|
||||
goto parse_args
|
||||
)
|
||||
if /i "%2"=="--translation" (
|
||||
set "TEST_PARAMS=%TEST_PARAMS% --translation"
|
||||
shift
|
||||
goto parse_args
|
||||
)
|
||||
REM Unbekannte Parameter ignorieren oder durchreichen
|
||||
shift
|
||||
goto parse_args
|
||||
|
||||
:run_test
|
||||
echo.
|
||||
echo ============================================================================
|
||||
echo Führe Test aus für: %FILENAME%.dxf
|
||||
echo Test-Parameter: %TEST_PARAMS%
|
||||
echo ============================================================================
|
||||
echo.
|
||||
|
||||
REM Python-Umgebung aktivieren
|
||||
CALL "%PROJECT_BIN%\manage_interpreter.bat" activate
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to activate Python environment
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM Wechsle ins Projektverzeichnis und führe run_tests.py aus
|
||||
pushd "%PROJECT%"
|
||||
|
||||
"%VIRTUAL_ENV%\Scripts\python.exe" -m lib.run_tests %TEST_PARAMS%
|
||||
set TEST_RESULT=%ERRORLEVEL%
|
||||
|
||||
popd
|
||||
REM Python-Umgebung deaktivieren
|
||||
CALL "%PROJECT_BIN%\manage_interpreter.bat" deactivate
|
||||
|
||||
echo.
|
||||
echo ============================================================================
|
||||
if %TEST_RESULT% EQU 0 (
|
||||
echo Test erfolgreich abgeschlossen für: %FILENAME%.dxf
|
||||
) else (
|
||||
echo Test fehlgeschlagen für: %FILENAME%.dxf
|
||||
)
|
||||
echo ============================================================================
|
||||
echo.
|
||||
|
||||
exit /B %TEST_RESULT%
|
||||
|
||||
:usage
|
||||
echo.
|
||||
echo Usage: %~nx0 ^<filename^> [OPTIONS]
|
||||
echo.
|
||||
echo Argumente:
|
||||
echo filename Name der DXF-Datei (mit oder ohne .dxf Erweiterung)
|
||||
echo Die Datei wird im testdata Ordner gesucht.
|
||||
echo.
|
||||
echo Optionen:
|
||||
echo --clean Räumt das work-Verzeichnis nach dem Test auf
|
||||
echo --ioconverter Führt ioconverter Test aus (statt getexdraw)
|
||||
echo --translation Führt translation Test aus (statt getexdraw)
|
||||
echo.
|
||||
echo Beispiele:
|
||||
echo %~nx0 easy
|
||||
echo %~nx0 easy.dxf
|
||||
echo %~nx0 easy --clean
|
||||
echo %~nx0 easy --ioconverter
|
||||
echo %~nx0 Erdungsbsp --translation
|
||||
echo.
|
||||
exit /B 1
|
||||
@@ -0,0 +1,124 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# run_test.sh - Führt Tests für eine einzelne DXF-Datei aus
|
||||
#
|
||||
# Usage:
|
||||
# run_test.sh <filename> - Führt getexdraw Test aus
|
||||
# run_test.sh <filename> --clean - Führt Test aus und räumt auf
|
||||
# run_test.sh <filename> --ioconverter - Führt ioconverter Test aus
|
||||
# run_test.sh <filename> --translation - Führt translation Test aus
|
||||
#
|
||||
# Der Dateiname kann mit oder ohne .dxf Erweiterung angegeben werden.
|
||||
# Die Datei wird standardmäßig im testdata Ordner gesucht.
|
||||
# ============================================================================
|
||||
|
||||
# Funktion für Usage-Ausgabe
|
||||
usage() {
|
||||
echo ""
|
||||
echo "Usage: $(basename "$0") <filename> [OPTIONS]"
|
||||
echo ""
|
||||
echo "Argumente:"
|
||||
echo " filename Name der DXF-Datei (mit oder ohne .dxf Erweiterung)"
|
||||
echo " Die Datei wird im testdata Ordner gesucht."
|
||||
echo ""
|
||||
echo "Optionen:"
|
||||
echo " --clean Räumt das work-Verzeichnis nach dem Test auf"
|
||||
echo " --ioconverter Führt ioconverter Test aus (statt getexdraw)"
|
||||
echo " --translation Führt translation Test aus (statt getexdraw)"
|
||||
echo ""
|
||||
echo "Beispiele:"
|
||||
echo " $(basename "$0") easy"
|
||||
echo " $(basename "$0") easy.dxf"
|
||||
echo " $(basename "$0") easy --clean"
|
||||
echo " $(basename "$0") easy --ioconverter"
|
||||
echo " $(basename "$0") Erdungsbsp --translation"
|
||||
echo ""
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Prüfe ob Parameter übergeben wurde
|
||||
if [ $# -eq 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
# Bestimme das Skript-Verzeichnis
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Umgebungsvariablen laden
|
||||
source "$SCRIPT_DIR/setenv.sh"
|
||||
|
||||
# Lade lokale Umgebungseinstellungen falls vorhanden
|
||||
if [ -f "$SCRIPT_DIR/_setenv.sh" ]; then
|
||||
echo "Lade lokale Umgebungseinstellungen aus _setenv.sh..."
|
||||
source "$SCRIPT_DIR/_setenv.sh"
|
||||
fi
|
||||
|
||||
# Dateinamen extrahieren (ohne Pfad und ohne .dxf Erweiterung)
|
||||
FILENAME=$(basename "$1" .dxf)
|
||||
|
||||
# Prüfe ob Datei im testdata Ordner existiert
|
||||
if [ ! -f "$PROJECT_TEST/$FILENAME.dxf" ]; then
|
||||
echo "Fehler: Datei $FILENAME.dxf nicht gefunden in $PROJECT_TEST"
|
||||
usage
|
||||
fi
|
||||
|
||||
# Sammle Parameter für run_tests.py
|
||||
TEST_PARAMS="--file $FILENAME"
|
||||
|
||||
# Verarbeite zusätzliche Parameter
|
||||
shift
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--clean)
|
||||
TEST_PARAMS="$TEST_PARAMS --clean"
|
||||
;;
|
||||
--ioconverter)
|
||||
TEST_PARAMS="$TEST_PARAMS --ioconverter"
|
||||
;;
|
||||
--translation)
|
||||
TEST_PARAMS="$TEST_PARAMS --translation"
|
||||
;;
|
||||
*)
|
||||
# Unbekannte Parameter ignorieren
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "============================================================================"
|
||||
echo "Führe Test aus für: $FILENAME.dxf"
|
||||
echo "Test-Parameter: $TEST_PARAMS"
|
||||
echo "============================================================================"
|
||||
echo ""
|
||||
|
||||
# Python-Umgebung aktivieren
|
||||
source "$SCRIPT_DIR/manage_interpreter.sh" activate
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Failed to activate Python environment"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Wechsle ins Projektverzeichnis und führe run_tests.py aus
|
||||
pushd "$PROJECT" > /dev/null
|
||||
|
||||
"$VIRTUAL_ENV/bin/python" -m lib.run_tests $TEST_PARAMS
|
||||
TEST_RESULT=$?
|
||||
|
||||
popd > /dev/null
|
||||
|
||||
# Python-Umgebung deaktivieren
|
||||
source "$SCRIPT_DIR/manage_interpreter.sh" deactivate
|
||||
|
||||
echo ""
|
||||
echo "============================================================================"
|
||||
if [ $TEST_RESULT -eq 0 ]; then
|
||||
echo "Test erfolgreich abgeschlossen für: $FILENAME.dxf"
|
||||
else
|
||||
echo "Test fehlgeschlagen für: $FILENAME.dxf"
|
||||
fi
|
||||
echo "============================================================================"
|
||||
echo ""
|
||||
|
||||
exit $TEST_RESULT
|
||||
@@ -0,0 +1,31 @@
|
||||
@echo off
|
||||
REM Test runner batch script for kabellaengen project
|
||||
REM Calls run_tests.py to execute all tests
|
||||
|
||||
call %~dp0setenv.bat
|
||||
|
||||
CALL manage_interpreter.bat activate
|
||||
if errorlevel 1 (
|
||||
echo.
|
||||
echo Failed to activate the Python interpreter!
|
||||
pause
|
||||
exit /B 1
|
||||
)
|
||||
|
||||
pushd "%PROJECT%"
|
||||
|
||||
"%VIRTUAL_ENV%\Scripts\python.exe" -m lib.run_tests %*
|
||||
set PYTHON_EXIT=%ERRORLEVEL%
|
||||
|
||||
popd
|
||||
CALL manage_interpreter.bat deactivate
|
||||
|
||||
if %PYTHON_EXIT% NEQ 0 (
|
||||
echo.
|
||||
echo Tests failed!
|
||||
exit /B 1
|
||||
) else (
|
||||
echo.
|
||||
echo All tests passed!
|
||||
exit /B 0
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
@echo off
|
||||
CALL setenv.bat
|
||||
|
||||
echo ========================================
|
||||
echo running all unittests in lib\Elemente
|
||||
echo ========================================
|
||||
echo.
|
||||
CALL manage_interpreter.bat activate
|
||||
if %ERRORLEVEL% NEQ 0 (
|
||||
echo.
|
||||
echo Failed to activate the Python interpreter!
|
||||
pause
|
||||
exit /B 1
|
||||
)
|
||||
echo Gefundene Testdateien:
|
||||
for /f "delims=" %%f in ('dir /b "%PROJECT_LIB%\*_tests.py" 2^>nul') do echo %%f
|
||||
echo.
|
||||
pushd "%PROJECT%"
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to change to project directory: %PROJECT%
|
||||
CALL manage_interpreter.bat deactivate
|
||||
exit /b 1
|
||||
)
|
||||
"%VIRTUAL_ENV%\Scripts\python.exe" -m unittest discover -t "%PROJECT%" -s lib -p "*_test.py" -v
|
||||
set TEST_EXIT=%ERRORLEVEL%
|
||||
popd
|
||||
if %TEST_EXIT% NEQ 0 (
|
||||
echo.
|
||||
echo Tests failed!
|
||||
CALL manage_interpreter.bat deactivate
|
||||
exit /B 1
|
||||
) else (
|
||||
echo.
|
||||
echo All tests passed!
|
||||
CALL manage_interpreter.bat deactivate
|
||||
exit /B 0
|
||||
)
|
||||
|
||||
@@ -1,26 +1,42 @@
|
||||
@echo off
|
||||
REM ~dp0 steht für das Verzeichnis, in der diese Datei liegt
|
||||
REM falls Umlaute in den Pfaden sind:
|
||||
chcp 65001 > nul
|
||||
|
||||
REM ~dp0 steht für das Verzeichnis, in der diese Datei liegt
|
||||
pushd %~dp0\..
|
||||
|
||||
set PROJECT=%cd%
|
||||
set PROJECT_BIN=%PROJECT%\bin
|
||||
set PROJECT_CFG=%PROJECT%\cfg
|
||||
set PROJECT_DOC=%PROJECT%\doc
|
||||
set PROJECT_LIB=%PROJECT%\lib
|
||||
set PROJECT_DATA=%PROJECT%\data
|
||||
set PROJECT_WORK=%PROJECT%\work
|
||||
set PROJECT_LOG=%PROJECT%\log
|
||||
set PROJECT_TEST=%PROJECT%\testdata
|
||||
set PROJECT_HOT=%PROJECT%\hotfolder
|
||||
set PROJECT_LOG=%PROJECT%\logs
|
||||
set PROJECT_TRANSLATION=%PROJECT%\translation
|
||||
|
||||
set SIVAS_TEILESTAMM=\\195.243.223.3\sivas\jit\programme\KSbExcelExportSivasTeilestamm.exe
|
||||
set SIVAS_EXCEL_EXPORT_DIR=%PROJECT_DATA%
|
||||
|
||||
if not exist %PROJECT%\work mkdir %PROJECT%\work
|
||||
if not exist %PROJECT%\log mkdir %PROJECT%\log
|
||||
if not exist %PROJECT%\data mkdir %PROJECT%\data
|
||||
if not exist %PROJECT%\hotfolder mkdir %PROJECT%\hotfolder
|
||||
if not exist %PROJECT%\translation mkdir %PROJECT%\translation
|
||||
if not exist %PROJECT%\logs mkdir %PROJECT%\logs
|
||||
|
||||
set PROJECT_IO_RESULTS=Z:\Automatisierung\Konvertierungstools\4_io-Konvertierer
|
||||
set PROJECT_BOM_RESULTS=Z:\Automatisierung\Konvertierungstools\3_Kabellaengen-Konvertierer
|
||||
set INSTALL_DIR="%ONEDRIVE%\Desktop\Kabeltool"
|
||||
|
||||
if exist "%~dp0_setenv.bat" (
|
||||
echo Lade lokale Umgebungseinstellungen aus _setenv.bat...
|
||||
call "%~dp0_setenv.bat"
|
||||
)
|
||||
|
||||
REM Prüfe ob PATH bereits erweitert wurde
|
||||
set PATH=%PROJECT_BIN%;%PATH%
|
||||
REM set NETWORK_PYTHON=TO_BE_SET
|
||||
|
||||
|
||||
popd
|
||||
goto :eof
|
||||
|
||||
:set_path
|
||||
set PATH=%PROJECT_BIN%;%PATH%
|
||||
goto r%return%
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Determine the project directory dynamically
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
export PROJECT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
export PROJECT_BIN="$PROJECT/bin"
|
||||
export PROJECT_CFG="$PROJECT/cfg"
|
||||
export PROJECT_DOC="$PROJECT/doc"
|
||||
export PROJECT_LIB="$PROJECT/lib"
|
||||
export PROJECT_DATA="$PROJECT/data"
|
||||
export PROJECT_WORK="$PROJECT/work"
|
||||
export PROJECT_TEST="$PROJECT/testdata"
|
||||
export PROJECT_LOG="$PROJECT/logs"
|
||||
export PROJECT_TRANSLATION="$PROJECT/translation"
|
||||
|
||||
# Linux executable instead of Windows .exe
|
||||
export SIVAS_TEILESTAMM="/usr/local/bin/KSbExcelExportSivasTeilestamm"
|
||||
export SIVAS_EXCEL_EXPORT_DIR="$PROJECT_DATA"
|
||||
|
||||
# Create directories if they don't exist
|
||||
mkdir -p "$PROJECT/work"
|
||||
mkdir -p "$PROJECT/data"
|
||||
mkdir -p "$PROJECT/logs"
|
||||
mkdir -p "$PROJECT/translation"
|
||||
mkdir -p "$PROJECT/testdata"
|
||||
|
||||
# Samba shares (adjust mount points as needed)
|
||||
export PROJECT_IO_RESULTS=$PROJECT_WORK
|
||||
export PROJECT_BOM_RESULTS=$PROJECT_WORK
|
||||
export INSTALL_DIR="$HOME/kabeltool"
|
||||
|
||||
# Add project bin to PATH (only if not already added)
|
||||
export PATH="$PROJECT_BIN:$PATH"
|
||||
|
||||
# Network Python interpreter (optional)
|
||||
# export NETWORK_PYTHON=/path/to/network/python
|
||||
@@ -0,0 +1,100 @@
|
||||
@echo off
|
||||
|
||||
REM Zentrale Batch-Datei f�r DXF/JSON-�bersetzungen
|
||||
REM Wird von tr2dxf_XX.bat Dateien mit Sprachparameter aufgerufen
|
||||
|
||||
if [%1]==[] goto usage
|
||||
if [%2]==[] goto usage
|
||||
|
||||
set "LANG=%1"
|
||||
set "INPUT_FILE=%2"
|
||||
|
||||
for %%i in ("%INPUT_FILE%") do (
|
||||
set "FILENAME=%%~ni"
|
||||
set "EXT=%%~xi"
|
||||
set "DIR=%%~dpi"
|
||||
)
|
||||
|
||||
call "%~dp0setenv.bat"
|
||||
|
||||
REM echo Dateiname ohne Erweiterung: %FILENAME%
|
||||
REM echo Erweiterung: %EXT%
|
||||
REM echo Verzeichnis: %DIR%
|
||||
REM echo Sprache: %LANG%
|
||||
|
||||
REM Zielverzeichnis
|
||||
set TARGET_DIR=%PROJECT_WORK%
|
||||
mkdir "%TARGET_DIR%"
|
||||
|
||||
REM Pr�fe Dateityp und w�hle entsprechenden Workflow
|
||||
if /I "%EXT%"==".json" goto retranslate_json
|
||||
if /I "%EXT%"==".txt" goto retranslate_txt
|
||||
if /I "%EXT%"==".dxf" goto translate_dxf
|
||||
if /I "%EXT%"==".dwg" goto translate_dxf
|
||||
goto invalid_filetype
|
||||
|
||||
:translate_dxf
|
||||
REM Namen der Ergebnisdateien
|
||||
set RESULT_DXF=%FILENAME%_%LANG%.dxf
|
||||
|
||||
echo.
|
||||
echo === Extracting TEXT, MTEXT and symbols, translating to %LANG% ===
|
||||
call translate.bat --filename "%INPUT_FILE%" --translate %LANG% --todxf %RESULT_DXF%
|
||||
if not exist "%PROJECT_WORK%\%RESULT_DXF%" (
|
||||
@echo == failed: extracting texts
|
||||
pause
|
||||
goto :eof
|
||||
)
|
||||
move %PROJECT_WORK%\%RESULT_DXF% %DIR%
|
||||
echo.
|
||||
echo === Translation file created: %DIR%\%RESULT_DXF% ===
|
||||
pause
|
||||
goto :eof
|
||||
|
||||
:retranslate_json
|
||||
echo.
|
||||
echo === Re-translating JSON file with current %LANG%.cfg ===
|
||||
call translate.bat --retranslate-json "%INPUT_FILE%" --translate %LANG%
|
||||
if errorlevel 1 (
|
||||
@echo == failed: re-translating JSON
|
||||
pause
|
||||
goto :eof
|
||||
)
|
||||
echo.
|
||||
echo === JSON file updated: %INPUT_FILE% ===
|
||||
pause
|
||||
goto :eof
|
||||
|
||||
:retranslate_txt
|
||||
echo.
|
||||
echo === Re-translating TXT file with current %LANG%.cfg ===
|
||||
call translate.bat --retranslate-txt "%INPUT_FILE%" --translate %LANG%
|
||||
if errorlevel 1 (
|
||||
@echo == failed: re-translating TXT
|
||||
pause
|
||||
goto :eof
|
||||
)
|
||||
echo.
|
||||
echo === TXT file updated: %INPUT_FILE% ===
|
||||
pause
|
||||
goto :eof
|
||||
|
||||
:invalid_filetype
|
||||
@echo FEHLER: Ung�ltiger Dateityp: %EXT%
|
||||
@echo Erlaubt sind: .dxf, .dwg, .json, .txt
|
||||
pause
|
||||
goto :eof
|
||||
|
||||
:usage
|
||||
@echo Usage: %0 ^<LANG^> ^<file.dxf^|file.json^|file.txt^>
|
||||
@echo LANG: Zielsprache (CS, EN, FR, IT, ES)
|
||||
@echo - .dxf/.dwg: Extrahiert und �bersetzt Texte zur angegebenen Sprache
|
||||
@echo - .json: Re-�bersetzt vorhandene �bersetzungen mit aktueller LANG.cfg
|
||||
@echo - .txt: Re-�bersetzt TXT-Datei (translations/untranslated) mit aktueller LANG.cfg
|
||||
@echo.
|
||||
@echo Beispiele:
|
||||
@echo %0 CS myfile.dxf
|
||||
@echo %0 EN translations.json
|
||||
@echo %0 CS translations_texts.txt
|
||||
exit /B 1
|
||||
goto :eof
|
||||
@@ -0,0 +1,6 @@
|
||||
@echo off
|
||||
REM Wrapper f r Tschechisch- bersetzungen
|
||||
REM Ruft tr2dxf.bat mit CS als Sprachparameter auf
|
||||
|
||||
call "%~dp0setenv.bat"
|
||||
call "%PROJECT_BIN%\tr2dxf.bat" CS %1
|
||||
@@ -0,0 +1,6 @@
|
||||
@echo off
|
||||
REM Wrapper für Englisch-Übersetzungen
|
||||
REM Ruft tr2dxf.bat mit EN als Sprachparameter auf
|
||||
|
||||
call "%~dp0setenv.bat"
|
||||
call "%PROJECT_BIN%\tr2dxf.bat" EN %1
|
||||
@@ -0,0 +1,6 @@
|
||||
@echo off
|
||||
REM Wrapper für Spanisch-Übersetzungen
|
||||
REM Ruft tr2dxf.bat mit ES als Sprachparameter auf
|
||||
|
||||
call "%~dp0setenv.bat"
|
||||
call "%PROJECT_BIN%\tr2dxf.bat" ES %1
|
||||
@@ -0,0 +1,6 @@
|
||||
@echo off
|
||||
REM Wrapper für Französisch-Übersetzungen
|
||||
REM Ruft tr2dxf.bat mit FR als Sprachparameter auf
|
||||
|
||||
call "%~dp0setenv.bat"
|
||||
call "%PROJECT_BIN%\tr2dxf.bat" FR %1
|
||||
@@ -0,0 +1,6 @@
|
||||
@echo off
|
||||
REM Wrapper für Italienisch-Übersetzungen
|
||||
REM Ruft tr2dxf.bat mit IT als Sprachparameter auf
|
||||
|
||||
call "%~dp0setenv.bat"
|
||||
call "%PROJECT_BIN%\tr2dxf.bat" IT %1
|
||||
@@ -0,0 +1,46 @@
|
||||
@echo off
|
||||
|
||||
if [%1]==[] goto usage
|
||||
for %%i in ("%~1") do (
|
||||
set "FILENAME=%%~ni"
|
||||
set "EXT=%%~xi"
|
||||
set "DIR=%%~dpi"
|
||||
)
|
||||
call C:\kabellaengen\bin\setenv.bat
|
||||
|
||||
REM echo Dateiname ohne Erweiterung: %FILENAME%
|
||||
REM echo Erweiterung: %EXT%
|
||||
REM echo Verzeichnis: %DIR%
|
||||
REM
|
||||
REM Namen der Ergebnisdateien
|
||||
set RESULT_JSON=%FILENAME%_texts.json
|
||||
|
||||
if exist "%~dp0_setenv.bat" (
|
||||
echo Lade lokale Umgebungseinstellungen aus _setenv.bat...
|
||||
call "%~dp0_setenv.bat"
|
||||
)
|
||||
REM Zielverzeichnis
|
||||
set TARGET_DIR=%PROJECT_WORK%
|
||||
mkdir "%TARGET_DIR%"
|
||||
|
||||
echo.
|
||||
echo === Extracting TEXT, MTEXT and symbols, translating to CS ===
|
||||
call translate.bat --filename %1 --extract -t json,text --outname %RESULT_JSON%
|
||||
if not exist "%PROJECT_WORK%\%RESULT_JSON%
|
||||
" (
|
||||
@echo == failed: extracting texts
|
||||
pause
|
||||
goto :eof
|
||||
)
|
||||
echo.
|
||||
echo === Translation file created: %PROJECT_WORK%\%RESULT_JSON% ===
|
||||
pause
|
||||
goto :eof
|
||||
|
||||
|
||||
:usage
|
||||
@echo Usage: %0 ^<dxfinWorkOrdner.dxf^>
|
||||
exit /B 1
|
||||
goto :eof
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
@echo off
|
||||
CALL manage_interpreter.bat activate
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to activate Python environment
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
pushd "%PROJECT%"
|
||||
|
||||
"%VIRTUAL_ENV%\Scripts\python.exe" -m lib.translate %*
|
||||
set PYTHON_EXIT=%ERRORLEVEL%
|
||||
|
||||
popd
|
||||
CALL manage_interpreter.bat deactivate
|
||||
exit /b %PYTHON_EXIT%
|
||||
@@ -0,0 +1,79 @@
|
||||
# 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
|
||||
MB
|
||||
QM
|
||||
BG
|
||||
BP
|
||||
BX
|
||||
PO
|
||||
SF
|
||||
PF
|
||||
GF
|
||||
|
||||
|
||||
# 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
|
||||
UH
|
||||
UC
|
||||
UZ
|
||||
DI
|
||||
DQ
|
||||
QA
|
||||
|
||||
|
||||
# Muster für die Erkennung von Schaltschränken (z.B. A01+UH00, A02+UC001, A03+UC0001)
|
||||
# Patterns for the recognition of Control-Cabinets (e.g. A01+UH00, A02+UC001, A03+UC0001)
|
||||
[Cabinet-Pattern]
|
||||
A\d\d\+(UH0\d)
|
||||
A\d\d\+(UC\d\d\d)
|
||||
\+(UC\d\d\d\d)
|
||||
\+(UH\d\d)
|
||||
A\d\+(UH0\d)
|
||||
A\d\+(UZ\d\d\d\d)
|
||||
A\d\d\+(UZ\d\d\d\d)
|
||||
|
||||
# Muster für die Erkennung von Tunneln (z.B. Tunnel1, Tunnel_2, Tunnel-3)
|
||||
# Patterns for the recognition of Tunnels (e.g. Tunnel1, Tunnel_2, Tunnel-3)
|
||||
[Tunnel-Pattern]
|
||||
Tunnel\d+
|
||||
Tunnel_\d+
|
||||
Tunnel-\d+
|
||||
TUNNEL\d+
|
||||
|
||||
|
||||
# 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 = Cable-Section[, Section2, ...]
|
||||
MA = MA
|
||||
MB-929012603 = WD_Q-929012603
|
||||
QM = WD_Q
|
||||
BG = WD_I
|
||||
BG-829422026 = WD_I-829422026
|
||||
BG-720002003 = WD_I-720002003
|
||||
BG-822035037 = WD_I-822035037
|
||||
BG-200000375 = WD_I-200000375
|
||||
BG-790000213 = WD_I-790000213
|
||||
BG-200000525 = WD_I-200000525
|
||||
BG-400101729 = WD_I-400101729
|
||||
BG-827072102 = WD_I-827072102
|
||||
BX = WF_BX, WD_I
|
||||
PO = WD_PO
|
||||
BP = WD_I
|
||||
SF = WD_I
|
||||
PF = WD_Q
|
||||
GF = WF_GF
|
||||
|
||||
|
||||
# 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
|
||||
BX = 4
|
||||
@@ -1,32 +1,138 @@
|
||||
# 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
|
||||
PRITSCHE_100-60-SCHRAFF
|
||||
PRITSCHE_200-60
|
||||
0-0_ILS_PRITSCHE_200--60_storage\ Level\ 1
|
||||
0-0_ILS_PRITSCHE_200--60_storage\ Level\ 2
|
||||
0-0_ILS_PRITSCHE_200--60_Workstation
|
||||
PRITSCHE_200-60_ILS
|
||||
PRITSCHE_200-60_OMNIFLO
|
||||
0-0_ILS_PRITSCHE_200-60_storage_Level1
|
||||
0-0_ILS_PRITSCHE_200-60_storage_Level2
|
||||
0-0_ILS_PRITSCHE_200-60_Workstation
|
||||
0-0_ILS_Pritsche_200-60_AMR
|
||||
0-0_ILS_PRITSCHE_200-60_Highway
|
||||
0-0_ILS_Pritsche_200-60_Inbound
|
||||
0-0_Omniflo_Pritsche_200-60_Workstation-Outbound
|
||||
0-0_Omniflo_Pritsche_200-60_outbound
|
||||
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
|
||||
0-0_ILS_Busverteiler-Kennzeichnung
|
||||
0-0_ILS_UNTERVERTEILER
|
||||
0-0_ILS_Unterverteiler
|
||||
0-0_Omniflo_UNTERVERTEILER
|
||||
0-0_Omniflo_Unterverteiler
|
||||
UNTERVERTEILER
|
||||
0-0_Omniflo_Busverteiler-Kennzeichnung
|
||||
Schaltschrank-ILS
|
||||
ILS_Schaltschrank
|
||||
ILS_Busmodul
|
||||
Omniflo_Schaltschrank
|
||||
|
||||
|
||||
# Layernamen der Tunnel
|
||||
# Layernames of Tunnels
|
||||
[GetPos-Layer_Tunnel]
|
||||
Busverteiler-Kennzeichnung
|
||||
0-0_Tunnel
|
||||
Omniflo_Tunnel
|
||||
ILS_Tunnel
|
||||
|
||||
|
||||
|
||||
# Layernamen des Equipments (Sensoren, Motoren, etc.)
|
||||
# Layernames of Equipment (Sensors, Motors, etc.)
|
||||
[GetPos-Layer_Equipment]
|
||||
0
|
||||
REALE_POSITION_IO
|
||||
0-0-ILS_Eingang
|
||||
0-0_ILS_EINGANG
|
||||
0-0_ILS_AUSGANG
|
||||
0-0_ILS_MOTOR
|
||||
ILS_Eingang
|
||||
ILS_Eingang-F
|
||||
ILS_BT-Eingang
|
||||
ILS_BT-Eingang-F
|
||||
ILS_BT-Kennzeichnung
|
||||
ILS_Schaltschrank
|
||||
ILS_Schaltschrank-Eingang
|
||||
ILS_Schaltschrank-Eingang-F
|
||||
ILS_Ausgang
|
||||
ILS_BT-Ausgang
|
||||
ILS_BT-Ausgang-F
|
||||
ILS_Schaltschrank-Ausgang
|
||||
ILS_Schaltschrank-Ausgang-F
|
||||
ILS_Motor
|
||||
ILS_Scanner
|
||||
ILS_A-Gruppe
|
||||
ILS_Encoder-800
|
||||
0-0-Omniflo_EINGANG
|
||||
0-0-Omniflo_AUSGANG
|
||||
0-0-Omniflo_MOTOR
|
||||
0-0-Omniflo-MOTOR
|
||||
0-0_Omniflo_MOTOR
|
||||
0-0_A-GRUPPE
|
||||
MOTOR
|
||||
0-0_ILS_POT Pritsche
|
||||
0-0_ILS_POT-DP
|
||||
0-0_ILS_POT-MA
|
||||
0-0_ILS_POT-RA
|
||||
0-0_ILS_A-GRUPPE
|
||||
0-0_Omniflo_POT Pritsche
|
||||
0-0_Omniflo_POT-CT
|
||||
0-0_Omniflo_A-GRUPPE
|
||||
0-0_Omniflo_POT-DP
|
||||
0-0_Omniflo_POT-MA
|
||||
0-0_Omniflo_POT-RA
|
||||
0-0_Omniflo_AM_POT_FS
|
||||
0-0_Omniflo_AM_POT_Pritsche
|
||||
POT-Erdung
|
||||
Omniflo_POT-Erdung
|
||||
Omniflo_Tunnel
|
||||
ILS_POT-Erdung
|
||||
ILS_Tunnel
|
||||
Omniflo_Schaltschrank
|
||||
Omniflo_Schaltschrank-Eingang
|
||||
Omniflo_Schaltschrank-Ausgang
|
||||
Omniflo_Schaltschrank-Eingang-F
|
||||
Omniflo_Schaltschrank-Ausgang-F
|
||||
Omniflo_Ausgang
|
||||
Omniflo_Eingang
|
||||
Omniflo_Motor
|
||||
Omniflo_BT-Eingang
|
||||
Omniflo_BT-Ausgang
|
||||
Omniflo_BT-Eingang_F
|
||||
Omniflo_BT-Kennzeichnung
|
||||
Omniflo_Scanner
|
||||
Omniflo_Busmodul
|
||||
Flex_Ausgang
|
||||
Flex_Eingang
|
||||
Flex_BT-Ausgang
|
||||
Flex_BT-Eingang
|
||||
Flex_BT-Eingang-F
|
||||
Flex_BT-Kennzeichnung
|
||||
Flex_Encoder-800
|
||||
Flex_Motor
|
||||
Flex_Scanner
|
||||
Flex_Schaltschrank
|
||||
Flex_Schaltschrank-Ausgang
|
||||
Flex_Schaltschrank-Ausgang-F
|
||||
Flex_Schaltschrank-Eingang
|
||||
Flex_Schaltschrank-Eingang-F
|
||||
Flex_Tunnel
|
||||
Flex_POT-Erdung
|
||||
|
||||
|
||||
|
||||
|
||||
# Maße des zur genauen Bestimmung der Mitte
|
||||
@@ -35,16 +141,25 @@ 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
|
||||
[Racks]
|
||||
SnapTolerances=200.
|
||||
|
||||
# bei den Sensoren
|
||||
# Geometrische Toleranz bei der Verbindung zweier Racks zueinander
|
||||
# Geometric tolerance for the connection (Snapping) of two adjacent racks
|
||||
[Racks]
|
||||
SnapTolerances=200.
|
||||
# Maximale erlaubte Höhendifferenz zwischen allen Racks (in mm) - Warnung wenn überschritten
|
||||
# Maximum allowed height difference between all racks (in mm) - warning if exceeded
|
||||
MaximalTotalHeightDifferences=2000.
|
||||
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
[Sivasnummern]
|
||||
200000248 = Lichttaster LP+SP als Staumelder
|
||||
200000215 = Camera DM280 m. Halter für Trolley Id.(AP110) - BG
|
||||
610554001 = Sensorhalter für WT18-3P420 oder -BG
|
||||
610554002 = CPC Sensorhalter mit Reflextaster P1NH601 -BG
|
||||
720002003 = Sensor Induk. M18x1, SA=12mm N-BÜ/NO, Kabel-150mm
|
||||
722001300 = Verb.-Leitung M12 St-0°/ M8 Bu-0° PUR UL/CSA 1m
|
||||
722001301 = Verb.-Leitung M12 St-0°/ M8 Bu-0° PUR UL/CSA 2m
|
||||
722001302 = Verb.-Leitung M12 St-0°/ M8 Bu-0° PUR UL/CSA 3m
|
||||
722001303 = Verb.-Leitung M12 St-0°/ M8 Bu-0° PUR UL/CSA 5m
|
||||
722001304 = Verb.-Leitung M12 St-0°/ M8 Bu-0° PUR UL/CSA 10m
|
||||
722001305 = Verb.-Leitung M12 St-0°/ M8 Bu-0° PUR UL/CSA 15m
|
||||
722001306 = Verb.-Leitung M12 St-0°/ M8 Bu-0° PUR UL/CSA 20m
|
||||
722001307 = Verb.-Leitung M12 St-0°/ M8 Bu-0° PUR UL/CSA 25m
|
||||
722001308 = Verb.-Leitung M12 St-0°/ M8 Bu-0° PUR UL/CSA 2,5m
|
||||
722001309 = Verb.-Leitung M12 St-0°/ M8 Bu-0° PUR UL/CSA 30m
|
||||
722001310 = Verb.-Leitung M12 St-0°/ M8 Bu-0° PUR UL/CSA 35m
|
||||
722001311 = Verb.-Leitung M12 St-0°/ M8 Bu-0° PUR UL/CSA 40m
|
||||
722001312 = Verb.-Leitung M12 St-0°/ M8 Bu-0° PUR UL/CSA 50m
|
||||
722001330 = Verb.-Leitung M12 St-0°/ M12 Bu-90° PUR UL/CSA 1m
|
||||
722001331 = Verb.-Leitung M12 St-0°/ M12 Bu-90° PUR UL/CSA 2m
|
||||
722001332 = Verb.-Leitung M12 St-0°/ M12 Bu-90° PUR UL/CSA 3m
|
||||
722001333 = Verb.-Leitung M12 St-0°/ M12 Bu-90° PUR UL/CSA 5m
|
||||
722001334 = Verb.-Leitung M12 St-0°/ M12 Bu-90° PUR UL/CSA 10m
|
||||
722001335 = Verb.-Leitung M12 St-0°/ M12 Bu-90° PUR UL/CSA 15m
|
||||
722001336 = Verb.-Leitung M12 St-0°/ M12 Bu-90° PUR UL/CSA 20m
|
||||
722001337 = Verb.-Leitung M12 St-0°/ M12 Bu-90° PUR UL/CSA 25m
|
||||
722001338 = Verb.-Leitung M12 St-0°/ M12 Bu-90° PUR UL/CSA 2,5
|
||||
722001339 = Verb.-Leitung M12 St-0°/ M12 Bu-90° PUR UL/CSA 30m
|
||||
722001340 = Verb.-Leitung M12 St-0°/ M12 Bu-90° PUR UL/CSA 35m
|
||||
722001341 = Verb.-Leitung M12 St-0°/ M12 Bu-90° PUR UL/CSA 40m
|
||||
722001342 = Verb.-Leitung M12 St-0°/ M12 Bu-90° PUR UL/CSA 50m
|
||||
722001352 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 3m
|
||||
722001353 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 5m
|
||||
722001354 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 10m
|
||||
722001355 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 15m
|
||||
722001356 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 20m
|
||||
722001357 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 30m
|
||||
722001358 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 2,5m
|
||||
722001359 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 40m
|
||||
722001252 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 3m
|
||||
722001253 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 5m
|
||||
722001254 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 10m
|
||||
722001255 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 15m
|
||||
722001256 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 20m
|
||||
722001257 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 30m
|
||||
722001259 = Verb.-Leitung M12 St-0°/ M12 Bu-0° PUR UL/CSA 40m
|
||||
723000013 = ADERLEITUNG H07V-K 6MM² GELB/GRÜN (RING a`100m)
|
||||
725000001 = 12G1,0mm², Steuerleitung
|
||||
725000002 = 12G1,0mm², Steuerleitung
|
||||
725000003 = 12G1,5MM², STEUERLEITUNG
|
||||
725000004 = 14G1,0MM², STEUERLEITUNG
|
||||
725000005 = 18G1,0MM², STEUERLEITUNG
|
||||
725000006 = 18G1,5MM², STEUERLEITUNG
|
||||
725000007 = 14G1,5mm², Steuerleitung
|
||||
725000009 = 25G1,0MM², STEUERLEITUNG
|
||||
725000010 = 25G1,5MM², STEUERLEITUNG
|
||||
725000011 = 3G0,5 MM², STEUERLEITUNG
|
||||
725000012 = 3G1,0MM², Steuerleitung
|
||||
725000013 = 25G2,5MM², STEUERLEITUNG
|
||||
725000014 = 4G1,0MM², STEUERLEITUNG
|
||||
725000015 = 4G1,5mm², Steuerleitung
|
||||
725000016 = 5G1,5MM², STEUERLEITUNG
|
||||
725000017 = 7G1,0mm², Steuerleitung
|
||||
725000018 = 5G16MM², STEUERLEITUNG VDE 0293-308
|
||||
725000019 = 8G1MM², STEUERLEITUNG
|
||||
725000026 = 25G0,5MM², STEUERLEITUNG
|
||||
725000027 = 34G1,0mm², Steuerleitung
|
||||
725000028 = 5G6,0MM², STEUERLEITUNG
|
||||
725000031 = 3G0,75MM², STEUERLEITUNG
|
||||
725000035 = 5G1,0MM², STEUERLEITUNG
|
||||
725000036 = 5G1,0MM², STEUERLEITUNG, PURÖ JZ HF 5G1 HF
|
||||
725000037 = 10G1,0mm², Steuerleitung
|
||||
725000040 = 3G1,5MM², Steuerleitung
|
||||
725000041 = 7G1,5MM², STEUERLEITUNG
|
||||
725000044 = 3G4MM², STEUERLEITUNG
|
||||
725000045 = 3G2,5MM², STEUERLEITUNG
|
||||
725000046 = 4G2,5MM², STEUERLEITUNG
|
||||
725000047 = 5G2,5mm², Steuerleitung
|
||||
725000048 = 7G2,5MM², STEUERLEITUNG
|
||||
725000049 = 12G2,5MM², STEUERLEITUNG
|
||||
725000050 = 4G4,0MM², STEUERLEITUNG
|
||||
725000051 = 5G4,0MM², STEUERLEITUNG
|
||||
725000052 = 4G10,0MM², STEUERLEITUNG
|
||||
725000053 = 5G10,0MM², STEUERLEITUNG
|
||||
725000054 = 4G1,5MM² CY, STEUERLEITUNG GESCHIRMT
|
||||
725000055 = 4G0,5MM², STEUERLEITUNG
|
||||
725000056 = 4G6,0MM², STEUERLEITUNG
|
||||
725000057 = 12G4,0mm², Steuerleitung
|
||||
725000058 = 12G1,0MM² CY, STEUERLEITUNG GESCHIRMT
|
||||
725000060 = 7G4,0MM², STEUERLEITUNG
|
||||
725000061 = 7G1,0MM² CY, STEUERLEITUNG GESCHIRMT
|
||||
725000152 = 3G1 mm², Steuerleitung Halogenfrei
|
||||
725000154 = 5G1 mm², Steuerleitung Halogenfrei
|
||||
725000155 = 7G1 mm², Steuerleitung Halogenfrei
|
||||
725000156 = 8G1 mm², Steuerleitung Halogenfrei
|
||||
725000157 = 12G1mm², Steuerleitung Halogenfrei
|
||||
725000158 = 18G1 mm², Steuerleitung Halogenfrei
|
||||
725000159 = 25G1 mm², Steuerleitung Halogenfrei
|
||||
725000160 = 3G1,5 mm², Steuerleitung Halogenfrei
|
||||
725000161 = 4G1,5 mm², Steuerleitung Halogenfrei
|
||||
725000163 = 7G1,5 mm², Steuerleitung Halogenfrei
|
||||
725000164 = 12G1,5 mm², Steuerleitung Halogenfrei
|
||||
725000165 = 5G2,5 mm², Steuerleitung Halogenfrei
|
||||
725000166 = 7G2,5 mm², Steuerleitung Halogenfrei
|
||||
725000167 = 18G1,5mm², Steuerleitung Halogenfrei
|
||||
725000169 = 12G2,5 mm², Steuerleitung Halogenfrei
|
||||
725000170 = 5G4 mm², Steuerleitung Halogenfrei
|
||||
725000171 = 5G6 mm², Steuerleitung Halogenfrei
|
||||
725000172 = 5G10 mm², Steuerleitung Halogenfrei
|
||||
725000180 = 4G1,5 mm², Multiflex 512-Pur grau
|
||||
725000181 = 7G1,5 mm², Multiflex 512-Pur grau
|
||||
725000182 = 3G1,5 mm², Multiflex 512-Pur grau
|
||||
726001040 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 0,5m grün
|
||||
726001041 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 1,0m grün
|
||||
726001042 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 1,5m grün
|
||||
726001043 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 2,0m grün
|
||||
726001044 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 3,0m grün
|
||||
726001045 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 5,0m grün
|
||||
726001046 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 10m grün
|
||||
726001047 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 15m grün
|
||||
726001048 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 20m grün
|
||||
726001049 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 25m grün
|
||||
726001050 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 30m grün
|
||||
726001051 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 35m grün
|
||||
726001052 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 40m grün
|
||||
726001053 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 45m grün
|
||||
726001054 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 50m grün
|
||||
726001055 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 55m grün
|
||||
726001056 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 60m grün
|
||||
726001057 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 65m grün
|
||||
726001060 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 85m grün
|
||||
726001061 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 95m grün
|
||||
726001062 = Patchkabel Cat6A 4P26 S/FTP 2xRJ45 0,25m grün
|
||||
790902001 = E-Teile für SEW Motor ASE1/HAN10ES - BG
|
||||
827072013 = STATISCHE TROLLEYABFRAGE L=700 FÜR AP110
|
||||
827072111 = Traversenabfrage AP110 mit Lichttaster
|
||||
827072112 = Traversenabfrage ST kpl. mit Lichttaster
|
||||
827072113 = Traversenabfrage KF kpl. mit Lichttaster
|
||||
829422026 = INDUKT. SENSOR LP KPL.
|
||||
720002011 = Sensor Induk. M18 8mm bündig/PNP-NO/ST M12
|
||||
703001017 = HILFSCHALTER MIT ZUGFEDERANSCHLUSS F. 3RV2011
|
||||
790000057 = SIRIUS ACT Tableau 4 F "LM-GN+PDT-GE+LDT-BL+NA"
|
||||
790801501 = Busverteiler kpl. ET 200SP DI+DQ, Exact -BG
|
||||
790820400 = Unterverteiler 1 800x2100x400 -BG
|
||||
790821106 = SCHALTSCHRANK 2000X2100X400 (HGF) -BG
|
||||
790821103 = SCHALTSCHRANK 1200x2000x400 KPL.
|
||||
829434314 = PINABFRAGE LI MECHANISCH KPL.
|
||||
829534306 = Camera DM280 m. Halter (ILS) - BG
|
||||
829624040 = UMLENKFLANSCH-c 800 MIT INKEMENTALGEBER KPL.
|
||||
929012655 = DRUCKSCHALTER PM1-M3-G014
|
||||
200000375 = Halter mit Sensor für Abfrage VARIO Finger
|
||||
720000007 = Sensor induk. M8x1, NO/ST-M12x1 4.pol, L=66 mm
|
||||
829434306 = INKREMENTALGEBER 800 5V KPL.
|
||||
400101729 = Abfrage Kettenbruch FLEX mit Sensor M12
|
||||
829434300 = LICHTTASTER LP+SP ALS STAUMELDER, KPL.
|
||||
721002006 = Lichtleiterverstärke [Erweiterungseinheit]
|
||||
721002005 = Lichtleiterverstärker [Basiseinheit]
|
||||
721002008 = Lichtleiterkabel_M4 2St.
|
||||
700002021 = AX-KOMPAKT-SCHALTSCHRANK 600X760X210
|
||||
822035037 = ROLLENSCH. KPL. 1 NO FÜR KF
|
||||
822035100 = ROLLENSCH. KPL. 1NO F. AFS/ST
|
||||
822035102 = ROLLENSCH. KPL. 1NO FÜR AP
|
||||
827072102 = KLEIDERBÜGEL ABFRAGE KPL. MIT SENSOR AM CP
|
||||
827072105 = TROLLEY-V IDENTIFIKATION MIT SCANNER AUF AP 110
|
||||
827072110 = SCHLEPPSEGMENTABFRAGE BIDIREKTIONAL
|
||||
790002020 = SIRIUS ACT TABLEAU 2 FACH "LDT-GE+NA" KPL. (HALTER)
|
||||
790002021 = SIRIUS ACT TABLEAU 1 FACH "LDT-GN" KPL.
|
||||
790002022 = Bedientableau kpl. LDT GRÜN+8-STUFENSCHALTER
|
||||
790002023 = TABLEAU 6- FACH KPL. "NA+DT-WS+ LDT-BL+ DT-GN"
|
||||
790002024 = TABLEAU 1-F kpl. LDT BLAU
|
||||
790002026 = Bedientableau 1 F kpl "DT-grün"
|
||||
790002027 = Bedientableau 2 F -kpl. "LDT-GE+NA"
|
||||
790002029 = Bedientableau 6 F - kpl.(LM-GN+LM-YE+LM-RD+BLIND+2xSW)
|
||||
790002039 = Bedientableau 2 F -kpl. "LDT-KL+NA" KPL.
|
||||
790002040 = Bedientableau 3 F"LDT-BL+LDT-KL+NA" KPL.
|
||||
790002041 = Bedientableau 4 F kpl."LDT-BL+LDT-BL+LDT-KL+NA"
|
||||
790002045 = Bedientableau 4 F -kpl. "DT-GN+LDT-BL+DT-WS+NA"
|
||||
790002057 = Bedientableau 4 F -kpl. "LM-GN+PDT-GE+LDT-BL+NA"
|
||||
790002058 = Bedientableau 4 F -kpl. LM-GN+PDT-GE+LDT-BL+BLIND
|
||||
790002059 = Bedientableau 1 F -kpl. "DT-Weiss"
|
||||
790002061 = Bedientableau 4 F -kpl. "LM-GN+PDT-GE+LDT-BL+NA"
|
||||
790002064 = Bedientableau 6 F, Not-halt, Ldt-bl, Ldt gn,Blind,
|
||||
790002066 = Bedientableau 2 F -kpl. "PDT-GE+KN-RAST 1-0-2"
|
||||
929012603 = WEGEVENT.5/2 MONOSTABIL SY5120-5WAOU-C6F-Q
|
||||
200000436 = Camera DM280 m. Halter Gefälleprofil ILS
|
||||
200000478 = Vereinzeler KB-Behängung links
|
||||
790000213 = DB-Automatisierung für Doppelbügelerkennung kpl.
|
||||
|
||||
|
||||
|
||||
[Missing]
|
||||
|
||||
@@ -0,0 +1,615 @@
|
||||
{
|
||||
"_description": "Konfiguration für create_example.py zur Erzeugung von Test-DXF-Dateien",
|
||||
|
||||
"test_scenes": {
|
||||
"Nummerierung1": {
|
||||
"description": "Test-Szene für automatische Nummerierung von MA-Symbolen mit Renamer-Rahmen",
|
||||
"ma_groups": [
|
||||
{
|
||||
"name": "MA-1@@_top",
|
||||
"count": 3,
|
||||
"layout_type": "horizontal",
|
||||
"base_x": 1500,
|
||||
"base_y": 1300,
|
||||
"spacing": 1450
|
||||
},
|
||||
{
|
||||
"name": "MA-1@@_bottom",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 500,
|
||||
"base_y": 200,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "MA-2@@_bottom",
|
||||
"count": 3,
|
||||
"layout_type": "horizontal_offset",
|
||||
"base_x": 1850,
|
||||
"base_y": 400,
|
||||
"spacing": 1450
|
||||
}
|
||||
],
|
||||
"renaming_frames": [
|
||||
{
|
||||
"comment": "Rahmen 1: Rechts oben - umschließt 3x MA-1@@",
|
||||
"name": "MA-1@@",
|
||||
"kennzeichnung": "A01+UH00",
|
||||
"layer_name": "ILS_MOTOR",
|
||||
"direction": "LEFT_RIGHT",
|
||||
"x": 1400,
|
||||
"y": 1200,
|
||||
"width": 4000,
|
||||
"height": 680,
|
||||
"use_polyline": false
|
||||
},
|
||||
{
|
||||
"comment": "Rahmen 2: Links unten - umschließt 1x MA-1@@, schmaler Rahmen mit Polylinie",
|
||||
"name": "MA-1@@",
|
||||
"kennzeichnung": "A01+UH00",
|
||||
"layer_name": "ILS_MOTOR",
|
||||
"direction": "LEFT_RIGHT",
|
||||
"x": 400,
|
||||
"y": 75,
|
||||
"width": 1150,
|
||||
"height": 480,
|
||||
"use_polyline": true
|
||||
},
|
||||
{
|
||||
"comment": "Rahmen 3: Rechts unten - umschließt 3x MA-2@@, mit Extra-Höhe für vertikale Offsets",
|
||||
"name": "MA-2@@",
|
||||
"kennzeichnung": "A01+UH00",
|
||||
"layer_name": "ILS_MOTOR",
|
||||
"direction": "TOP_BOTTOM",
|
||||
"x": 1600,
|
||||
"y": 250,
|
||||
"width": 4000,
|
||||
"height": 680,
|
||||
"use_polyline": false
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"Nummerierung2": {
|
||||
"description": "Test-Szene mit zirkulärer Nummerierung des Layouts - 8 MA-1@@ Symbole entlang einer Polyline nummerieren",
|
||||
"ma_groups": [
|
||||
{
|
||||
"name": "MA-1@@_top_left",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 400,
|
||||
"base_y": 2800,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "MA-1@@_top_right",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 4800,
|
||||
"base_y": 2800,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "MA-1@@_middle_left",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 1200,
|
||||
"base_y": 1800,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "MA-1@@_middle_right",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 3400,
|
||||
"base_y": 1800,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "MA-1@@_bottom_center",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 2480,
|
||||
"base_y": 800,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "MA-1@@_right_top",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 6400,
|
||||
"base_y": 2400,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "MA-1@@_right_middle",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 6400,
|
||||
"base_y": 1400,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "MA-1@@_right_bottom",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 6080,
|
||||
"base_y": 800,
|
||||
"spacing": 0
|
||||
}
|
||||
],
|
||||
"renaming_frames": [
|
||||
{
|
||||
"comment": "Polyline-Pfad: Verbindet alle MA-1@@ in kreisförmiger Bewegung",
|
||||
"type": "polyline_path",
|
||||
"name": "MA-1@@",
|
||||
"kennzeichnung": "A01+UH00",
|
||||
"layer_name": "ILS_MOTOR",
|
||||
"direction": "POLYLINE_PATH",
|
||||
"path_points": [
|
||||
{"x": 400, "y": 2800},
|
||||
{"x": 4800, "y": 2800},
|
||||
{"x": 6500, "y": 2400},
|
||||
{"x": 6500, "y": 1400},
|
||||
{"x": 6080, "y": 800},
|
||||
{"x": 2480, "y": 800},
|
||||
{"x": 3500, "y": 1800},
|
||||
{"x": 1200, "y": 1800},
|
||||
{"x": 400, "y": 2800}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"BGMG": {
|
||||
"description": "Test-Szene mit drei Rechtecken für BG-1@@@ und BG-2@@@ Symbole mit mehreren Layern",
|
||||
"bg_groups": [
|
||||
{
|
||||
"name": "BG-1@@_frame1",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 700,
|
||||
"base_y": 700,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "BG-1@@_frame2_1",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 3500,
|
||||
"base_y": 2350,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "BG-1@@_frame2_2",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 4800,
|
||||
"base_y": 2400,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "BG-1@@_frame2_3",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 6100,
|
||||
"base_y": 2300,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "MB-1@@_frame2_1",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 3500,
|
||||
"base_y": 2800,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "MB-1@@_frame2_2",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 4800,
|
||||
"base_y": 2850,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "MB-1@@_frame2_3",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 6100,
|
||||
"base_y": 2750,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "BG-2@@_frame3_1",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 3700,
|
||||
"base_y": 700,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "BG-2@@_frame3_2",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 5000,
|
||||
"base_y": 700,
|
||||
"spacing": 0
|
||||
},
|
||||
{
|
||||
"name": "BG-2@@_frame3_3",
|
||||
"count": 1,
|
||||
"layout_type": "single",
|
||||
"base_x": 6300,
|
||||
"base_y": 700,
|
||||
"spacing": 0
|
||||
}
|
||||
],
|
||||
"renaming_frames": [
|
||||
{
|
||||
"comment": "Rahmen 1: Links unten - 1x BG-1@@@ (Polylinie) - Angepasst für left_bottom_corner",
|
||||
"name": "BG-1@@",
|
||||
"name2": "MB-1@@",
|
||||
"kennzeichnung": "",
|
||||
"layer_name1": "ILS_Eingang",
|
||||
"layer_name2": "ILS_Ausgang",
|
||||
"direction": "LEFT_RIGHT",
|
||||
"x": 600,
|
||||
"y": 500,
|
||||
"width": 1610,
|
||||
"height": 600,
|
||||
"use_polyline": true
|
||||
},
|
||||
{
|
||||
"comment": "Rahmen 2: Rechts oben - 3x BG-1@@@ + 3x MB-1@@@ (Polylinie) - Angepasst für left_bottom_corner",
|
||||
"name": "BG-1@@",
|
||||
"name2": "MB-1@@",
|
||||
"kennzeichnung": "",
|
||||
"layer_name1": "ILS_Eingang",
|
||||
"layer_name2": "ILS_Ausgang",
|
||||
"direction": "LEFT_RIGHT",
|
||||
"x": 3400,
|
||||
"y": 2100,
|
||||
"width": 4310,
|
||||
"height": 1150,
|
||||
"use_polyline": true
|
||||
},
|
||||
{
|
||||
"comment": "Rahmen 3: Rechts unten - 3x BG-2@@@ (normales Rechteck) - Angepasst für left_bottom_corner",
|
||||
"name": "BG-2@@",
|
||||
"name2": "MB-2@@",
|
||||
"kennzeichnung": "",
|
||||
"layer_name1": "ILS_Eingang",
|
||||
"layer_name2": "ILS_Ausgang",
|
||||
"direction": "LEFT_RIGHT",
|
||||
"x": 3600,
|
||||
"y": 500,
|
||||
"width": 4310,
|
||||
"height": 600,
|
||||
"use_polyline": false
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"BGMG-UndefSymbols": {
|
||||
"description": "Test-Szene wie BGMB, aber mit nur 2x BG-1@@ Symbolen, um Undefiniert-Symbole zu testen",
|
||||
"bg_groups": [
|
||||
{
|
||||
"name": "BG-1@@@_frame1",
|
||||
"count": 5,
|
||||
"layout_type": "horizontal",
|
||||
"base_x": 1000,
|
||||
"base_y": 1000,
|
||||
"spacing": 2000
|
||||
}
|
||||
],
|
||||
"renaming_frames": [
|
||||
{
|
||||
"comment": "Rahmen: 2x BG-1@@@ (Polylinie) - Angepasst für linke Seite",
|
||||
"name": "BG-1@@@",
|
||||
"kennzeichnung": "",
|
||||
"layer_name1": "ILS_Eingang",
|
||||
"direction": "LEFT_RIGHT",
|
||||
"x": 800,
|
||||
"y": 800,
|
||||
"width": 3210,
|
||||
"height": 600,
|
||||
"use_polyline": true
|
||||
},
|
||||
{
|
||||
"comment": "Rahmen: 2x BG-1@@@ (Polylinie) - Angepasst für rechte Seite",
|
||||
"name": "BG-1@@@",
|
||||
"kennzeichnung": "",
|
||||
"layer_name1": "ILS_Eingang",
|
||||
"direction": "LEFT_RIGHT",
|
||||
"x": 6500,
|
||||
"y": 800,
|
||||
"width": 3210,
|
||||
"height": 600,
|
||||
"use_polyline": true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"POT": {
|
||||
"description": "Test-Szene für POT-Erdungssymbole mit drei verschiedenen Typen (POT-RA30@@, POT-MA30@@, POT-UC30@@)",
|
||||
"pot_groups": [
|
||||
{
|
||||
"name": "POT-RA30@@_RA",
|
||||
"count": 3,
|
||||
"layout_type": "horizontal",
|
||||
"base_x": 1000,
|
||||
"base_y": 3000,
|
||||
"spacing": 2500
|
||||
},
|
||||
{
|
||||
"name": "POT-MA30@@_MA",
|
||||
"count": 3,
|
||||
"layout_type": "horizontal",
|
||||
"base_x": 1000,
|
||||
"base_y": 2000,
|
||||
"spacing": 2500
|
||||
},
|
||||
{
|
||||
"name": "POT-UC30@@_UC",
|
||||
"count": 3,
|
||||
"layout_type": "horizontal",
|
||||
"base_x": 1000,
|
||||
"base_y": 1000,
|
||||
"spacing": 2500
|
||||
}
|
||||
],
|
||||
"renaming_frames": [
|
||||
{
|
||||
"comment": "Rahmen für alle 9 POT-Symbole (3x POT-RA30@@, 3x POT-MA30@@, 3x POT-UC30@@)",
|
||||
"name": "POT-RA30@@",
|
||||
"name2": "POT-MA30@@",
|
||||
"name3": "POT-UC30@@",
|
||||
"kennzeichnung": "AH01+UC0101-x",
|
||||
"layer_name1": "ILS_POT-Erdung",
|
||||
"layer_name2": "ILS_POT-Erdung",
|
||||
"layer_name3": "ILS_POT-Erdung",
|
||||
"direction": "LEFT_RIGHT",
|
||||
"x": 800,
|
||||
"y": 800,
|
||||
"width": 7200,
|
||||
"height": 2800,
|
||||
"use_polyline": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"ma_defaults": {
|
||||
"_description": "Standard-Werte für MA-Symbole",
|
||||
"block_name": "io",
|
||||
"layer": "ILS_MOTOR",
|
||||
"attributes": {
|
||||
"SPS": "1",
|
||||
"IO": "MA0000",
|
||||
"VERW": "ILS-M03@@",
|
||||
"BEZEICHNUNG": "Motor MA0000",
|
||||
"ARTIKELNR": "790902001",
|
||||
"ARTIKELBEZEICHN": "E-Teile für SEW Motor ASE1-HAN10ES-BG",
|
||||
"KENNZEICHNUNG": "=A01+UH00",
|
||||
"REALE_POSITION": "x",
|
||||
"TEXT-D": "",
|
||||
"TEXT-E": "",
|
||||
"TEXT-ES": "",
|
||||
"TEXT-F": "",
|
||||
"TEXT-I": "",
|
||||
"ID": "",
|
||||
"REALE_POSITION": "x"
|
||||
},
|
||||
"dimensions": {
|
||||
"_comment": "Symbol-Dimensionen für Layout-Berechnung. Feste Werte basierend auf IO-Feld Analyse (6 Zeichen MA-1@@: 1210 × 381)",
|
||||
"width": 1210,
|
||||
"height": 381
|
||||
}
|
||||
},
|
||||
"pot_defaults": {
|
||||
"_description": "Standard-Werte für POT-Symbole. Basiert auf Analyse von ILS_POT-Erdung aus Nummerierung_IO.dxf",
|
||||
"block_name": "ILS_POT-Erdung",
|
||||
"layer": "ILS_POT-Erdung",
|
||||
"attributes": {
|
||||
"REALE_POSITION": "x",
|
||||
"KENNZEICHNUNG": "=A01+UH00-X01",
|
||||
"NAME": "POT-1@@@"
|
||||
},
|
||||
"dimensions": {
|
||||
"_comment": "Symbol-Dimensionen für POT-Erdung. Basiert auf Block-Analyse: 816 × 618",
|
||||
"width": 1400,
|
||||
"height": 300
|
||||
},
|
||||
"attrib_defs": [
|
||||
{
|
||||
"tag": "REALE_POSITION",
|
||||
"insert": [0.0, 200.0, 0.0],
|
||||
"height": 50.0,
|
||||
"default": "x",
|
||||
"layer": "ILS_POT-Erdung",
|
||||
"invisible": false
|
||||
},
|
||||
{
|
||||
"tag": "NAME",
|
||||
"insert": [50, 100, 0.0],
|
||||
"height": 128.0,
|
||||
"default": "POT-1@@@",
|
||||
"layer": "ILS_POT-Erdung",
|
||||
"invisible": false
|
||||
},
|
||||
{
|
||||
"tag": "KENNZEICHNUNG",
|
||||
"insert": [0.0, -150, 0.0],
|
||||
"height": 128.0,
|
||||
"default": "=A01+UH00-X01",
|
||||
"layer": "ILS_POT-Erdung",
|
||||
"invisible": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"bg_defaults": {
|
||||
"_description": "Standard-Werte für BG/MB-Symbole (Eingänge/Ausgänge). Basiert auf Analyse von BG3240 aus easy.dxf",
|
||||
"block_name": "io",
|
||||
"layer": "ILS_Eingang",
|
||||
"attributes": {
|
||||
"SPS": "1",
|
||||
"IO": "BG0000",
|
||||
"VERW": "Sensor",
|
||||
"BEZEICHNUNG": "",
|
||||
"ARTIKELNR": "",
|
||||
"ARTIKELBEZEICHN": "",
|
||||
"KENNZEICHNUNG": "=A01+UC0101",
|
||||
"TEXT-D": "",
|
||||
"TEXT-E": "",
|
||||
"TEXT-ES": "",
|
||||
"TEXT-F": "",
|
||||
"TEXT-I": "",
|
||||
"ID": "",
|
||||
"REALE_POSITION": "x"
|
||||
},
|
||||
"dimensions": {
|
||||
"_comment": "Symbol-Dimensionen für BG/MB-Symbole. 7 Zeichen (BG-1@@@): 1410 × 381",
|
||||
"width": 1410,
|
||||
"height": 381
|
||||
}
|
||||
},
|
||||
"mb_defaults": {
|
||||
"_description": "Standard-Werte für MB-Symbole (Ausgänge). Verwendet dieselbe Struktur wie BG, nur anderer Layer",
|
||||
"block_name": "io",
|
||||
"layer": "ILS_Ausgang",
|
||||
"attributes": {
|
||||
"SPS": "1",
|
||||
"IO": "MB0000",
|
||||
"VERW": "Aktor",
|
||||
"BEZEICHNUNG": "",
|
||||
"ARTIKELNR": "",
|
||||
"ARTIKELBEZEICHN": "",
|
||||
"KENNZEICHNUNG": "=A01+UC0101",
|
||||
"TEXT-D": "",
|
||||
"TEXT-E": "",
|
||||
"TEXT-ES": "",
|
||||
"TEXT-F": "",
|
||||
"TEXT-I": "",
|
||||
"ID": "",
|
||||
"REALE_POSITION": "x"
|
||||
},
|
||||
"dimensions": {
|
||||
"_comment": "Symbol-Dimensionen für MB-Symbole. 7 Zeichen (MB-1@@@): 1410 × 381",
|
||||
"width": 1410,
|
||||
"height": 381
|
||||
}
|
||||
},
|
||||
"general": {
|
||||
"_description": "Allgemeine Frame-Attribute und Einstellungen. Renamer Frame Struktur (zweistufig): Äußerer Block mit LWPOLYLINE (umschließender Rahmen), Innerer Block mit ATTDEF (NAME, KENNZEICHNUNG, LAYER_NAME, DIRECTION)",
|
||||
|
||||
"ma_frame": {
|
||||
"_description": "MA Frame-Typ Attribute (einfache Frames für MA, MG, etc.)",
|
||||
"layer": "ILS_RENAMER",
|
||||
"color": 1,
|
||||
"insert_point": "left_bottom_corner",
|
||||
"_insert_point_description": "Einfügepunkt für MA-Blöcke. Mögliche Werte: left_top_corner, left_bottom_corner, right_top_corner, right_bottom_corner, center, top_center, bottom_center",
|
||||
"attdef_positions": {
|
||||
"_description": "ATTDEF Positionen im inneren Block RENAMER_ATTRIB_MA",
|
||||
"NAME": {
|
||||
"x": 10,
|
||||
"y": -10,
|
||||
"height": 21.25
|
||||
},
|
||||
"KENNZEICHNUNG": {
|
||||
"x": 10,
|
||||
"y": -35,
|
||||
"height": 21.25
|
||||
},
|
||||
"LAYER_NAME": {
|
||||
"x": 10,
|
||||
"y": -60,
|
||||
"height": 21.25
|
||||
},
|
||||
"DIRECTION": {
|
||||
"x": 10,
|
||||
"y": -85,
|
||||
"height": 21.25
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"multi_frame": {
|
||||
"_description": "MULTI Frame-Typ Attribute (für BG/MG/POT mit mehreren Layern)",
|
||||
"layer": "ILS_RENAMER",
|
||||
"color": 1,
|
||||
"attdef_positions": {
|
||||
"_description": "ATTDEF Positionen im inneren Block RENAMER_ATTRIB_MULTI",
|
||||
"NAME1": {
|
||||
"x": 10,
|
||||
"y": -10,
|
||||
"height": 21.25
|
||||
},
|
||||
"NAME2": {
|
||||
"x": 10,
|
||||
"y": -45,
|
||||
"height": 21.25
|
||||
},
|
||||
"NAME3": {
|
||||
"x": 10,
|
||||
"y": -80,
|
||||
"height": 21.25
|
||||
},
|
||||
"KENNZEICHNUNG": {
|
||||
"x": 10,
|
||||
"y": -115,
|
||||
"height": 21.25
|
||||
},
|
||||
"LAYER_NAME1": {
|
||||
"x": 10,
|
||||
"y": -150,
|
||||
"height": 21.25
|
||||
},
|
||||
"LAYER_NAME2": {
|
||||
"x": 10,
|
||||
"y": -185,
|
||||
"height": 21.25
|
||||
},
|
||||
"LAYER_NAME3": {
|
||||
"x": 10,
|
||||
"y": -220,
|
||||
"height": 21.25
|
||||
},
|
||||
"DIRECTION": {
|
||||
"x": 10,
|
||||
"y": -255,
|
||||
"height": 21.25
|
||||
},
|
||||
"ID": {
|
||||
"x": 10,
|
||||
"y": -290,
|
||||
"height": 21.25
|
||||
}
|
||||
},
|
||||
"dimensions": {
|
||||
"_comment": "Symbol-Dimensionen für Multi-Layer Frames. Feste Werte basierend auf IO-Feld Analyse (7 Zeichen BG-1@@@: 1410 × 381)",
|
||||
"width": 1410,
|
||||
"height": 381
|
||||
}
|
||||
},
|
||||
|
||||
"textstyle": {
|
||||
"attrib_textstyle": "textstyle3",
|
||||
"attrib_color": 1
|
||||
},
|
||||
|
||||
"inner_block_position": {
|
||||
"_description": "Innerer Block Insert-Position (relativ zum äußeren Block)",
|
||||
"x": 10,
|
||||
"y_offset_from_top": 30
|
||||
},
|
||||
|
||||
"layout": {
|
||||
"_description": "Frame-Padding (Abstand zwischen Symbol und Rahmen), Symbol-Spacing (Abstand zwischen Symbolen in Gruppen)",
|
||||
"frame_padding": 100,
|
||||
"frame_padding_small": 50,
|
||||
"symbol_spacing_factor": 1.2,
|
||||
"horizontal_offset_y_offsets": [0, -50, 50]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
[Layers]
|
||||
ILS_RENAMER
|
||||
Omniflo_RENAMER
|
||||
|
||||
[Parameters]
|
||||
# Maximale Distanz (in DXF-Einheiten) eines Symbols zur Polylinie bei POLYLINE_PATH
|
||||
# Symbole die weiter entfernt sind, werden nicht zur Nummerierung berücksichtigt
|
||||
polyline_max_distance = 500.0
|
||||
@@ -0,0 +1,202 @@
|
||||
# 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
|
||||
2.5=722001308
|
||||
3.0=722001302
|
||||
5.0=722001303
|
||||
10.0=722001304
|
||||
15.0=722001305
|
||||
20.0=722001306
|
||||
25.0=722001307
|
||||
30.0=722001309
|
||||
35.0=722001310
|
||||
40.0=722001311
|
||||
50.0=722001312
|
||||
|
||||
# Kabel für Default Sensoren
|
||||
# Cables for default sensors
|
||||
[WD_I]
|
||||
1.0=722001330
|
||||
2.0=722001331
|
||||
2.5=722001338
|
||||
3.0=722001332
|
||||
5.0=722001333
|
||||
10.0=722001334
|
||||
15.0=722001335
|
||||
20.0=722001336
|
||||
25.0=722001337
|
||||
30.0=722001339
|
||||
35.0=722001340
|
||||
40.0=722001341
|
||||
50.0=722001342
|
||||
|
||||
# Kabel für Sensor 829422026
|
||||
# cables for sensor 829422026
|
||||
[WD_I-829422026]
|
||||
2.5=722001358
|
||||
3.0=722001352
|
||||
5.0=722001353
|
||||
10.0=722001354
|
||||
15.0=722001355
|
||||
20.0=722001356
|
||||
30.0=722001357
|
||||
40.0=722001359
|
||||
|
||||
[WD_I-822035037]
|
||||
100.0=725000012
|
||||
|
||||
# Kabel für Sensor 720002003
|
||||
# cables for sensor 720002003
|
||||
[WD_I-720002003]
|
||||
2.5=722001358
|
||||
3.0=722001352
|
||||
5.0=722001353
|
||||
10.0=722001354
|
||||
15.0=722001355
|
||||
20.0=722001356
|
||||
30.0=722001357
|
||||
40.0=722001359
|
||||
|
||||
# Kabel für Sensor 790000213
|
||||
# cables for sensor 790000213
|
||||
[WD_I-790000213]
|
||||
2.5=722001358
|
||||
3.0=722001352
|
||||
5.0=722001353
|
||||
10.0=722001354
|
||||
15.0=722001355
|
||||
20.0=722001356
|
||||
30.0=722001357
|
||||
40.0=722001359
|
||||
|
||||
# Kabel für Sensor 200000525
|
||||
# cables for sensor 200000525
|
||||
[WD_I-200000525]
|
||||
3.0=722001252
|
||||
5.0=722001253
|
||||
10.0=722001254
|
||||
15.0=722001255
|
||||
20.0=722001256
|
||||
30.0=722001257
|
||||
40.0=722001259
|
||||
|
||||
# Kabel für Sensor 400101729
|
||||
# cables for sensor 400101729
|
||||
[WD_I-400101729]
|
||||
3.0=722001252
|
||||
5.0=722001253
|
||||
10.0=722001254
|
||||
15.0=722001255
|
||||
20.0=722001256
|
||||
30.0=722001257
|
||||
40.0=722001259
|
||||
|
||||
# Kabel für Sensor 827072102
|
||||
# cables for sensor 827072102
|
||||
[WD_I-827072102]
|
||||
3.0=722001252
|
||||
5.0=722001253
|
||||
10.0=722001254
|
||||
15.0=722001255
|
||||
20.0=722001256
|
||||
30.0=722001257
|
||||
40.0=722001259
|
||||
|
||||
# Daten-Kabel für Scanner (Patchkabel gruen)
|
||||
# Data-cable for scanners (Patchcable green)
|
||||
[WF_BX]
|
||||
0.25=726001062
|
||||
0.5=726001040
|
||||
1.0=726001041
|
||||
1.5=726001042
|
||||
2.0=726001043
|
||||
3.0=726001044
|
||||
5.0=726001045
|
||||
10.0=726001046
|
||||
15.0=726001047
|
||||
20.0=726001048
|
||||
25.0=726001049
|
||||
30.0=726001050
|
||||
35.0=726001051
|
||||
40.0=726001052
|
||||
45.0=726001053
|
||||
50.0=726001054
|
||||
55.0=726001055
|
||||
60.0=726001056
|
||||
65.0=726001057
|
||||
85.0=726001060
|
||||
95.0=726001061
|
||||
|
||||
# Daten-Kabel für ENCODER (Patchkabel gruen)
|
||||
# Data-cable for encoder (Patchcable green)
|
||||
# ist identisch mit Scanner Kabel
|
||||
[WF_GF]
|
||||
0.25=726001062
|
||||
0.5=726001040
|
||||
1.0=726001041
|
||||
1.5=726001042
|
||||
2.0=726001043
|
||||
3.0=726001044
|
||||
5.0=726001045
|
||||
10.0=726001046
|
||||
15.0=726001047
|
||||
20.0=726001048
|
||||
25.0=726001049
|
||||
30.0=726001050
|
||||
35.0=726001051
|
||||
40.0=726001052
|
||||
45.0=726001053
|
||||
50.0=726001054
|
||||
55.0=726001055
|
||||
60.0=726001056
|
||||
65.0=726001057
|
||||
85.0=726001060
|
||||
95.0=726001061
|
||||
|
||||
[WD_PO]
|
||||
100.0=723000013
|
||||
|
||||
# Kabel für Sensor 200000375
|
||||
# cables for sensor 200000375
|
||||
[WD_I-200000375]
|
||||
1.0=722001330
|
||||
2.0=722001331
|
||||
2.5=722001338
|
||||
3.0=722001332
|
||||
5.0=722001333
|
||||
10.0=722001334
|
||||
15.0=722001335
|
||||
20.0=722001336
|
||||
25.0=722001337
|
||||
30.0=722001339
|
||||
35.0=722001340
|
||||
40.0=722001341
|
||||
50.0=722001342
|
||||
|
||||
# Kabel für Ventil 929012603
|
||||
# cables for valves 929012603
|
||||
[WD_Q-929012603]
|
||||
1.0=722001300
|
||||
2.0=722001301
|
||||
2.5=722001308
|
||||
3.0=722001302
|
||||
5.0=722001303
|
||||
10.0=722001304
|
||||
15.0=722001305
|
||||
20.0=722001306
|
||||
25.0=722001307
|
||||
30.0=722001309
|
||||
35.0=722001310
|
||||
40.0=722001311
|
||||
50.0=722001312
|
||||
@@ -0,0 +1,114 @@
|
||||
#Erweiterung von Nikolai Schwechten 09.12.2025
|
||||
#Änderungsstand 09.12.2025, 15:02h
|
||||
|
||||
|
||||
|
||||
|
||||
# Hier werden Muster definiert für Texte die NICHT in die Excel Datei geschrieben werden sollen
|
||||
[ignore_pattern_wildcard]
|
||||
# Wildcard-Muster für Texte
|
||||
# Ein Muster pro Zeile
|
||||
# Wildcards: * (mehrere Zeichen), ? (ein Zeichen)
|
||||
# Format: pattern_name = muster
|
||||
|
||||
# Häufige technische Abkürzungen und Codes
|
||||
#layer = LAYER=*
|
||||
#special = %%*
|
||||
|
||||
# Koordinaten und technische Angaben
|
||||
coord_x = X=*
|
||||
coord_y = Y=*
|
||||
coord_z = Z=*
|
||||
KR_code = KR-M*
|
||||
|
||||
|
||||
[ignore_pattern_regex]
|
||||
# Reguläre Ausdrücke für Texte die NICHT in die Excel Datei geschrieben werden sollen
|
||||
# Ein Ausdruck pro Zeile (Python regex Syntax)
|
||||
# Format: pattern_name = regex
|
||||
|
||||
# Dezimalzahl mit Punkt oder Komma
|
||||
#decimal_number = ^-?\d+([.,]\d+)?$
|
||||
#pos_decimal_number = ^\+?\d+([.,]\d+)?$
|
||||
# Prozentangaben
|
||||
#percent = ^-?\d+([.,]\d+)?\s*%$
|
||||
|
||||
# Angaben wie =A1 +AB12 oder =A2+UZ304
|
||||
|
||||
#Auskommentiert nach Problemen wie "Sicherung =A01+UC0110 gefallen"
|
||||
#anlagen_nr = ^=A\d\s*\+[A-Z]{2}\d+
|
||||
#anlagen_nr3 = ^=A\d\+UZ\d{3}
|
||||
|
||||
|
||||
# Zeichen von A bis F als einzelnes Zeichen
|
||||
#Auskommentiert nach Problemen
|
||||
#ein_zeichen = ^[A-F]$
|
||||
|
||||
#Auskommentiert nach Problemen
|
||||
# A.1 bold
|
||||
#single_letters = ^\\f.*;[A-Z]\.\d$
|
||||
#Auskommentiert nach Problemen
|
||||
#AX = ^[A]\d$
|
||||
#ILSCV = ^ILS-CV\\PM\d{4}$
|
||||
#B.1 = B.\d
|
||||
#C.1 = C.\d
|
||||
#WS_1.x = WS \d.\d
|
||||
# # Blöcke wie BLOCK 1.1.2
|
||||
# BLOCK_3 = ^BLOCK \d\.\d(\.\d)?$
|
||||
# BLOCK_2 = ^BLOCK \d\.\d$
|
||||
# BLOCK_1 = ^BLOCK \d\$
|
||||
|
||||
# Technische Angaben
|
||||
#h1875 = ^\\H1.875x
|
||||
#h1875ff = ^\\H1.875x;.*$
|
||||
#millimeter = ^\d+\s*mm$
|
||||
#m_numbers = ^M\d{3}$
|
||||
|
||||
# Koordinaten mit Pfeilen
|
||||
coord_arrows = ^\+\d{1,3}(?:[.,]\d{3})\s*(?:<<<|>>>)\s*\+\d{1,3}(?:[.,]\d{3})$
|
||||
coord_arrows_generell_ignorieren = <<<|>>>
|
||||
|
||||
#Folgende Auskommentiert da Probleme mit Bezeichnungen wie "Feedback Hauptschütze Aktiv +UC0110"
|
||||
#uc4 = ^\+UC\d{4}
|
||||
#ax_uc4 = ^=A\d\+UC\d{2,4}
|
||||
#ax_uz4 = ^=A\d\+UZ\d{2,4}
|
||||
#ax_uh4 = ^=A\d\+UH\d{2,4}
|
||||
#a0x_uz1= ^=A01\+UZ\d+
|
||||
#a0x_uc4 = ^=A0\d\+UC\d{2,4}
|
||||
#a0x_uz4 = ^=A\d\+UZ\d{2,4}
|
||||
#a0x_uh4 = ^=A\d\+UH\d{2,4}
|
||||
|
||||
#Auskommentiert nach Problemen
|
||||
#pxqc_patterns = ^\\pxqc; =A0[1-9]\+UC\d{2,4}$
|
||||
#pxqc_patterns2 = ^\\pxqc; =A1\+UC\d{2,4}$
|
||||
#pxqc_patterns3 = ^\\pxqc; =A1\+UH\d{2,4}$
|
||||
Belastung=Belastung \\P(.*?):\\P(\d+) kg \/ (\d+) N
|
||||
|
||||
ip_adress = ^.*;(\d{1,3}\.){3}\d{1,3}$
|
||||
|
||||
# TUNNEL Bezeichnungen wie \fArial TUNNEL12-3456
|
||||
tunnel = ^\\fArial.*TUNNEL\d+-\d{4}$
|
||||
|
||||
kw_A = ^\d+\s*KW\s*-\s*\d+\s*A$
|
||||
AUZ=\=A\d\d\+UZ\d\d\d\d$
|
||||
AUC=\=A\d\d\+UC\d\d\d\d$
|
||||
AUH=\=A\d\d\+UH\d\d$
|
||||
ILSCV=ILS-CV\\PM\d\d\d\d$
|
||||
|
||||
|
||||
[symbol_attribute]
|
||||
# Zuordnung von Sprachcodes zu Block-Attributnamen für Texte
|
||||
# Format: SPRACHCODE = TEXT-ATTRIBUTNAME
|
||||
# Diese Zuordnung wird verwendet um die richtigen Attribute aus DXF-Blöcken zu lesen/schreiben
|
||||
DE = TEXT-D
|
||||
EN = TEXT-E
|
||||
ES = TEXT-ES
|
||||
FR = TEXT-F
|
||||
CS = TEXT-CS
|
||||
|
||||
[symbol_layer]
|
||||
DE = 0-0_TEXT-D
|
||||
EN = 0-0_TEXT-E
|
||||
ES = 0-0_TEXT-ES
|
||||
FR = 0-0_TEXT-F
|
||||
CS = 0-0_TEXT-CS
|
||||
@@ -0,0 +1,197 @@
|
||||
# Anwenderdoku zum I/O Converter (ioconverter) <!-- omit in toc -->
|
||||
|
||||
- [Zweck des Programms](#zweck-des-programms)
|
||||
- [Schnellstart](#schnellstart)
|
||||
- [Verwendung per Drag \& Drop](#verwendung-per-drag--drop)
|
||||
- [Verwendung per Kommandozeile](#verwendung-per-kommandozeile)
|
||||
- [Pipeline und Programmablauf](#pipeline-und-programmablauf)
|
||||
- [Ausgabedateien](#ausgabedateien)
|
||||
- [EA-Liste (`*_EA.xlsx`)](#ea-liste-_eaxlsx)
|
||||
- [TIA-Portal-Export (`*_TIA.xlsx`)](#tia-portal-export-_tiaxlsx)
|
||||
- [WSCAD-Export (`*_WSCAD.xlsx`)](#wscad-export-_wscadxlsx)
|
||||
- [Konfiguration und Symbolerkennung](#konfiguration-und-symbolerkennung)
|
||||
- [Fehlerfälle und Fehlerbehandlung](#fehlerfälle-und-fehlerbehandlung)
|
||||
- [Allgemeine Fehler und Warnungen](#allgemeine-fehler-und-warnungen)
|
||||
- [Ausgabedateien bei Fehlern](#ausgabedateien-bei-fehlern)
|
||||
- [Empfohlene Vorgehensweise](#empfohlene-vorgehensweise)
|
||||
- [Erweiterte Optionen](#erweiterte-optionen)
|
||||
|
||||
## Zweck des Programms
|
||||
|
||||
Der **I/O Converter** (`ioconverter.bat`) dient der vereinfachten Ableitung von **Ein-/Ausgangslisten (EA-Listen)** sowie der **Eingabedaten für das Siemens TIA Portal** und **WSCAD** aus einer DXF-Layoutzeichnung.
|
||||
|
||||
Das Programm extrahiert alle relevanten Geräteinformationen (Sensoren, Aktoren, Schaltschrankelemente) aus dem Layout und erzeugt daraus formatierte Excel-Dateien, die direkt in die jeweiligen Zielsysteme importiert werden können. Das Routing und die Kabelberechnung entfallen dabei vollständig - es geht ausschließlich um die **Geräte- und IO-Daten**.
|
||||
|
||||
## Schnellstart
|
||||
|
||||
### Verwendung per Drag & Drop
|
||||
|
||||
Im Desktop-Ordner *Kabeltool* (erstellt via `bin\dropItem_create.bat`) befindet sich die Verknüpfung *io_converter*. Die zu verarbeitende **.dxf-Datei** einfach per **Drag & Drop** auf diese Verknüpfung ziehen.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Der Dateiname darf **keine Leerzeichen oder Sonderzeichen** enthalten.
|
||||
> Verwende z. B. `projekt_123.dxf` statt `mein projekt #1.dxf`.
|
||||
|
||||
### Verwendung per Kommandozeile
|
||||
|
||||
```bash
|
||||
bin\ioconverter.bat <meine_anlage.dxf>
|
||||
```
|
||||
|
||||
Die Ausgabe schreibt:
|
||||
|
||||
```text
|
||||
=== Fetching Positions ===
|
||||
...
|
||||
=== Creating Excel Files for TIA, WSCAD, .. ===
|
||||
Export 'EA' erfolgreich: ...\work\meine_anlage_EA.xlsx
|
||||
Export 'TIA' erfolgreich: ...\work\meine_anlage_TIA.xlsx
|
||||
Export 'WSCAD' erfolgreich: ...\work\meine_anlage_WSCAD.xlsx
|
||||
```
|
||||
|
||||
Die erzeugten Dateien werden automatisch in das Ergebnisverzeichnis (`PROJECT_IO_RESULTS`) verschoben.
|
||||
|
||||
## Pipeline und Programmablauf
|
||||
|
||||
Der I/O Converter arbeitet in zwei Schritten:
|
||||
|
||||
```text
|
||||
DXF-Datei
|
||||
1. getpositions.py --> Positionen und Attribute extrahieren --> *_positionsconv.json
|
||||
2. portalexport.py --> Excel-Export erzeugen --> *_EA.xlsx, *_TIA.xlsx, *_WSCAD.xlsx
|
||||
```
|
||||
|
||||
1. **Positionsextraktion** (`getpositions.py`): Liest die DXF-Datei ein und extrahiert alle Blöcke mit ihren Attributen (IO, SPS, KENNZEICHNUNG, BEZEICHNUNG, VERW, TEXT-D/E/ES/F, ARTINR). Das Ergebnis wird als `*_positionsconv.json` gespeichert.
|
||||
|
||||
2. **Excel-Export** (`portalexport.py`): Liest die JSON-Zwischendatei und erzeugt daraus die Excel-Dateien in den gewünschten Formaten. Die Daten werden dabei nach SPS-Nummer gruppiert - pro SPS entsteht ein eigener Satz Ausgabedateien (z.B. `anlage-SPS1_TIA.xlsx`, `anlage-SPS2_TIA.xlsx`).
|
||||
|
||||
## Ausgabedateien
|
||||
|
||||
Standardmäßig werden **drei Excel-Dateien** pro SPS erzeugt:
|
||||
|
||||
### EA-Liste (`*_EA.xlsx`)
|
||||
|
||||
Eine einfache Übersicht aller Ein- und Ausgänge. Die Datei enthält folgende Worksheets:
|
||||
|
||||
**Ein-, Ausgaenge**: Listet alle erkannten Eingänge und Ausgänge mit Name, Kommentar (Bezeichnung) und Bezug (Kennzeichnung) auf. Die Klassifizierung in Ein- oder Ausgang erfolgt automatisch anhand der Identifier aus dem Block (z.B. DI, FDI = Eingang; DQ, K, M = Ausgang).
|
||||
|
||||
**Duplikate / Errors**: Falls doppelte Namen oder fehlerhafte Einträge erkannt werden, werden diese in separaten Worksheets aufgeführt.
|
||||
|
||||
### TIA-Portal-Export (`*_TIA.xlsx`)
|
||||
|
||||
Im TIA-Portal-Importformat mit folgenden Worksheets:
|
||||
|
||||
**PLC Tags**: Enthält die Spalten `Name`, `Path`, `Data Type`, `Logical Address`, `Comment`, `Hmi Visible`, `Hmi Accessible`, `Hmi Writeable`, `Typeobject ID`, `Version ID`. Diese Datei kann direkt in das Siemens TIA Portal importiert werden.
|
||||
|
||||
**Constants**: Enthält Konstanten mit `Name`, `Path`, `Data Type`, `Value`, `Comment`.
|
||||
|
||||
### WSCAD-Export (`*_WSCAD.xlsx`)
|
||||
|
||||
Im WSCAD-Importformat mit den Spalten `Anschluss`, `Kommentar`, `Symboltext`, `Bezug`, `Sondertext 1-8`. Der Export enthält standardmäßig Bezugsinformationen. Mit der Option `--no_bezug` kann der Export ohne Bezüge erstellt werden.
|
||||
|
||||
Für Bauteile mit unvollständigen Anschlüssen werden fehlende Anschlüsse automatisch bis zur Standardanzahl (8 pro Bauteil) ergänzt.
|
||||
|
||||
## Konfiguration und Symbolerkennung
|
||||
|
||||
Der I/O Converter verwendet folgende Konfigurationsdateien aus `cfg/`:
|
||||
|
||||
| Datei | Relevanz für I/O Converter |
|
||||
|-----------------|---------------------------|
|
||||
| `allgemein.cfg` | Layernamen für Sensoren, Aktoren, Unterverteiler etc. - bestimmt, welche Blöcke aus der DXF-Datei extrahiert werden |
|
||||
| `BMK.cfg` | Betriebsmittelkennzeichnungen (`[Routing-Include]`, `[Routing-Ignore]`) - bestimmt, welche Gerätetypen berücksichtigt werden |
|
||||
|
||||
> [!NOTE]
|
||||
> Die Konfigurationsdateien `kabel.cfg` und `bezeichner.cfg` werden vom I/O Converter **nicht** benötigt, da keine Kabelberechnung stattfindet.
|
||||
|
||||
Die Erkennung der Symbole (Blöcke) in der DXF-Datei ist die gemeinsame Basis von I/O Converter und Kabelberechnung. Beide Programme nutzen `getpositions.py` mit denselben Regeln zur Symbolsuche:
|
||||
|
||||
- Welche **Layer** durchsucht werden, wird in `allgemein.cfg` unter `[GetPos-Layer_Equipment]`, `[GetPos-Layer_Distributors]` etc. festgelegt
|
||||
- Welche **Betriebsmittelkennzeichen** (BMK-Präfixe) berücksichtigt werden, regelt `BMK.cfg` unter `[Routing-Include]` und `[Routing-Ignore]`
|
||||
- Welche **Block-Attribute** erwartet werden (KENNZEICHNUNG, SPS, IO, ARTINR, etc.) und wie die Blöcke im Layout angelegt sein müssen
|
||||
|
||||
Eine ausführliche Beschreibung der Konfigurationsdateien sowie der Anforderungen an die Layouterstellung findet sich in der [Anwenderdokumentation zur Kabellängenermittlung](Anwenderdoku.md) in den Abschnitten "Anpassung des Verhaltens des Programms" und "Anwenderhinweise zur Layouterstellung".
|
||||
|
||||
## Fehlerfälle und Fehlerbehandlung
|
||||
|
||||
### Allgemeine Fehler und Warnungen
|
||||
|
||||
Der I/O Converter durchläuft dieselbe Positionsextraktion wie der Cable-Routing-Workflow. Es gelten daher die gleichen Fehler- und Warnungstypen aus `getpositions.py`. Die vollständige Fehlertabelle findet sich in der [Anwenderdoku](Anwenderdoku.md) bzw. [Kurzanleitung](Anwenderdoku_kurz.md) im Abschnitt "Fehlerfälle und Fehlerbehandlung".
|
||||
|
||||
Die für den I/O Converter relevantesten Fehler sind:
|
||||
|
||||
| Fehlertyp | Auswirkung |
|
||||
|-----------------|------------|
|
||||
| `double_ids` | **Abbruch** - Doppelte Geräte-IDs führen zum Programmabbruch. Die `*_errors.json` wird erzeugt, aber keine Excel-Dateien. |
|
||||
| `missing_attributes` | Betroffene Elemente fehlen in den Export-Dateien |
|
||||
| `mapping_warnings` (keine KENNZEICHNUNG) | Keine korrekte Zuordnung zu Unterverteilern möglich |
|
||||
| `missing_sps_prefix` | Gerät kann keiner SPS zugeordnet werden |
|
||||
|
||||
### Ausgabedateien bei Fehlern
|
||||
|
||||
- `*_errors.json` - enthält alle Fehler und Warnungen aus der Positionsextraktion
|
||||
- `*_positionsconv.json` - Zwischenergebnis mit extrahierten Positionen
|
||||
- `*_EA.xlsx`, `*_TIA.xlsx`, `*_WSCAD.xlsx` - werden auch bei Warnungen erzeugt, können aber unvollständig sein
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Bei `double_ids`-Fehlern bricht das Programm nach der Positionsextraktion ab. Es werden **keine** Excel-Dateien erzeugt. Beheben Sie zuerst die doppelten IDs im Layout.
|
||||
|
||||
### Empfohlene Vorgehensweise
|
||||
|
||||
1. Programm ausführen
|
||||
2. Falls `*_errors.json` erstellt wurde: Fehler prüfen und im Layout korrigieren
|
||||
3. Erneut ausführen bis keine Fehler mehr auftreten
|
||||
4. Export-Dateien an nachgelagerte Systeme (TIA Portal, WSCAD) übergeben
|
||||
|
||||
> [!TIP]
|
||||
> Beheben Sie alle Warnungen aus `*_errors.json`, bevor Sie die Export-Dateien an nachgelagerte Systeme übergeben, um Vollständigkeit sicherzustellen.
|
||||
|
||||
## Erweiterte Optionen
|
||||
|
||||
### Einzelne Exportformate erzeugen
|
||||
|
||||
Der `portalexport.py` kann auch direkt aufgerufen werden, um nur bestimmte Exportformate zu erzeugen:
|
||||
|
||||
```bash
|
||||
# Nur TIA-Export erzeugen
|
||||
bin\portalexport.bat --filename <positionsconv.json> --outname <basename> --mode TIA
|
||||
|
||||
# Nur WSCAD-Export ohne Bezüge
|
||||
bin\portalexport.bat --filename <positionsconv.json> --outname <basename> --mode WSCAD --no_bezug
|
||||
|
||||
# Nur EA-Liste
|
||||
bin\portalexport.bat --filename <positionsconv.json> --outname <basename> --mode EA
|
||||
```
|
||||
|
||||
### Spezialfall: Eingabe über Textdatei (ohne DXF)
|
||||
|
||||
Für den Fall, dass die IO-Daten **nicht aus einer DXF-Datei** stammen, sondern bereits in aufbereiteter Form vorliegen, kann `portalexport.py` auch direkt mit einer Textdatei als Eingabe arbeiten. Damit wird die gesamte DXF-Verarbeitung (`getpositions.py`) übersprungen.
|
||||
|
||||
**Anwendungsfälle:**
|
||||
|
||||
- IO-Listen aus einem **anderen System** (z.B. manuell gepflegte Excel-Listen, Datenbank-Exporte) sollen in das TIA- oder WSCAD-Format konvertiert werden
|
||||
- Daten aus der DXF-Extraktion sollen **vorab korrigiert oder ergänzt** werden, bevor der Excel-Export erfolgt
|
||||
- **Testen** des Exporters ohne eine DXF-Datei verarbeiten zu müssen
|
||||
|
||||
**Aufruf:**
|
||||
|
||||
```bash
|
||||
bin\portalexport.bat --input <eingabe.txt> --mode TIA
|
||||
```
|
||||
|
||||
**Format der Textdatei:** Die Datei muss pro Zeile einen Eintrag im folgenden CSV-Format mit einfachen Anführungszeichen enthalten:
|
||||
|
||||
```text
|
||||
'<IO>','<BEZEICHNUNG>','<VERW>','<KENNZEICHNUNG>','<TEXT-D>','<TEXT-E>','<TEXT-ES>','<TEXT-F>'
|
||||
```
|
||||
|
||||
**Beispiel:**
|
||||
|
||||
```text
|
||||
'DI01','Stausensor 1 (ILS-CV M0108)','Jam detector','=A01+UC0101-KF1DI1','','','',''
|
||||
'DQ04','Motor MA0062','CV-M0062_0,75','=A01+UH01-KF1DQ04','Motor MA0062','Motor MA0062','',''
|
||||
```
|
||||
|
||||
Die Felder entsprechen den Block-Attributen aus der DXF-Datei. Dieses Format wird auch intern von `portalexport.py` erzeugt, wenn es die JSON-Daten aus `getpositions.py` verarbeitet.
|
||||
|
||||
> [!NOTE]
|
||||
> Bei der Eingabe per Textdatei entfällt die Gruppierung nach SPS-Nummer - alle Einträge werden in einem Satz Ausgabedateien zusammengefasst. Ebenso werden keine `getpositions`-Fehler und -Warnungen in die Excel-Dateien geschrieben, da keine DXF-Validierung stattfindet.
|
||||
@@ -0,0 +1,460 @@
|
||||
# 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: *dxfdatei*\_cables.xlsx](#excel-datei-dxfdatei_cablesxlsx)
|
||||
- [Excel-Datei: *dxfdatei*\_BOM.xlsx](#excel-datei-dxfdatei_bomxlsx)
|
||||
- [Fehlerfälle und Fehlerbehandlung](#fehlerfälle-und-fehlerbehandlung)
|
||||
- [Übersicht](#übersicht)
|
||||
- [Programmablauf](#programmablauf)
|
||||
- [Fehler- und Warnungskategorien](#fehler--und-warnungskategorien)
|
||||
- [Fehlerausgabe](#fehlerausgabe)
|
||||
- [Allgemeine Fehler und Warnungen](#allgemeine-fehler-und-warnungen)
|
||||
- [Struktur der Error-JSON-Datei](#struktur-der-error-json-datei)
|
||||
- [Arbeiten mit Fehlerfällen](#arbeiten-mit-fehlerfällen)
|
||||
- [Beispiele aus Testdaten](#beispiele-aus-testdaten)
|
||||
- [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)
|
||||
- [BMK.cfg](#bmkcfg)
|
||||
- [kabel.cfg](#kabelcfg)
|
||||
- [bezeichner.cfg](#bezeichnercfg)
|
||||
- [Validierung der Konfigurationsdateien](#validierung-der-konfigurationsdateien)
|
||||
- [Anwenderhinweise zur Layouterstellung](#anwenderhinweise-zur-layouterstellung)
|
||||
- [Verwendung der Layer](#verwendung-der-layer)
|
||||
- [Zeichnen von Kabeltrassen](#zeichnen-von-kabeltrassen)
|
||||
- [Attribute der Blöcke (Bauteile)](#attribute-der-blöcke-bauteile)
|
||||
- [Positionierung von Bauteilen](#positionierung-von-bauteilen)
|
||||
|
||||
# Installation des Programmes und Schnellstart-Guide
|
||||
|
||||
## 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.
|
||||
|
||||
Danach muss auf dem Zielrechner (z.B. per Windows APP) Python 3.X installiert werden. Alternativ kann ein Python Interpreter von einem Netzlaufwerk verwendet werden. Der Pfad zu diesem Interpreter muss dann über eine *Umgebungsvariable* mit dem Namen **NETWORK_INTERPRETER_PATH** auf der Maschine gesetzt sein.
|
||||
Grundsätzlich wird eine lokale Installation eines Python Interpreters (von https://www.python.org/downloads/) empfohlen.
|
||||
|
||||
Zur Installation des Kabeltools muss in dem geclonten Ordner `kabellaengen\bin` die Datei `install.bat` **als Administrator** ausgeführt werden. Hierfür *Rechtsklick* auf die Datei und *als Administrator ausführen*. Es wird in der Folge ein Ordner auf dem Desktop des Computers mit dem namen *Kabeltool* erstellt. In diesem Ordner ist eine Verknüpfung *create_cables*.
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
Die Ausgabe schreibt:
|
||||
|
||||
```text
|
||||
=== Fetching Positions ===
|
||||
Given .dxf-file is ASCII-dxf. Proceeding to use iterative functions. Process may take longer.
|
||||
|
||||
Validating given configs: Checking for inconsistency.
|
||||
No Inconsistencies found. Continuing with routing process.
|
||||
|
||||
writing results to a json file ...
|
||||
done
|
||||
|
||||
=== Creating Graph for Routing ===
|
||||
writing results to a json file ...
|
||||
done
|
||||
|
||||
=== Writing Output Files ===
|
||||
Cable-Routes exported to new dxf-file
|
||||
Cable-Summary exported to Excel-file
|
||||
BOM exported to Excel-file
|
||||
|
||||
C:\10-Develop\kabellaengen\work\easy_BOM.xlsx
|
||||
C:\10-Develop\kabellaengen\work\easy_cables.dxf
|
||||
C:\10-Develop\kabellaengen\work\easy_cables.xlsx
|
||||
C:\10-Develop\kabellaengen\work\easy_positions.json
|
||||
C:\10-Develop\kabellaengen\work\easy_todraw.json
|
||||
5 Datei(en) verschoben.
|
||||
Drücken Sie eine beliebige Taste . . .
|
||||
```
|
||||
|
||||
Das Drücken einer beliebigen Taste beendet das Programm und die Ausgabe kann verwendet werden.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Der Dateiname darf **keine Leerzeichen oder Sonderzeichen** enthalten.
|
||||
> Verwende z. B. projekt_123.dxf statt mein projekt #1.dxf.
|
||||
|
||||
## 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 vier Dateien, wovon letztlich zwei für den Anwender bestimmt sind. In der nachfolgenden Liste steht der name *dxfdatei* stellvertretend für die eingegebene Datei des Benutzers.
|
||||
|
||||
| Dateiname | Details |
|
||||
|---------------------------|---------------------------------------------------------------------------------------------------|
|
||||
| `dxfdatei_cables.dxf` | `.dxf`-Datei, **mit Kabelwegen** (z. B. für Import ins Original-Layout als eigenes Layer) und gezeichneten Racks (ggf. in 3D) |
|
||||
| `dxfdatei_cables.xlsx` | **Excel-Datei** mit Kabellängen, Längenübersicht und Fehler-Übersicht |
|
||||
| `dxfdatei_BOM.xlsx` | **Excel-Datei** mit Gesamtstückliste und Unterverteiler-spezifisicher Stückliste |
|
||||
| `dxfdatei_positions` | **Zwischendatei** (nicht für Endnutzer bestimmt) |
|
||||
| `dxfdatei_todraw` | **Zwischendatei** (nicht für Endnutzer bestimmt) |
|
||||
|
||||
### .dxf-Datei: *dxfdatei*_cables.dxf
|
||||
|
||||
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. Desweiteren werden die von dem Programm erkannten Kabeltrassen eingezeichnet und nummeriert. Sofern diese im Ursprungslayout dreidimensional angelegt wurden, wird auch das in der Ausgabe berücksichtigt.
|
||||
|
||||
### Excel-Datei: *dxfdatei*_cables.xlsx
|
||||
|
||||
Die standardmäßig erstellte und abgelegte Ausgabedatei `dxfdatei_cables.xlsx` enthält im fehlerfreien Fall drei Worksheets:
|
||||
|
||||
**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 |
|
||||
|
||||
**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 |
|
||||
|
||||
**Rack-Lengths**:
|
||||
zeigt die Längen der einzelnen Kabeltrassen-Segmente anhand deren Nummerierung innerhalb der dxf Datei. Diese Ausgabe dient der Überprüfung der benötigten Gesamtlänge der Kabeltrassen.
|
||||
|
||||
| Rack-ID | Length (m) |
|
||||
|------------|------------|
|
||||
| Rack_1 | 6,5 |
|
||||
| Rack_2-1 | 3,5 |
|
||||
| Rack_2-2 | 15 |
|
||||
|
||||
#### Erweiterte Ausgabe im Fehlerfall: <!-- omit in toc -->
|
||||
|
||||
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
|
||||
- ERRORS-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.
|
||||
|
||||
### Excel-Datei: *dxfdatei*_BOM.xlsx
|
||||
|
||||
Diese Datei enthält eine vollständige **Stückliste (BOM)** aller im Layout erkannten Komponenten – also sowohl aller Sensoren/Aktoren als auch der Kabel, die zum Einsatz kommen. Die Datei besteht aus zwei Tabellenblättern:
|
||||
|
||||
#### 1. BOM (Gesamtstückliste): <!-- omit in toc -->
|
||||
Zeigt für jede verwendete Artikelnummer den Namen laut bezeichner.cfg, die Gesamtanzahl bzw. Gesamtlänge. Sensoren (bzw. andere Komponenten mit Artikelnr) werden über ihre Artikelnummer gezählt. Kabel werden – sofern Meterware (z.B. Steuerleitungen für Motoren) – über die summierte Länge dargestellt, andernfalls über Stückzahl.
|
||||
|
||||
| Art.-Number | Amount (pcs) | Length (m) | Name (SIVAS) |
|
||||
|-------------|--------------|------------|----------------------------------------|
|
||||
| 722001330 | 3 | | M12 Sensorleitung 1 m, gewinkelt |
|
||||
| 725000015 | | 24 | Steuerleitung MA, 4G1,5mm² |
|
||||
| 839220147 | 5 | | Reflexionslichttaster XYZ |
|
||||
|
||||
|
||||
#### 2. BOM by UV (Stückliste pro Unterverteiler): <!-- omit in toc -->
|
||||
|
||||
Dieses Worksheet gibt für jede Artikelnummer aus, **welchem Unterverteiler (UV)** sie zugeordnet ist und wie viele davon jeweils dorthin gehören. Kabelmeter werden wie im anderen Arbeitsblatt getrennt ausgewiesen.
|
||||
|
||||
| UV | Art.-Number | Amount (pcs) | Length (m) | Name (SIVAS) |
|
||||
|--------|-------------|--------------|------------|----------------------------------|
|
||||
| UH01 | 722001330 | 1 | | M12 Sensorleitung 1 m, gewinkelt |
|
||||
| UC01 | 722001330 | 2 | | M12 Sensorleitung 1 m, gewinkelt |
|
||||
| UC01 | 725000015 | | 12 | Steuerleitung MA, 4G1,5mm² |
|
||||
|
||||
Hinweis: Diese Ansicht ist besonders nützlich zur **vorbereitenden Bestellplanung pro UV**.
|
||||
|
||||
# Fehlerfälle und Fehlerbehandlung
|
||||
|
||||
## Übersicht
|
||||
|
||||
Das Programm führt während der Verarbeitung umfassende Validierungen durch und erkennt verschiedene Arten von Fehlern im Layout. Die Fehlerbehandlung unterscheidet sich je nach Anwendungsfall:
|
||||
|
||||
### Programmablauf
|
||||
|
||||
Das Kabeltool (`getexdraw.bat`) arbeitet in drei Schritten:
|
||||
|
||||
1. `getpositions.py` - Extrahiert Positionen und validiert Layout
|
||||
2. `routing.py` - Berechnet Kabelwege über Graph-Algorithmen
|
||||
3. `drawdxf.py` - Erzeugt DXF mit Kabelwegen und Excel-Listen
|
||||
- **Ausgabe**: `*_cables.dxf`, `*_cables.xlsx`, `*_BOM.xlsx`
|
||||
|
||||
### Fehler- und Warnungskategorien
|
||||
|
||||
Die Fehlerbehandlung unterscheidet zwischen zwei Kategorien:
|
||||
|
||||
- **Fehler (errors)**: Schwerwiegende Probleme, die die Korrektheit der Ausgabe beeinträchtigen oder zum Abbruch führen
|
||||
- **Warnungen (warnings)**: Hinweise auf potenzielle Probleme, das Programm kann aber fortfahren
|
||||
|
||||
### Fehlerausgabe
|
||||
|
||||
- Falls Fehler oder Warnungen auftreten, schreibt `getpositions.py` **automatisch** eine JSON-Datei `*_errors.json` in den `work`-Ordner
|
||||
- Zusätzliche Fehler werden in der Excel-Datei `*_cables.xlsx` als separate Worksheets ausgegeben (siehe [ERR-Worksheets](#erweiterte-ausgabe-im-fehlerfall))
|
||||
|
||||
Im Ordner [testdata/](testdata/) finden sich Beispiel-DXF-Dateien, die gezielt bestimmte Fehlerfälle demonstrieren (z.B. [easy_3tunnels_errors.json](testdata/easy_3tunnels_errors.json), [easy_tunnelerror1.json](testdata/easy_tunnelerror1.json)).
|
||||
|
||||
## Allgemeine Fehler und Warnungen
|
||||
|
||||
Die folgende Tabelle zeigt alle möglichen Fehler- und Warnungstypen, die von `getpositions.py` erkannt werden:
|
||||
|
||||
| Fehlertyp | Kategorie | Beschreibung | Ursache | Behebung |
|
||||
|-----------|-----------|--------------|---------|----------|
|
||||
| `double_ids` | Fehler | Mehrere Blöcke haben dieselbe ID (z.B. MA0062@1) | Doppelte Bauteile mit identischer Kennzeichnung und SPS-Präfix im Layout | IDs eindeutig vergeben oder doppelte Blöcke entfernen |
|
||||
| `missing_attributes` | Warnung | Block hat fehlende oder unvollständige Attribute | Block enthält z.B. nur A, B, C, ARTINR aber keine SPS-, IO- oder KENNZEICHNUNG-Attribute | Fehlende Attribute im DXF-Block ergänzen (z.B. SPS, KENNZEICHNUNG) |
|
||||
| `missing_distributors` | Fehler | Unterverteiler in KENNZEICHNUNG erwähnt aber nicht im Layout | Sensor verweist auf UV (z.B. UH01) in KENNZEICHNUNG, aber UV-Symbol fehlt im Layout | Unterverteiler-Block im Layout positionieren oder KENNZEICHNUNG korrigieren |
|
||||
| `missing_sensors` | Fehler | Sensor/Aktor nicht gefunden | Sensor wird in Mappings referenziert, aber Block fehlt oder hat ungültige Attribute | Sensor-Block im Layout ergänzen oder fehlerhafte Attribute korrigieren |
|
||||
| `missing_tunnel` | Fehler | Tunnel hat weniger als 2 Positionen | Tunnel-Eingang oder -Ausgang fehlt (TUNNEL-Block oder MTEXT mit Muster `TUNNEL<nr>-<länge>`) | Zweiten Tunnel-Eingang/Ausgang im Layout ergänzen |
|
||||
| `overdefined_tunnel` | Fehler | Tunnel hat mehr als 2 Positionen | Mehr als zwei TUNNEL-Blöcke mit demselben Namen (z.B. TUNNEL2 dreimal) | Überzählige Tunnel-Positionen entfernen |
|
||||
| `tunnel_missing_length` | Warnung | Tunnel-Block hat kein LAENGE-Attribut | LAENGE-Attribut fehlt in Tunnel-Block, Default-Länge (5m) wird verwendet | LAENGE-Attribut im Tunnel-Block ergänzen |
|
||||
| `mapping_warnings` → `keine KENNZEICHNUNG vorhanden` | Warnung | KENNZEICHNUNG-Attribut fehlt komplett | Block hat kein KENNZEICHNUNG-Attribut | KENNZEICHNUNG-Attribut im Format `=<Anlage>+<UV>-<Karte>` ergänzen |
|
||||
| `mapping_warnings` → `Ungültiger Pfad in Kennzeichnung` | Warnung | KENNZEICHNUNG hat falsches Format | Trennzeichen `+`, `-` oder `=` fehlen oder falsch positioniert | KENNZEICHNUNG-Format korrigieren (z.B. `=A01+UH01-KF1DQ04`) |
|
||||
| `missing_sps_prefix` | Fehler | SPS-Präfix fehlt für Block-ID | Beim Zusammenführen von Blöcken fehlt der SPS-Präfix | SPS-Attribut in Block ergänzen |
|
||||
|
||||
|
||||
Für eine genaue Übersicht siehe in der normalen Anwenderdokumentation.
|
||||
|
||||
|
||||
## Struktur der Error-JSON-Datei
|
||||
|
||||
Die `*_errors.json`-Datei ist wie folgt strukturiert:
|
||||
|
||||
```json
|
||||
{
|
||||
"errors": {
|
||||
"missing_distributors": ["UH02", "UC05"],
|
||||
"overdefined_tunnel": ["TUNNEL2"],
|
||||
...
|
||||
},
|
||||
"warnings": {
|
||||
"missing_attributes": {
|
||||
"BX0101": "Nur ein Block und/oder fehlende Attribute: dict_keys([...])"
|
||||
},
|
||||
"mapping_warnings": {
|
||||
"MA0099": "keine KENNZEICHNUNG vorhanden"
|
||||
},
|
||||
"tunnel_missing_length": {
|
||||
"TUNNEL1": "Tunnel 'TUNNEL1' hat keine LAENGE-Angabe. Verwende Default-Länge: 5m"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Jeder Fehlertyp enthält entweder:
|
||||
- Eine **Liste** von betroffenen IDs/Namen (z.B. `["UH02", "UC05"]`)
|
||||
- Ein **Dictionary** mit IDs als Keys und detaillierten Beschreibungen als Values
|
||||
|
||||
## Arbeiten mit Fehlerfällen
|
||||
|
||||
**Empfohlene Vorgehensweise:**
|
||||
|
||||
1. **Programm ausführen** – Das Programm läuft auch bei Fehlern durch und erstellt soweit möglich Ausgaben
|
||||
2. **Error-Datei prüfen** – Falls `*_errors.json` erstellt wurde, enthält sie alle erkannten Probleme
|
||||
3. **Fehler beheben** – Layout gemäß Tabelle oben korrigieren
|
||||
4. **Erneut ausführen** – Nach Korrektur sollte keine Error-Datei mehr erstellt werden
|
||||
|
||||
**Hinweis:** Die Error-Datei wird **nur dann** erstellt, wenn tatsächlich Fehler oder Warnungen erkannt wurden. Fehlt die Datei, ist die Verarbeitung fehlerfrei verlaufen.
|
||||
|
||||
## Beispiele aus Testdaten
|
||||
|
||||
Im Ordner [testdata/](testdata/) befinden sich mehrere Beispieldateien, die gezielt Fehlerfälle demonstrieren:
|
||||
|
||||
| DXF-Datei | Fehlertyp | Beschreibung |
|
||||
|-----------|-----------|--------------|
|
||||
| [easy_tunnelerror1.dwg](testdata/easy_tunnelerror1.dwg) | `overdefined_tunnel`, `missing_attributes` | TUNNEL2 hat 3 Positionen statt 2; Block BX0101 hat fehlende Attribute |
|
||||
| [easy_3tunnels.dxf](testdata/easy_3tunnels.dxf) | Diverse Tunnel-Fehler | Demonstriert verschiedene Tunnel-Konfigurationen |
|
||||
|
||||
Diese Testdateien können als Referenz dienen, um Fehler im eigenen Layout zu verstehen und zu beheben.
|
||||
|
||||
# Anpassung des Verhaltens des Programms:
|
||||
|
||||
## Verwendete Konfigurationsdateien
|
||||
|
||||
Zum aktuellen Zeitpunkt verwendet bzw. berücksichtigt das Programm **vier** 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.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> 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.**
|
||||
|
||||
| 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 |
|
||||
| `bezeichner.cfg`| Speicherung der Bezeichner zu den SIVAS-Nummern sowie automatische Pflege fehlender Artikelnummern |
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Änderungen an den .cfg-Dateien werden erst beim nächsten Programmlauf wirksam.
|
||||
> Stelle sicher, dass die Datei korrekt gespeichert wurde und keine doppelten Abschnitte enthält.**
|
||||
|
||||
## 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.
|
||||
|
||||
| Abschnitt | Beschreibung | Beispiel(e) |
|
||||
|---------------------------|------------------------------------------------------------|----------------------------------------------------|
|
||||
| `[GetPos-Layer_Racks]` | Layer mit Kabelpritschen (Racks) | PRITSCHE_200-60_OMNIFLO<br>0-0_ILS_Pritsche_200-60 |
|
||||
| `[GetPos-Layer_Distributors]` | Layer mit Unterverteilern | 0-0_ILS_UNTERVERTEILER<br>UNTERVERTEILER |
|
||||
| `[GetPos-Layer_Tunnel]` | Layer für Tunnel | Busverteiler-Kennzeichnung |
|
||||
| `[GetPos-Layer_Equipment]`| Layer mit Sensoren, Motoren, IOs etc. | 0-0_ILS_MOTOR<br>MOTOR<br>REALE_POSITION_IO |
|
||||
| `[GetPos-Geom-Sensor]` | Maße von Sensor-Markern zur Mittelpunktberechnung | Breite = 80<br>Höhe = 90 |
|
||||
| `[Racks]` | Snap-Toleranz zwischen benachbarten Racks | SnapTolerances = 200 |
|
||||
| `[Sensoren]` | Verbindungstoleranz Sensoren ↔ Racks | ConnectionTolerances = 3000 |
|
||||
|
||||
### BMK.cfg
|
||||
|
||||
Diese Datei steuert, **welche Betriebsmittelkennzeichen (BMK)** beim Routing berücksichtigt werden und welche **Kabeltypen** zugewiesen sind.
|
||||
|
||||
| Abschnitt | Beschreibung | Beispiel(e) |
|
||||
|----------------------|------------------------------------------------------|--------------------------------------------------|
|
||||
| `[Routing-Include]` | BMKs, die beim Routing berücksichtigt werden | MA = Motoren<br>QM = Ventile<br>BX = Scanner |
|
||||
| `[Routing-Ignore]` | BMKs, die ignoriert werden | FC = Frequenzumrichter<br>QA = Sicherungen |
|
||||
| `[Cable-Mapping]` | Zuordnung BMK → Kabelgruppe(n) (aus `kabel.cfg`) | MA → MA<br>MB → WD_Q<br>BX → WF_B, WD_I |
|
||||
| `[Length-Adjustments]`| Kabellängen-Korrektur (z. B. vorkonf. Sensorleitung) | BX → 4 m abziehen |
|
||||
|
||||
### kabel.cfg
|
||||
|
||||
Diese Datei enthält die **SIVAS-Nummern je Kabellänge und -typ** sowie einen Abschnitt für **spezifische Kabelgruppen**
|
||||
|
||||
| Abschnitt / Gruppe | Beschreibung | Beispiel(e) |
|
||||
|----------------------------|-----------------------------------------------|---------------------------------------------------|
|
||||
| `[WD_Q]`, `[WD_I]`, `[WF_B]` | Kabellängen je Gruppe + zugehörige SIVAS-Nr. | 1.0 m → 722001300<br>2.5 m → 722001338<br>5.0 m → 726001045 |
|
||||
| sensorspezifische Gruppen:<br>`[WD_I-829422026]`<br> `[WD_I-720002003]` | Kabellisten für bestimmte Artikelnummern |<br>5.0 m → 722001353<br>10.0 m → 722001354 |
|
||||
|
||||
|
||||
### bezeichner.cfg
|
||||
|
||||
Diese Datei enthält Bezeichner zu den verwendeten SIVAS-Artikelnummern. Sie beinhaltet sowohl die Bezeichner (laut SIVAS) für die Bauteil-Artikelnummern als auch für die Kabel. Die Datei wird im Laufe eines Routing-Prozesses bei Bedarf angepasst und mittels einer SIVAS-Datenbankabfage (bei bestehender VPN-Verbindung bzw. im lokalen Firmennetz am Standort) erweitert.
|
||||
|
||||
| Abschnitt | Beschreibung | Beispiel(e) |
|
||||
|-------------------|----------------------------------------------------------------|--------------------------------------------------|
|
||||
| `[Sivasnummern]` | Bekannte SIVAS-Nr. mit <br> zugehörigem Bezeichner | 725000015 → 4G1,5mm² Steuerleitung<br>722001300 → Verb.-Leitung M12 St/M8 Bu 1 m |
|
||||
| `[Missing]` | Fehlende Nummern, die im Layout vorkommen, aber unbenannt sind | Automatisch ergänzt bei VPN/SIVAS-Datenbankzugriff |
|
||||
|
||||
## Validierung der Konfigurationsdateien
|
||||
|
||||
Bevor das Routing beginnt, werden alle `.cfg`-Dateien automatisch auf **Plausibilität und Konsistenz** überprüft. Ziel ist es, fehlerhafte oder unvollständige Konfigurationen frühzeitig zu erkennen und entsprechende Warnungen auszugeben.
|
||||
|
||||
Diese Prüfung geschieht vollautomatisch im Hintergrund – der Anwender muss nichts weiter tun. Falls Probleme erkannt werden, werden diese in der Konsole (bzw. dem Terminal-Fenster) protokolliert. Die Verarbeitung wird trotzdem fortgesetzt, allerdings **können fehlerhafte Konfigurationen zu falschen Verkabelungen oder fehlenden Ausgaben führen**.
|
||||
|
||||
#### Prüfkriterien im Detail: <!-- omit in toc -->
|
||||
|
||||
1. **Vollständigkeit der Zuweisungen in `BMK.cfg`**
|
||||
- Jeder Prefix aus `[Routing-Include]` muss in `[Cable-Mapping]` enthalten sein.
|
||||
- Fehlt eine Zuordnung, wird ein Fehler gemeldet:
|
||||
`No Cable-Mapping for Prefix 'BX' within [Cable-Mapping]`
|
||||
|
||||
2. **Existenz der referenzierten Sektionen in `kabel.cfg`**
|
||||
- Jeder Eintrag in `[Cable-Mapping]` verweist auf eine oder mehrere Sektionen (z. B. `WD_Q`, `WF_B`), die in `kabel.cfg` existieren müssen.
|
||||
- Fehlt eine Sektion, wird gewarnt:
|
||||
`Cable-Section 'WF_B' from Cable-Mapping is not defined in kabel.cfg`
|
||||
|
||||
3. **Gültigkeit der Werte in `[Length-Adjustments]`**
|
||||
- Jeder Wert muss eine **nicht-negative Kommazahl (float ≥ 0.0)** sein.
|
||||
- Ungültige oder negative Einträge verursachen entsprechende Warnungen:
|
||||
`Invalid Value in Length-Adjustments for BX: 'abc' is not a valid float`
|
||||
|
||||
> [!NOTE]
|
||||
> Die Validierung dient als wichtige Schutzmaßnahme gegen fehlerhafte Eingaben oder veraltete Konfigurationsdateien. Es ist **empfohlen**, bei jeder Layoutanpassung oder Änderung von Komponenten auch die `.cfg`-Dateien zu prüfen und ggf. zu aktualisieren, um die Ricthigkeit der Ergebnisse sicherzustellen.
|
||||
|
||||
# Anwenderhinweise zur Layouterstellung
|
||||
|
||||
Im nachfolgenden Abschnitt sind die **wichtigsten** Punkte zur Erstellung der Layoutzeichnungen aufgeführt. Die Beachtung dieser Hinweise stellt sicher, dass die automatische Auswertung durch das Programm fehlerfrei und zuverlässig erfolgen kann.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Dieser Abschnitt ist durch die Fachabteilung regelmäßig zu pflegen und analog zu Konfigurationsdateien stets aktuell zu halten.**
|
||||
|
||||
## Verwendung der Layer
|
||||
|
||||
- **Erfasst werden ausschließlich Elemente auf Layern**, die in der Konfigurationsdatei (`cfg`) unter dem jeweiligen Abschnitt (`GetPos-Layer_...`) aufgeführt sind.
|
||||
- Nicht konfigurierte Layer oder falsch benannte Layer werden vollständig ignoriert.
|
||||
- Für jede Objektklasse (z. B. Racks, Sensoren, Unterverteiler) sollte ein eigener dedizierter Layer verwendet werden.
|
||||
- Layer-Namen dürfen **keine Sonderzeichen oder Leerzeichen** enthalten, und sollten **eindeutig** benannt sein.
|
||||
|
||||
## Zeichnen von Kabeltrassen
|
||||
|
||||
- **Verbindungspunkte von Racks sollten präzise aneinander gezeichnet werden**, idealerweise mit Fangmodi (Snapping) im CAD.
|
||||
- Das Programm erkennt und verbindet nahe beieinanderliegende Racks automatisch, jedoch nur mit begrenzter Toleranz.
|
||||
- Eine saubere Planung der Trassengeometrie erleichtert die automatische Graphenerstellung erheblich.
|
||||
- **2D-Kabeltrassen (LWPOLYLINE)** sollten verwendet werden für Strecken in einer Ebene bzw. auf einer Höhe
|
||||
- **3D-Trassenführung** bei Höhendifferenzen (z.B entlang von Förderern) erfolgt in drei Schritten:
|
||||
1. Untere Ebene als `LWPOLYLINE` mit Z=0.
|
||||
2. Obere Ebene als `LWPOLYLINE` mit Z=Erhebung (über DXF-Attribut `Erhebung`).
|
||||
3. Verbindung über `3DPOLYLINE`, welche die Steigung darstellt.
|
||||
|
||||
## Attribute der Blöcke (Bauteile)
|
||||
|
||||
- **Pro Bauteil darf nur ein Block vorhanden sein.** Alle relevanten Informationen (z. B. Artikelnummer, Bezeichner, Position) müssen diesem einen Block als Attribute zugeordnet sein.
|
||||
- **Keine übereinanderliegenden Blöcke!**
|
||||
- In der Vergangenheit wurden häufig zwei Blöcke übereinandergelegt, um Kabel- und Sensorinformationen zu trennen. Dies ist künftig nicht mehr zulässig.
|
||||
- **Beispiel für frühere Aufteilung (nicht mehr erlaubt):**
|
||||
- *Rahmen innen* (Angaben zum Kabel):
|
||||
- A:
|
||||
- B: Kabel-ID
|
||||
- C: lange Nummer (?)
|
||||
- ArtiNr: Kabelartikelnummer
|
||||
- Beschr: Kabelname (SIVAS)
|
||||
- Menge, Position, Gruppe, Etikette, Auflöse, etc.
|
||||
- *Rahmen außen* (Angaben zum Bauteil selbst):
|
||||
- A:
|
||||
- B: Bauteil-Kurzbezeichnung
|
||||
- C: lange Nummer (?)
|
||||
- ArtiNr: Sensorartikelnummer
|
||||
- Beschr: Kurzbeschreibung
|
||||
- sowie gleiche Attribute wie oben.
|
||||
- *Text*
|
||||
- IO: Bauteil-Kurzbezeichnung
|
||||
- id
|
||||
- VERW
|
||||
- BEZEICHNUNG
|
||||
- TEXT-D, TEXT-E, TEXT-ES, TEXT-F
|
||||
- SPS
|
||||
- **In Zukunft**:
|
||||
- Ein einziger Block enthält alle Informationen des Bauteils.
|
||||
- Die Informationen zu den benötigten Kabeln werden **allein** vom Kabeltool bereitgestellt
|
||||
- Die konkrete Struktur der Attribute wird noch festgelegt (To Be Defined).
|
||||
- Ziel ist es, sowohl die Verarbeitung im System als auch die manuelle Pflege im Layout zu vereinfachen.
|
||||
|
||||
## Positionierung von Bauteilen
|
||||
|
||||
- In Zukunft wird das Attribut `REALE_POSITION` eingeführt. Damit kann die **exakte physische Einbauposition** eines Bauteils (z. B. Sensors) unabhängig von der tatsächlichen Platzierung des Blocks im Layout definiert werden.
|
||||
- Ermöglicht eine saubere, leserliche Platzierung der Blöcke im Plan – z. B. seitlich der Anlage (dort wo Platz ist)
|
||||
- Der Block selbst kann damit **optisch gut positioniert**, aber technisch korrekt ausgewertet werden.
|
||||
|
||||
- Bauteile ohne `REALE_POSITION` werden standardmäßig an der **gezeichneten Blockposition** verortet.
|
||||
|
||||
- **Anbindung an Kabeltrassen erfolgt immer zur nächstgelegenen Rack-Geometrie** im definierten Toleranzbereich.
|
||||
- Wird ein Block zu weit entfernt vom Rack gezeichnet (bzw. `REALE_POSITION` liegt zu weit weg), erfolgt **keine automatische Verbindung**.
|
||||
- Die maximale Toleranz ist über die Konfiguration `allgemein.cfg[tol_connect]` steuerbar.
|
||||
|
||||
- Es ist daher darauf zu achten, dass Bauteile (bzw. deren reale Positionen) **räumlich korrekt und in sinnvoller Nähe** zu den Kabeltrassen platziert sind.
|
||||
@@ -0,0 +1,85 @@
|
||||
# Automatisierung in der Verkabelung: Zeitersparnis in der Anlagenplanung
|
||||
|
||||
### Projektübersicht
|
||||
Automatische Extraktion von Equipment-Positionen und Kabeltrassen aus DXF-Layouts zur automatischen Wegfindung und optimierten Verkabelung.
|
||||
|
||||
### Projektaufgaben
|
||||
- Konzeption
|
||||
- Ausarbeitung
|
||||
- Rollout
|
||||
|
||||
---
|
||||
|
||||
## Ausgangslage (Vorher vs. Nachher)
|
||||
|
||||
**Vorher:**
|
||||
Die Platzierung von Kabeltrassen, Sensoren, Motoren und Verteilerschränken in großen Industrieanlagen erfolgte überwiegend manuell. Auch die Planung der Kabelwege, die Auswahl der Kabeltypen sowie die Stücklistenerstellung waren manuelle, zeitintensive Prozesse. Große Kabelzulagen und Änderungen führten zu Produktivitätsverlusten und erhöhten Kosten. Fehlerhafte Kabellängen beeinträchtigten die Inbetriebnahme erheblich.
|
||||
|
||||
**Nachher:**
|
||||
Die Platzierung der Elektronikkomponenten bleibt manuell, doch die Übergabe des 2D-Anlagenlayouts an das Kabeltool ermöglicht eine **vollautomatisierte**, konfigurierbare Verbindung aller Bauteile mit den Verteilerschränken entlang definierter Kabeltrassen. Kabellängen werden präzise ermittelt und Stücklisten automatisch erstellt. Dies führt zu Zeitersparnis, Kostensenkung und Qualitätssteigerung.
|
||||
|
||||
---
|
||||
|
||||
## 1/4 Ausgangslage
|
||||
Ziel war die Automatisierung der Verkabelung großer Industrieanlagen, um manuelle und fehleranfällige Prozesse zu eliminieren und stets den kürzesten Kabelweg zu ermitteln. Ein umfassendes Fehler-Management ermöglicht die frühzeitige Erkennung von Layout- und Spezifikationsfehlern. So können mehrere Verkabelungsvarianten auch effizient miteinander verglichen werden.
|
||||
|
||||
---
|
||||
|
||||
## 2/4 Idee & Konzeption
|
||||
|
||||
**Ziel:**
|
||||
Entwicklung eines Tools, das Kabellängen automatisch auf Basis von DXF-CAD-Zeichnungen ermittelt und dokumentiert. Die Verbindung von Sensoren, Aktoren und Unterverteilern wird algorithmisch über einen Graphen berechnet. Integration in bestehende CAD- und ERP-Prozesse steht im Fokus.
|
||||
|
||||
**Entscheidungsfindung:**
|
||||
- Analyse manueller Arbeitsschritte
|
||||
- Erstellung von typischen Pilotlayouts aus vorhandenen Projekten
|
||||
- Abwägung einer Eigenentwicklung gegenüber einer kommerziellen Lösung
|
||||
|
||||
**Konzeption:**
|
||||
- Anforderungen an Layout, Routinglogik und Ausgabeformate
|
||||
- Schnittstellen zu CAD, Excel und ERP (Artikelnummern)
|
||||
- Definition der Schnittstellen und Verwendung der Anwendung
|
||||
- Konfigurierbares Regelwerk zur Betriebsmittelerkennung
|
||||
- Technische Rahmenbedingungen: Python-Umgebung, Layerstrukturen und Attribute der Blöcke oder Elemente in der DXF Datei
|
||||
|
||||
**Lösung:**
|
||||
Das Tool liest DXF-Dateien ein, berechnet Kabelwege automatisch und liefert Excel-Listen sowie DXF-Dateien mit Kabelwegen zur direkten Weiterverwendung. Alles erfolgt automatisiert ohne Benutzereingriff.
|
||||
|
||||
---
|
||||
|
||||
## 3/4 Ausführung
|
||||
|
||||
### **Entwicklung:**
|
||||
- Spezifikation der Programmteilen für die automatisierte Verkabelung (Koordinatenextraktion, Routing und Ergebnis Erzeugung)
|
||||
- Programmierung von Routinglogik und Betriebsmittelerkennung inklusive Unittests
|
||||
- Modulare Architektur mit klaren Schnittstellen zu Excel, CAD und ERP
|
||||
- Iterative Tests mit Pilotlayouts
|
||||
|
||||
### **Einführung:**
|
||||
- Tool-Integration in die Konstruktionspraxis
|
||||
- Dokumentation und Anwendungsrichtlinien
|
||||
- Anpassung der CAD-DXF-Erstellungsprozesse
|
||||
- Einbindung der Excel-Outputs in Arbeitsvorbereitung und Bestellprozesse
|
||||
|
||||
#### **Konzept zur automatisierten Kabelauswertung**
|
||||
|
||||
Die Analyse der Verkabelung erfolgt direkt aus einer DXF-Datei, welche zuvor durch die Abteilung Automation zur Beschreibung der Anlage erstellt wird. Die Herausforderung bestand in der zuverlässigen Erkennung der Betriebsmittel (Stecker, Klemmen, Sensoren) sowie deren logischer Verbindung über Linienzüge, unabhängig von Layerstrukturen oder Maßstäben. Zur Lösung wurde eine robuste Parsing-Logik entwickelt, die anhand definierter Symbole und Geometriebeziehungen die Verkabelung interpretiert und automatisch Kabellisten erzeugt.
|
||||
|
||||
#### **Schnittstellen zu Bestandsdaten und ERP**
|
||||
|
||||
Die durch das Tool erzeugten Listen enthalten nicht nur Start- und Zielpunkte, sondern verknüpfen diese auch mit ERP-relevanten Informationen wie Materialnummern, Steckertypen und Kabellängen. Eine direkte Anbindung an das ERP wurde vorbereitet, jedoch vorerst über eine strukturierte Excel-Schnittstelle realisiert. So können Daten manuell geprüft und sukzessive automatisiert übernommen werden. Die Integration in bestehende Excel-basierte Arbeitsprozesse ermöglichte eine schnelle Akzeptanz und niedrige Einstiegshürde.
|
||||
|
||||
#### **Standardisierung von Symbolen und Layern**
|
||||
|
||||
Damit das Tool zuverlässig funktioniert, mussten klare Standards für Layer-Namen, Symbole und deren Attribute definiert werden. Unterschiedliche Zeichnungsstile oder unterschiedliche Benennungs - Standards aus früheren Projekten führen zu fehlerhaften Auswertungen. Durch die Festlegung verbindlicher Konventionen sowie die Bereitstellung einer Symbolbibliothek konnte ein einheitlicher Datenbestand sichergestellt werden. Dies war Voraussetzung für eine skalierbare Nutzung.
|
||||
|
||||
#### **Automatisierung wiederkehrender Arbeitsschritte**
|
||||
|
||||
Die Auswertung erfolgt auf Knopfdruck ohne Zwischenschritte. Neben der Kabelliste werden automatisch Auszüge für die Arbeitsvorbereitung, Längenlisten für die Konfektionierung und Verbindungsübersichten für die Dokumentation erzeugt. Über konfigurierbare Vorlagen lassen sich kundenspezifische Layouts anpassen. Auch eine automatische Plausibilitätsprüfung (z.B. doppelte Nummern, offene Enden) ist integriert, um Fehlerquellen frühzeitig zu erkennen – ganz ohne manuelles Nacharbeiten.
|
||||
|
||||
#### **Fehlererkennung und Qualitätssicherung**
|
||||
|
||||
Ein zentraler Bestandteil des Tools ist die automatische Prüfung auf typische Fehlerquellen: unverbundene Leitungen, doppelt vergebene Kennzeichen oder falsche Layer. Diese werden bereits bei der Analyse der DXF-Datei erkannt und in einem Fehlerprotokoll ausgegeben. Dadurch wird verhindert, dass unvollständige oder inkonsistente Daten weiterverarbeitet werden. Über die zusätzliche Ausgabe der erkannten Fehler in dafür vorgesehenen Arbeitsblättern im Excel-Output kann eine manuelle Behandlung der Fehler im Eingangs-layout erfolgen.
|
||||
|
||||
# 4/4 Ergebnis
|
||||
Der Zeitaufwand von der Konstruktion bis zur bestellbaren Baugruppe wurde deutlich reduziert. Viele fehleranfällige, manuelle Tätigkeiten im Layout entfallen – stattdessen übernehmen automatisierte Workflows wiederkehrende Aufgaben wie Wegfindung, Längenberechnung und Stücklistenerstellung. Das System ist damit nicht nur ein Werkzeug zur Auswertung, sondern ein zentrales Element in der Standardisierung elektrotechnischer Konstruktion. Es bildet die Basis für weitere Digitalisierungsschritte in der Produktentstehung und ermöglicht eine durchgängige Informationsverfügbarkeit bis hin zur Beschaffung und Inbetriebnahme.
|
||||
@@ -0,0 +1,284 @@
|
||||
# Symbole und Benennungen im DXF-Layout
|
||||
|
||||
Diese Dokumentation beschreibt, wie Symbole und Texte in der DXF-Zeichnung benannt und strukturiert sein muessen, damit sie vom System erkannt werden.
|
||||
|
||||
---
|
||||
|
||||
## 1. Sensoren / Aktoren / Motoren (Equipment)
|
||||
|
||||
Equipment wird ueber **INSERT-Bloecke mit Attributen** erkannt.
|
||||
|
||||
### Block-Attribute
|
||||
|
||||
| Attribut-Tag | Bedeutung | Beispiel | Pflicht |
|
||||
|---|---|---|---|
|
||||
| `NAME` | Geraete-ID (moderner Block) | `MA0062`, `BG3240` | Ja (oder IO+B) |
|
||||
| `IO` | Geraete-ID (I/O-Block, Legacy) | `MA0062` | Alternativ zu NAME |
|
||||
| `B` | Geraete-ID (Technik-Block, Legacy) | `MA0062` | Alternativ zu NAME |
|
||||
| `ARTINR` | SIVAS-Artikelnummer | `790902001` | Ja |
|
||||
| `KENNZEICHNUNG` | Routing-Adresse | `=A01+UH01-KF1DQ04` | Ja |
|
||||
| `SPS` | SPS-Praefix / Anlage | `1` | Ja (fuer Zuordnung) |
|
||||
| `VERW` | Verwendung/Beschreibung | `CV-M0062_0,75` | Nein |
|
||||
| `REALE_POSITION` | Marker fuer tatsaechliche Position | `x` | Nein |
|
||||
|
||||
### Geraete-Praefix (erste 2 Zeichen der ID)
|
||||
|
||||
Welche Geraete geroutet werden, bestimmt die `cfg/BMK.cfg`:
|
||||
|
||||
**Routing-Include** (werden geroutet):
|
||||
|
||||
| Praefix | Typ |
|
||||
|---|---|
|
||||
| `MA` | Motoren |
|
||||
| `MB` | Ventile |
|
||||
| `QM` | Ventile/Pumpen |
|
||||
| `BG` | Sensoren/Naeherungsschalter |
|
||||
| `BP` | Naeherungsschalter |
|
||||
| `BX` | Mehrzweckgeraete, z.B. Scanner |
|
||||
| `PO` | Pneumatik-Elemente |
|
||||
| `SF` | Sicherheitselemente |
|
||||
| `PF` | Programmierbare Logik |
|
||||
| `GF` | Encoder |
|
||||
|
||||
**Routing-Ignore** (Schaltschrankelemente, nicht geroutet):
|
||||
|
||||
| Praefix | Typ |
|
||||
|---|---|
|
||||
| `FC` | Steuerungselemente |
|
||||
| `UH` | Unterverteiler |
|
||||
| `UC` | Unterverteiler |
|
||||
| `UZ` | Spezialverteiler |
|
||||
| `DI` | Digitale Eingaenge |
|
||||
| `DQ` | Digitale Ausgaenge |
|
||||
| `QA` | Ausgabegeraete |
|
||||
|
||||
### KENNZEICHNUNG-Format
|
||||
|
||||
```
|
||||
=ANLAGE+VERTEILER-KARTE
|
||||
```
|
||||
|
||||
**Beispiel:** `=A01+UH01-KF1DQ04`
|
||||
|
||||
| Teil | Bedeutung | Beispiel |
|
||||
|---|---|---|
|
||||
| ANLAGE | Anlagengruppe | `A01` |
|
||||
| VERTEILER | Unterverteiler-ID | `UH01` |
|
||||
| KARTE | Karte/Kanal | `KF1DQ04` |
|
||||
|
||||
Trennzeichen: `=` (Start), `+` (zwischen Anlage und Verteiler), `-` (zwischen Verteiler und Karte)
|
||||
|
||||
### Block-Zusammenfuehrung (Legacy Dual-Block)
|
||||
|
||||
Bei der alten Dual-Block-Struktur werden zwei Bloecke mit gleicher ID (z.B. `MA0062`) zusammengefuehrt, wenn:
|
||||
- Beide innerhalb von **1000mm** Abstand liegen
|
||||
- Einer das `SPS`-Attribut hat, der andere nicht
|
||||
- Ergebnis-ID: `{id}@{sps}` (z.B. `MA0062@1`)
|
||||
|
||||
---
|
||||
|
||||
## 2. Unterverteiler (Distributoren)
|
||||
|
||||
Unterverteiler koennen auf **zwei Arten** definiert werden: als Text oder als Symbol.
|
||||
|
||||
### Variante A: Text (MTEXT)
|
||||
|
||||
Ein MTEXT-Element auf einem erlaubten Layer mit folgendem Muster:
|
||||
|
||||
```
|
||||
-UH01 (Minus vor dem Namen)
|
||||
+UH01 (Plus vor dem Namen)
|
||||
```
|
||||
|
||||
Der Text muss den Verteilernamen als Teilstring enthalten, mit `-` oder `+` davor.
|
||||
|
||||
**Erlaubte Layer** (konfiguriert in `cfg/allgemein.cfg`, Sektion `GetPos-Layer_Distributors`):
|
||||
- `Busverteiler-Kennzeichnung`
|
||||
- `0-0_ILS_Busverteiler-Kennzeichnung`
|
||||
- `0-0_ILS_UNTERVERTEILER`
|
||||
- `0-0_ILS_Unterverteiler`
|
||||
- `0-0_Omniflo_UNTERVERTEILER`
|
||||
- `0-0_Omniflo_Unterverteiler`
|
||||
- `UNTERVERTEILER`
|
||||
- `0-0_Omniflo_Busverteiler-Kennzeichnung`
|
||||
- `Schaltschrank-ILS`
|
||||
|
||||
### Variante B: Symbol (INSERT-Block)
|
||||
|
||||
Ein INSERT-Block mit dem Attribut `NAME`, dessen Wert einem **Cabinet-Pattern** entspricht.
|
||||
|
||||
**Cabinet-Patterns** (Regex, konfiguriert in `cfg/BMK.cfg`, Sektion `Cabinet-Pattern`):
|
||||
|
||||
| Pattern | Beispiel-Match | Extrahierte ID |
|
||||
|---|---|---|
|
||||
| `A\d\d\+(UH0\d)` | `A01+UH01` | `UH01` |
|
||||
| `A\d\d\+(UC\d\d\d)` | `A01+UC001` | `UC001` |
|
||||
| `\+(UC\d\d\d\d)` | `+UC0101` | `UC0101` |
|
||||
| `\+(UH\d\d)` | `+UH01` | `UH01` |
|
||||
|
||||
Die Klammer-Gruppe im Regex bestimmt die extrahierte Verteiler-ID.
|
||||
|
||||
**Optionale Attribute:**
|
||||
- `REALE_POSITION` = `x` : Position wird aus Attribut-Position berechnet (Mittelpunkt des Markers)
|
||||
- `SPS` : SPS-Zuordnung
|
||||
|
||||
---
|
||||
|
||||
## 3. Tunnel
|
||||
|
||||
Tunnel koennen ebenfalls als **Text** oder **Symbol** definiert werden.
|
||||
|
||||
### Variante A: Text (MTEXT)
|
||||
|
||||
Ein MTEXT-Element auf einem erlaubten Layer mit folgendem Muster:
|
||||
|
||||
```
|
||||
TUNNEL1-5 (Tunnelname-Laenge)
|
||||
TUNNEL2-10
|
||||
```
|
||||
|
||||
**Regex:** `(TUNNEL\d+)-(\d+)`
|
||||
|
||||
| Teil | Bedeutung | Beispiel |
|
||||
|---|---|---|
|
||||
| Gruppe 1 | Tunnelname | `TUNNEL1` |
|
||||
| Gruppe 2 | Laenge in Metern | `5` |
|
||||
|
||||
Pro Tunnel muessen genau **2 MTEXT-Elemente** vorhanden sein (Ein- und Ausgang).
|
||||
|
||||
**Erlaubte Layer** (konfiguriert in `cfg/allgemein.cfg`, Sektion `GetPos-Layer_Tunnel`):
|
||||
- `Busverteiler-Kennzeichnung`
|
||||
- `0-0_Tunnel`
|
||||
|
||||
### Variante B: Symbol (INSERT-Block)
|
||||
|
||||
Ein INSERT-Block mit dem Attribut `NAME`, dessen Wert einem **Tunnel-Pattern** entspricht.
|
||||
|
||||
**Tunnel-Patterns** (Regex, konfiguriert in `cfg/BMK.cfg`, Sektion `Tunnel-Pattern`):
|
||||
|
||||
| Pattern | Beispiel |
|
||||
|---|---|
|
||||
| `Tunnel\d+` | `Tunnel1`, `Tunnel2` |
|
||||
| `Tunnel_\d+` | `Tunnel_1`, `Tunnel_2` |
|
||||
| `Tunnel-\d+` | `Tunnel-1`, `Tunnel-2` |
|
||||
| `TUNNEL\d+` | `TUNNEL1`, `TUNNEL2` |
|
||||
|
||||
**Attribute:**
|
||||
|
||||
| Attribut-Tag | Bedeutung | Beispiel | Pflicht |
|
||||
|---|---|---|---|
|
||||
| `NAME` | Tunnelname | `Tunnel1` | Ja |
|
||||
| `LAENGE` | Tunnellaenge in Metern | `5` | Nein (Default: 5) |
|
||||
| `REALE_POSITION` | Positionsmarker | `x` | Nein |
|
||||
|
||||
Pro Tunnel muessen genau **2 Symbole** platziert werden (Ein- und Ausgang).
|
||||
|
||||
**Fehler bei Tunnel-Definition:**
|
||||
- Weniger als 2 Positionen: Fehler `missing_tunnel`
|
||||
- Mehr als 2 Positionen: Fehler `overdefined_tunnel`
|
||||
- Fehlende Laenge: Warnung, Default 5m wird verwendet
|
||||
|
||||
---
|
||||
|
||||
## 4. Kabelpritschen (Racks)
|
||||
|
||||
Kabelpritschen werden als **LWPOLYLINE** oder **POLYLINE** auf bestimmten Layern erkannt.
|
||||
|
||||
Es sind keine Attribute oder Texte noetig - nur der **Layer** entscheidet.
|
||||
|
||||
**Erlaubte Layer** (konfiguriert in `cfg/allgemein.cfg`, Sektion `GetPos-Layer_Racks`):
|
||||
|
||||
| Layer | Beschreibung |
|
||||
|---|---|
|
||||
| `PRITSCHE_100-60` | Standard 100x60 |
|
||||
| `PRITSCHE_100-60-SCHRAFF` | Standard 100x60 schraffiert |
|
||||
| `PRITSCHE_200-60` | Standard 200x60 |
|
||||
| `PRITSCHE_200-60_ILS` | ILS 200x60 |
|
||||
| `PRITSCHE_200-60_OMNIFLO` | Omniflo 200x60 |
|
||||
| `0-0_ILS_PRITSCHE_200-60_storage_Level1` | ILS Storage Level 1 |
|
||||
| `0-0_ILS_PRITSCHE_200-60_storage_Level2` | ILS Storage Level 2 |
|
||||
| `0-0_ILS_PRITSCHE_200-60_Workstation` | ILS Workstation |
|
||||
| `0-0_ILS_Pritsche_200-60_AMR` | ILS AMR |
|
||||
| `0-0_ILS_PRITSCHE_200-60_Highway` | ILS Highway |
|
||||
| `0-0_ILS_Pritsche_200-60_Inbound` | ILS Inbound |
|
||||
| `0-0_Omniflo_Pritsche_200-60_Workstation-Outbound` | Omniflo Workstation Outbound |
|
||||
| `0-0_Omniflo_Pritsche_200-60_outbound` | Omniflo Outbound |
|
||||
| `0-0_Omniflo_Pritsche_200-60_AMR` | Omniflo AMR |
|
||||
| `0-0_Omniflo_Pritsche_200-60_Highway` | Omniflo Highway |
|
||||
|
||||
**Validierung:** Wenn die Z-Koordinaten aller Racks mehr als 2000mm auseinanderliegen, wird eine Warnung ausgegeben (Schwellwert konfigurierbar in `cfg/allgemein.cfg`, Sektion `Racks`, Schluessel `MaximalTotalHeightDifferences`).
|
||||
|
||||
---
|
||||
|
||||
## 5. Zusammenfassung: Was muss im Layout vorhanden sein?
|
||||
|
||||
| Element | Erkennungsart | Mindestangaben |
|
||||
|---|---|---|
|
||||
| **Sensor/Motor** | INSERT-Block | `NAME` (oder `IO`+`B`), `ARTINR`, `KENNZEICHNUNG` |
|
||||
| **Unterverteiler** | MTEXT **oder** INSERT-Block | Text: `-UH01` auf richtigem Layer / Block: `NAME` = `A01+UH01` |
|
||||
| **Tunnel** | MTEXT **oder** INSERT-Block | Text: `TUNNEL1-5` (2x) / Block: `NAME` = `Tunnel1`, `LAENGE` = `5` (2x) |
|
||||
| **Kabelpritsche** | LWPOLYLINE/POLYLINE | Auf richtigem Layer gezeichnet |
|
||||
|
||||
---
|
||||
|
||||
## 6. Funktionsreferenz (getpositions.py)
|
||||
|
||||
Uebersicht der zentralen Funktionen, die die Erkennung durchfuehren.
|
||||
|
||||
### Sensoren / Equipment
|
||||
|
||||
| Funktion | Zeile | Aufgabe |
|
||||
|---|---|---|
|
||||
| `get_attributes_of_insert(d_insert, d_pos)` | ~76 | Extrahiert ID, Typ und Position aus einem einzelnen INSERT-Block. Prueft zuerst `IO`, dann `NAME`, dann `B`. Bei `REALE_POSITION='x'` wird der Mittelpunkt aus Marker-Geometrie berechnet (Breite/Hoehe aus Config). Gibt `(dict, id, typ)` zurueck. |
|
||||
| `extract_input_positions(all_inserts, all_positions, error_collector)` | ~221 | Hauptfunktion: Iteriert ueber alle Bloecke, ruft `get_attributes_of_insert()` auf, trennt Sensoren von Schaltschrankelementen anhand des Praefixes. Fuehrt Block-Zusammenfuehrung via `CompareBuffer` durch. |
|
||||
| `allocate_blocks_together(...)` | ~329 | Fuehrt die Zusammenfuehrung von Dual-Bloecken durch (Legacy). Nutzt `CompareBuffer.positions_are_close()` mit 1000mm Toleranz. |
|
||||
|
||||
### Unterverteiler
|
||||
|
||||
| Funktion | Zeile | Aufgabe |
|
||||
|---|---|---|
|
||||
| `get_subdistributor_positions_from_entities(entities, dist2sensors)` | ~547 | **Text-Erkennung:** Iteriert ueber MTEXT-Entities auf erlaubten Layern. Sucht nach `-{name}` oder `+{name}` im Text. Gibt `{distname: (x, y)}` zurueck. |
|
||||
| `get_subdistributor_positions_from_symbols(all_inserts, all_positions, dist2sensors)` | ~472 | **Symbol-Erkennung:** Iteriert ueber alle INSERT-Bloecke mit `NAME`-Attribut. Prueft NAME gegen Cabinet-Patterns aus BMK.cfg. Ruft `get_subdistributor_position_of_symbol()` fuer die Positionsextraktion auf. |
|
||||
| `get_subdistributor_position_of_symbol(d_insert, d_pos)` | ~413 | Hilfsfunktion: Extrahiert Position aus einem einzelnen Unterverteiler-Block. Beruecksichtigt `REALE_POSITION` fuer Mittelpunktberechnung. Gibt `(dict, id)` zurueck. |
|
||||
|
||||
### Tunnel
|
||||
|
||||
| Funktion | Zeile | Aufgabe |
|
||||
|---|---|---|
|
||||
| `get_tunnel_positions_from_entities(entities)` | ~574 | **Text-Erkennung:** Iteriert ueber MTEXT-Entities auf erlaubten Layern. Regex `(TUNNEL\d+)-(\d+)` extrahiert Name und Laenge. Sammelt alle Positionen pro Tunnelname. |
|
||||
| `get_tunnel_positions_from_symbols(all_inserts, all_positions, error_collector)` | ~493 | **Symbol-Erkennung:** Iteriert ueber alle INSERT-Bloecke mit `NAME`-Attribut. Prueft NAME gegen Tunnel-Patterns aus BMK.cfg. Liest `LAENGE`-Attribut (Default: 5m). Warnung bei fehlender Laenge. |
|
||||
| `get_tunnel_position_of_symbol(d_insert, d_pos)` | ~441 | Hilfsfunktion: Extrahiert Position und Laenge aus einem einzelnen Tunnel-Block. Beruecksichtigt `REALE_POSITION`. Gibt `(dict, id)` zurueck. |
|
||||
|
||||
### Kabelpritschen
|
||||
|
||||
| Funktion | Zeile | Aufgabe |
|
||||
|---|---|---|
|
||||
| `get_rack_positions(msp)` | ~614 | Sucht LWPOLYLINE und POLYLINE auf erlaubten Layern. Nummeriert Racks automatisch (`Rack_1`, `Rack_2`, ...). Delegiert an `handle_lwpolyline()` bzw. `handle_polyline()`. |
|
||||
| `handle_lwpolyline(entity, rack_key, ret)` | ~636 | Verarbeitet 2D-Polylinien. Z-Wert kommt global aus `elevation`. |
|
||||
| `handle_polyline(entity, rack_key, ret)` | ~644 | Verarbeitet 3D-Polylinien. Jeder Vertex hat individuelle x/y/z-Koordinaten. |
|
||||
| `check_rack_z_coordinates(res_racks, error_collector, config)` | ~654 | Validierung: Prueft ob Z-Koordinaten-Differenz den Schwellwert uebersteigt. |
|
||||
|
||||
### Erkennungsablauf im Hauptprogramm
|
||||
|
||||
```
|
||||
1. DXF laden: get_dxf_file() -> msp
|
||||
2. Alle Bloecke extrahieren: attribs_to_dicts(msp) -> all_inserts, all_positions
|
||||
3. Sensoren: extract_input_positions(all_inserts, all_positions)
|
||||
4. Mappings: create_mappings(res_sens) -> sensor2unterverteiler
|
||||
5. Unterverteiler (Text): get_subdistributor_positions_from_entities(msp.query('MTEXT'))
|
||||
6. Unterverteiler (Symbol): get_subdistributor_positions_from_symbols(all_inserts, all_positions)
|
||||
7. Tunnel (Text): get_tunnel_positions_from_entities(msp.query('MTEXT'))
|
||||
8. Tunnel (Symbol): get_tunnel_positions_from_symbols(all_inserts, all_positions)
|
||||
9. Racks: get_rack_positions(msp)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Konfigurationsdateien
|
||||
|
||||
| Datei | Inhalt |
|
||||
|---|---|
|
||||
| `cfg/allgemein.cfg` | Layer-Zuordnungen, Geometrie-Parameter, Toleranzen |
|
||||
| `cfg/BMK.cfg` | Geraete-Praefixe, Cabinet-Patterns, Tunnel-Patterns, Kabelzuordnungen |
|
||||
| `cfg/kabel.cfg` | SIVAS-Artikelnummern nach Kabeltyp und Laenge |
|
||||
| `cfg/bezeichner.cfg` | Artikelnummer-Beschreibungen |
|
||||
|
After Width: | Height: | Size: 663 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 486 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
@@ -0,0 +1,4 @@
|
||||
[ViewState]
|
||||
Mode=
|
||||
Vid=
|
||||
FolderType=Pictures
|
||||
|
After Width: | Height: | Size: 800 KiB |
|
After Width: | Height: | Size: 766 KiB |
|
After Width: | Height: | Size: 800 KiB |
|
After Width: | Height: | Size: 722 KiB |
|
After Width: | Height: | Size: 124 KiB |
|
After Width: | Height: | Size: 669 KiB |
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 667 KiB |
|
After Width: | Height: | Size: 120 KiB |
|
After Width: | Height: | Size: 667 KiB |
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 667 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
@@ -0,0 +1,686 @@
|
||||
# translate.py - Text-Extraktion und -Übersetzung für DXF-Dateien
|
||||
|
||||
## Übersicht
|
||||
|
||||
`translate.py` ist ein Python-Tool zur Extraktion, Filterung und Übersetzung von Texten aus DXF/DWG-Dateien. Es unterstützt mehrere Arbeitsweisen und ermöglicht die Erstellung mehrsprachiger technischer Zeichnungen für den internationalen Einsatz.
|
||||
|
||||
---
|
||||
|
||||
## Quickstart - Haupt-Workflow für DXF-Übersetzung
|
||||
|
||||
Dieser Workflow beschreibt die **empfohlene Vorgehensweise** für die Übersetzung technischer Zeichnungen.
|
||||
|
||||
### Schritt 1: Text-Extraktion aus DXF
|
||||
|
||||
Ziehen Sie die DXF-Datei per **Drag & Drop** auf die Desktop-Verknüpfung **`tr_dxf2txt`**:
|
||||
|
||||
<img src="img/Icons/dxf2txt.png" width="113" alt="tr_dxf2txt Icon">
|
||||
|
||||
**Was passiert:**
|
||||
- Alle TEXT, MTEXT und Block-Attribute (TEXT-D) werden aus der DXF extrahiert
|
||||
- Zwei Dateien werden im `work/` Ordner erstellt:
|
||||
- `<dateiname>_texts.json` - JSON-Datei mit allen extrahierten Texten
|
||||
- `<dateiname>_texts.txt` - Textdatei mit allen extrahierten Texten
|
||||
|
||||
**Beispiel:**
|
||||
```
|
||||
Eingabe: Projekt_Anlage_Rev3.dxf
|
||||
Ausgabe: work/Projekt_Anlage_Rev3_texts.json
|
||||
work/Projekt_Anlage_Rev3_texts.txt
|
||||
```
|
||||
|
||||
### Schritt 2: Automatische Übersetzung mit Sprach-Config
|
||||
|
||||
Ziehen Sie die erzeugte **JSON-Datei** (`<dateiname>_texts.json`) per **Drag & Drop** auf die gewünschte Sprach-Verknüpfung:
|
||||
|
||||
- **tr2dxf_CS** (Tschechisches Icon) → Tschechische Übersetzung
|
||||
- **tr2dxf_EN** (Englisch-Icon) → Englische Übersetzung
|
||||
- **tr2dxf_FR** (Französisch-Icon) → Französische Übersetzung
|
||||
- **tr2dxf_ES** (Spanisch-Icon) → Spanische Übersetzung
|
||||
- **tr2dxf_IT** (Italienisch-Icon) → Italienische Übersetzung
|
||||
|
||||
<img src="img/Icons/dxfCs.png" width="113" alt="tr2dxf_CS Icon">
|
||||
<img src="img/Icons/dxfEN.png" width="113" alt="tr2dxf_EN Icon">
|
||||
<img src="img/Icons/dxfFR.png" width="113" alt="tr2dxf_FR Icon">
|
||||
<img src="img/Icons/dxfES.png" width="113" alt="tr2dxf_ES Icon">
|
||||
|
||||
**Was passiert:**
|
||||
- Die JSON-Datei wird mit der aktuellen Sprachkonfiguration (z.B. `CS.cfg`) re-übersetzt
|
||||
- Alle konfigurierten Begriffe werden automatisch übersetzt
|
||||
- Der `[translate]` Block in der JSON wird mit Übersetzungen gefüllt
|
||||
- Nicht-übersetzte Begriffe bleiben im `untranslated` Block
|
||||
|
||||
**JSON-Struktur nach diesem Schritt:**
|
||||
```json
|
||||
{
|
||||
"[CS]": {
|
||||
"translations": [
|
||||
{"source": "Emergency stop", "target": "Nouzové zastavení"},
|
||||
{"source": "Power supply", "target": "Napájení"}
|
||||
],
|
||||
"untranslated": [
|
||||
{"source": "Custom text XY", "target": ""}
|
||||
]
|
||||
},
|
||||
"ignored": ["X=123.45", "LAYER=0"]
|
||||
}
|
||||
```
|
||||
|
||||
### Schritt 3: Sichtkontrolle und manuelle Ergänzung
|
||||
|
||||
Öffnen Sie die `_texts.json` Datei mit einem **Texteditor** oder **JSON-Editor** und prüfen Sie:
|
||||
|
||||
1. **Translations Block:** Sind alle Übersetzungen korrekt?
|
||||
2. **Untranslated Block:** Welche Begriffe fehlen noch?
|
||||
|
||||
Bei Bedarf:
|
||||
- Fügen Sie fehlende Übersetzungen **manuell** in die JSON ein:
|
||||
```json
|
||||
{"source": "Custom text XY", "target": "Vlastní text XY"}
|
||||
```
|
||||
- **Oder** ergänzen Sie die Sprach-Config (`translation/CS.cfg`) und wiederholen Sie Schritt 2
|
||||
|
||||
**Hinweis zur .txt Datei:**
|
||||
Die parallel erzeugte `.txt` Datei hat folgendes Format:
|
||||
```
|
||||
--- translations:
|
||||
|
||||
Emergency stop -> Nouzové zastavení
|
||||
Power supply -> Napájení
|
||||
|
||||
--- untranslated:
|
||||
|
||||
Custom text XY
|
||||
|
||||
--- ignored:
|
||||
|
||||
X=123.45
|
||||
LAYER=0
|
||||
```
|
||||
|
||||
Die `.txt` Datei eignet sich gut für einen **schnellen Überblick**, während die `.json` Datei für die tatsächliche DXF-Übersetzung verwendet wird.
|
||||
|
||||
### Schritt 4: DXF-Datei übersetzen
|
||||
|
||||
Ziehen Sie die **Original-DXF-Datei** per **Drag & Drop** auf die gewünschte **Sprach-Verknüpfung** (z.B. `tr2dxf_CS`).
|
||||
|
||||
**Voraussetzung:**
|
||||
- Die `<dateiname>_texts.json` muss im `work/` Ordner vorhanden sein
|
||||
- Die JSON sollte möglichst vollständige Übersetzungen enthalten
|
||||
|
||||
**Was passiert:**
|
||||
- Eine neue DXF-Datei wird erstellt: `<dateiname>_CS.dxf` (oder EN, FR, etc.)
|
||||
- Alle TEXT, MTEXT und Block-Attribute werden übersetzt
|
||||
- Die Übersetzungen werden in die entsprechenden Ziel-Attribute geschrieben:
|
||||
- TEXT-D → TEXT-CS (bei Tschechisch)
|
||||
- TEXT-D → TEXT-E (bei Englisch)
|
||||
- TEXT-D → TEXT-ES (bei Spanisch)
|
||||
- etc.
|
||||
- Das Original-Attribut TEXT-D bleibt **unverändert erhalten**
|
||||
|
||||
**Beispiel:**
|
||||
```
|
||||
Eingabe: Projekt_Anlage_Rev3.dxf (+ work/Projekt_Anlage_Rev3_texts.json)
|
||||
Ausgabe: work/Projekt_Anlage_Rev3_CS.dxf
|
||||
```
|
||||
|
||||
### Zusammenfassung des Workflows
|
||||
|
||||
```
|
||||
1. DXF → [tr_dxf2txt] → _texts.json + _texts.txt
|
||||
↓
|
||||
2. _texts.json → [tr2dxf_CS] → _texts.json (mit Übersetzungen)
|
||||
↓
|
||||
3. Manuelle Prüfung/Ergänzung der JSON
|
||||
↓
|
||||
4. DXF → [tr2dxf_CS] → DXF_CS.dxf (übersetzte Zeichnung)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Konfiguration für neue Sprachen
|
||||
|
||||
Wenn Sie eine neue Sprache konfigurieren oder bestehende Übersetzungen erweitern möchten, folgen Sie dieser Anleitung.
|
||||
|
||||
### Aufbau der Sprach-Konfigurationsdateien
|
||||
|
||||
Sprach-Configs befinden sich im Verzeichnis `translation/` (z.B. `CS.cfg`, `EN.cfg`, `FR.cfg`).
|
||||
|
||||
Jede Config-Datei hat **vier Sektionen** in festgelegter Prioritätsreihenfolge:
|
||||
|
||||
1. **[multi]** - Phrasen mit 4 oder mehr Wörtern
|
||||
2. **[trigramme]** - Phrasen mit genau 3 Wörtern
|
||||
3. **[bigramme]** - Phrasen mit genau 2 Wörtern
|
||||
4. **[single]** - Einzelwörter
|
||||
|
||||
**Wichtig:** Die Übersetzung erfolgt in dieser Reihenfolge. Längere Phrasen werden zuerst ersetzt, danach kürzere.
|
||||
|
||||
### Empfohlene Vorgehensweise beim Konfigurieren
|
||||
|
||||
#### 1. Erste Extraktion durchführen
|
||||
|
||||
Führen Sie zunächst eine Text-Extraktion **ohne Übersetzung** durch:
|
||||
|
||||
```bash
|
||||
bin\translate.bat --filename projekt.dxf --extract --outname projekt_texts.json
|
||||
```
|
||||
|
||||
Dies erzeugt `projekt_texts.json` und `projekt_texts.txt` mit allen extrahierten Texten.
|
||||
|
||||
#### 2. Zusammenhängende Phrasen identifizieren
|
||||
|
||||
Öffnen Sie die `.txt` Datei und suchen Sie nach zusammenhängenden Phrasen:
|
||||
|
||||
**Beispiele für zusammenhängende Phrasen:**
|
||||
- "Main distribution panel" (3 Wörter)
|
||||
- "Emergency stop button" (3 Wörter)
|
||||
- "Power supply unit" (3 Wörter)
|
||||
- "Safety circuit monitoring relay" (4 Wörter)
|
||||
|
||||
#### 3. Konfiguration ausfüllen - Sektion [multi]
|
||||
|
||||
Beginnen Sie mit den **längsten Phrasen** (4+ Wörter) in der `[multi]` Sektion:
|
||||
|
||||
```ini
|
||||
[multi]
|
||||
Safety circuit monitoring relay = Relé sledování bezpečnostního obvodu
|
||||
Main circuit breaker control unit = Hlavní jistič řízení jednotky
|
||||
Emergency stop button reset function = Nouzové tlačítko funkce reset
|
||||
```
|
||||
|
||||
**Format:** `Original = Übersetzung`
|
||||
|
||||
#### 4. Konfiguration ausfüllen - Sektion [trigramme]
|
||||
|
||||
Fügen Sie **3-Wort-Phrasen** in die `[trigramme]` Sektion ein:
|
||||
|
||||
```ini
|
||||
[trigramme]
|
||||
Main distribution panel = Hlavní rozváděč
|
||||
Power supply unit = Napájecí zdroj
|
||||
Emergency stop button = Nouzové tlačítko zastavení
|
||||
Safety light curtain = Bezpečnostní světelná závěsa
|
||||
Motor protection switch = Ochrana motoru spínač
|
||||
```
|
||||
|
||||
#### 5. Konfiguration ausfüllen - Sektion [bigramme]
|
||||
|
||||
Fügen Sie **2-Wort-Phrasen** in die `[bigramme]` Sektion ein:
|
||||
|
||||
```ini
|
||||
[bigramme]
|
||||
Emergency stop = Nouzové zastavení
|
||||
Power supply = Napájení
|
||||
Control panel = Ovládací panel
|
||||
Safety relay = Bezpečnostní relé
|
||||
Main switch = Hlavní spínač
|
||||
Motor protection = Ochrana motoru
|
||||
```
|
||||
|
||||
#### 6. Konfiguration ausfüllen - Sektion [single]
|
||||
|
||||
Fügen Sie **Einzelwörter** in die `[single]` Sektion ein:
|
||||
|
||||
```ini
|
||||
[single]
|
||||
Weight = Hmotnost
|
||||
Cable = Kabel
|
||||
Emergency = Nouzový
|
||||
Stop = Zastavení
|
||||
Power = Napájení
|
||||
Control = Ovládání
|
||||
Safety = Bezpečnost
|
||||
Motor = Motor
|
||||
Switch = Spínač
|
||||
Panel = Panel
|
||||
```
|
||||
|
||||
**Hinweis:** Einzelwörter werden auch innerhalb von Wörtern mit Sonderzeichen erkannt:
|
||||
- `"Weight:"` → `"Hmotnost:"`
|
||||
- `"(Motor)"` → `"(Motor)"`
|
||||
- `"\\fArial|b0;Switch"` → `"\\fArial|b0;Spínač"`
|
||||
|
||||
### Warum diese Reihenfolge?
|
||||
|
||||
Die Reihenfolge **Multi → Trigramme → Bigramme → Single** ist entscheidend für korrekte Übersetzungen:
|
||||
|
||||
**Beispiel:**
|
||||
- Text: `"Emergency stop button"`
|
||||
- Falsche Reihenfolge (single zuerst):
|
||||
- "Emergency" → "Nouzový"
|
||||
- "stop" → "zastavení"
|
||||
- Ergebnis: `"Nouzový zastavení button"` ❌
|
||||
|
||||
- Richtige Reihenfolge (trigramme zuerst):
|
||||
- "Emergency stop button" → "Nouzové tlačítko zastavení" ✓
|
||||
|
||||
### Testen der Konfiguration
|
||||
|
||||
Nach dem Ausfüllen der Config testen Sie die Übersetzung:
|
||||
|
||||
```bash
|
||||
# Extraktion mit automatischer Übersetzung
|
||||
bin\translate.bat --filename projekt.dxf --extract --translate CS --outname test_cs.json
|
||||
|
||||
# Prüfen Sie die JSON-Datei:
|
||||
# - "translations" Block: erfolgreich übersetzte Begriffe
|
||||
# - "untranslated" Block: fehlende Übersetzungen
|
||||
```
|
||||
|
||||
Ergänzen Sie die Config basierend auf dem `untranslated` Block und wiederholen Sie den Test.
|
||||
|
||||
### Re-Übersetzung einer bestehenden JSON
|
||||
|
||||
Wenn Sie die Sprach-Config erweitert haben, können Sie eine bestehende JSON-Datei **re-übersetzen**:
|
||||
|
||||
```bash
|
||||
# Manuelle Kommandozeile
|
||||
bin\translate.bat --retranslate-json projekt_texts.json --translate CS
|
||||
|
||||
# ODER: Drag & Drop der JSON auf die Sprach-Verknüpfung (tr2dxf_CS)
|
||||
```
|
||||
|
||||
Dies aktualisiert alle Übersetzungen basierend auf der aktuellen Config.
|
||||
|
||||
---
|
||||
|
||||
## Hauptfunktionen
|
||||
|
||||
- **Text-Extraktion**: Extrahiert TEXT, MTEXT und Block-Attribute aus DXF-Dateien
|
||||
- **Text-Filterung**: Filtert Texte basierend auf konfigurierbaren Mustern (Wildcards und Regex)
|
||||
- **Automatische Übersetzung**: Übersetzt Texte mittels konfigurierbarer Wörterbücher (Multi-Phrasen, Trigramme, Bigramme, Einzelwörter)
|
||||
- **DXF-zu-DXF Übersetzung**: Erstellt übersetzte DXF-Dateien mit mehrsprachigen Attributen
|
||||
- **Mehrsprachige Übersetzung**: Unterstützt gleichzeitige Übersetzung in mehrere Sprachen
|
||||
- **Export**: Exportiert Texte in verschiedene Formate (Excel, JSON, Text)
|
||||
|
||||
---
|
||||
|
||||
## Konfigurationsdateien
|
||||
|
||||
### translator.cfg
|
||||
|
||||
Hauptkonfigurationsdatei im `cfg/` Verzeichnis:
|
||||
|
||||
```ini
|
||||
[symbol_attribute]
|
||||
# Zuordnung von Sprachcodes zu Block-Attributnamen
|
||||
DE = TEXT-D
|
||||
EN = TEXT-E
|
||||
ES = TEXT-ES
|
||||
CS = TEXT-CS
|
||||
FR = TEXT-F
|
||||
|
||||
[symbol_layer]
|
||||
# Zuordnung von Sprachcodes zu Layer-Namen
|
||||
DE = 0-0_TEXT-D
|
||||
EN = 0-0_TEXT-E
|
||||
ES = 0-0_TEXT-ES
|
||||
CS = 0-0_TEXT-CS
|
||||
FR = 0-0_TEXT-F
|
||||
|
||||
[ignore_pattern_wildcard]
|
||||
# Wildcard-Muster für zu ignorierende Texte
|
||||
coord_x = X=*
|
||||
coord_y = Y=*
|
||||
coord_z = Z=*
|
||||
# ... weitere Muster
|
||||
|
||||
[ignore_pattern_regex]
|
||||
# Regex-Muster für zu ignorierende Texte
|
||||
coord_arrows = ^\+\d{1,3}(?:[.,]\d{3})\s*(?:<<<|>>>)\s*\+\d{1,3}(?:[.,]\d{3})$
|
||||
ip_adress = ^.*;(\d{1,3}\.){3}\d{1,3}$
|
||||
# ... weitere Muster
|
||||
```
|
||||
|
||||
**Zweck der Sektionen:**
|
||||
- **[symbol_attribute]**: Mapping von Sprach-Codes zu DXF-Block-Attributnamen
|
||||
- **[symbol_layer]**: Mapping von Sprach-Codes zu DXF-Layer-Namen
|
||||
- **[ignore_pattern_wildcard]**: Einfache Muster mit `*` und `?` für zu ignorierende Texte
|
||||
- **[ignore_pattern_regex]**: Reguläre Ausdrücke für komplexere Filter-Muster
|
||||
|
||||
### Übersetzungs-Configs (Beispiel: CS.cfg)
|
||||
|
||||
Sprachspezifische Konfigurationsdateien im `translation/` Verzeichnis:
|
||||
|
||||
```ini
|
||||
[multi]
|
||||
# Phrasen mit 4+ Wörtern
|
||||
Safety circuit monitoring relay = Relé sledování bezpečnostního obvodu
|
||||
Main circuit breaker control unit = Hlavní jistič řízení jednotky
|
||||
|
||||
[trigramme]
|
||||
# 3-Wort-Phrasen
|
||||
Main distribution panel = Hlavní rozváděč
|
||||
Power supply unit = Napájecí zdroj
|
||||
Emergency stop button = Nouzové tlačítko zastavení
|
||||
|
||||
[bigramme]
|
||||
# 2-Wort-Phrasen
|
||||
Emergency stop = Nouzové zastavení
|
||||
Power supply = Napájení
|
||||
Control panel = Ovládací panel
|
||||
|
||||
[single]
|
||||
# Einzelwörter
|
||||
Weight = Hmotnost
|
||||
Cable = Kabel
|
||||
Emergency = Nouzový
|
||||
Stop = Zastavení
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verwendungsbeispiele (Kommandozeile)
|
||||
|
||||
### 1. Text-Extraktion aus DXF
|
||||
|
||||
Extrahiert Texte aus einer DXF-Datei und speichert sie in verschiedenen Formaten.
|
||||
|
||||
```bash
|
||||
# Extraktion in JSON (Standard)
|
||||
bin\translate.bat --filename file.dxf --extract --outname output.json
|
||||
|
||||
# Extraktion in Excel
|
||||
bin\translate.bat --filename file.dxf --extract --export-type excel --outname output.xlsx
|
||||
|
||||
# Extraktion in Textdatei
|
||||
bin\translate.bat --filename file.dxf --extract --export-type text --outname output.txt
|
||||
|
||||
# Mehrere Formate gleichzeitig (komma-separiert)
|
||||
bin\translate.bat --filename file.dxf --extract --export-type excel,json,text --outname output
|
||||
# Erzeugt: output.xlsx, output.json, output.txt
|
||||
|
||||
# Ohne Angabe von --outname: Automatische Namensvergabe
|
||||
bin\translate.bat --filename easy.dxf --extract --export-type excel,json
|
||||
# Erzeugt: easy_texts.xlsx, easy_texts.json
|
||||
|
||||
# Mit Quellsprache (Standard: DE -> TEXT-D)
|
||||
bin\translate.bat --filename file.dxf --extract --lang_source EN
|
||||
```
|
||||
|
||||
**Extrahierte Entitäten:**
|
||||
- TEXT-Objekte im Modellbereich
|
||||
- MTEXT-Objekte im Modellbereich
|
||||
- Block-Attribute (nur Blöcke mit IO, ID, VERW, BEZEICHNUNG, KENNZEICHNUNG)
|
||||
|
||||
### 2. Text-Extraktion mit Übersetzung
|
||||
|
||||
Extrahiert und übersetzt Texte automatisch mittels Übersetzungs-Config.
|
||||
|
||||
```bash
|
||||
# Extraktion mit automatischer Übersetzung nach CS (Tschechisch)
|
||||
bin\translate.bat --filename file.dxf --extract --translate CS --outname output.json
|
||||
|
||||
# Extraktion mit Übersetzung nach EN (Englisch)
|
||||
bin\translate.bat --filename file.dxf --extract --translate EN --export-type excel
|
||||
```
|
||||
|
||||
**Output-Format für eine Sprache (JSON):**
|
||||
```json
|
||||
{
|
||||
"translations": [
|
||||
{"source": "Weight", "target": "Hmotnost"}
|
||||
],
|
||||
"untranslated": [
|
||||
{"source": "Custom text", "target": ""}
|
||||
],
|
||||
"ignored": [
|
||||
"X=123.45",
|
||||
"LAYER=0"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Mehrsprachige Text-Extraktion
|
||||
|
||||
Extrahiert und übersetzt Texte gleichzeitig in mehrere Sprachen mit hierarchischer JSON-Struktur.
|
||||
|
||||
```bash
|
||||
# Extraktion mit mehreren Sprachen (komma-separiert)
|
||||
bin\translate.bat --filename file.dxf --extract --translate CS,EN --outname output.json
|
||||
|
||||
# Drei Sprachen gleichzeitig
|
||||
bin\translate.bat --filename file.dxf --extract --translate CS,EN,FR --export-type json
|
||||
|
||||
# Mit Excel-Export (nur erste Sprache wird in Excel verwendet)
|
||||
bin\translate.bat --filename file.dxf --extract --translate CS,EN --export-type excel,json
|
||||
```
|
||||
|
||||
**Output-Format für mehrere Sprachen (hierarchische JSON-Struktur):**
|
||||
```json
|
||||
{
|
||||
"[CS]": {
|
||||
"translations": [
|
||||
{"source": "Emergency stop", "target": "Nouzové zastavení"},
|
||||
{"source": "Weight", "target": "Hmotnost"}
|
||||
],
|
||||
"untranslated": [
|
||||
{"source": "Custom text", "target": ""}
|
||||
]
|
||||
},
|
||||
"[EN]": {
|
||||
"translations": [
|
||||
{"source": "Emergency stop", "target": "Emergency stop"},
|
||||
{"source": "Weight", "target": "Weight"}
|
||||
],
|
||||
"untranslated": [
|
||||
{"source": "Custom text", "target": ""}
|
||||
]
|
||||
},
|
||||
"ignored": [
|
||||
"X=123.45",
|
||||
"LAYER=0"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 4. DXF-zu-DXF Übersetzung
|
||||
|
||||
Erstellt eine neue DXF-Datei mit übersetzten Texten in mehrsprachigen Attributen.
|
||||
|
||||
```bash
|
||||
# Übersetzung TEXT-D -> TEXT-CS (verwendet automatisch file_texts.json)
|
||||
bin\translate.bat --filename file.dxf --todxf file_cs.dxf --translate CS
|
||||
|
||||
# Mit expliziter JSON-Datei
|
||||
bin\translate.bat --filename file.dxf --todxf output.dxf --translate CS --translation-json custom.json
|
||||
|
||||
# Mit alternativer Quellsprache
|
||||
bin\translate.bat --filename file.dxf --todxf output.dxf --lang_source EN --translate CS
|
||||
```
|
||||
|
||||
**Verhalten:**
|
||||
- **TEXT/MTEXT**: Direkt im Entity übersetzt
|
||||
- **Block-Attribute**:
|
||||
- Liest aus Quell-Attribut (z.B. TEXT-D)
|
||||
- Schreibt in Ziel-Attribut (z.B. TEXT-CS)
|
||||
- Quell-Attribut bleibt unverändert
|
||||
- Erstellt fehlende ATTDEF im Block
|
||||
- Erstellt fehlende Layer (aus `[symbol_layer]`)
|
||||
|
||||
### 5. JSON-Reprocessing
|
||||
|
||||
Übersetzt den `untranslated` Block einer JSON-Datei erneut.
|
||||
|
||||
```bash
|
||||
bin\translate.bat --fromjson output.json --translate CS
|
||||
```
|
||||
|
||||
### 6. JSON Re-Translation
|
||||
|
||||
Re-übersetzt den `translations` Block mit aktualisierter Sprach-Config.
|
||||
|
||||
```bash
|
||||
bin\translate.bat --retranslate-json output.json --translate CS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Umgebungsvariablen
|
||||
|
||||
Das Programm benötigt folgende Umgebungsvariablen (werden in `bin/setenv.bat` gesetzt):
|
||||
|
||||
- `PROJECT_WORK`: Arbeitsverzeichnis für Ein-/Ausgabe-Dateien
|
||||
- `PROJECT_CFG`: Konfigurationsverzeichnis (`cfg/`)
|
||||
- `PROJECT_TRANSLATION`: Übersetzungs-Konfigurationsverzeichnis (`translation/`)
|
||||
|
||||
---
|
||||
|
||||
## Fehlerbehandlung und Ausgabe
|
||||
|
||||
Das Programm gibt detaillierte Statusmeldungen aus:
|
||||
|
||||
```
|
||||
Anzahl gefundener TEXT Objekte: 150
|
||||
Anzahl gefundener MTEXT Objekte: 25
|
||||
Anzahl gefundener TEXT-D in Blöcken: 340
|
||||
Duplikate entfernt: 75
|
||||
Eindeutige Texte extrahiert: 440
|
||||
|
||||
Filterung abgeschlossen:
|
||||
Akzeptierte Texte: 380
|
||||
Ignorierte Texte: 60
|
||||
|
||||
DXF-Übersetzung abgeschlossen:
|
||||
TEXT übersetzt: 140, übersprungen: 10, ignoriert: 0
|
||||
MTEXT übersetzt: 20, übersprungen: 5, ignoriert: 0
|
||||
TEXT-CS (Blöcke) erstellt/aktualisiert: 310, übersprungen: 30, ignoriert: 0
|
||||
Gesamt: 470 übersetzt, 45 übersprungen, 0 ignoriert
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tipps und Hinweise
|
||||
|
||||
- Texte werden als Set verarbeitet → Duplikate werden automatisch entfernt
|
||||
- Leere Texte werden ignoriert
|
||||
- Übersetzungen erfolgen in der Reihenfolge: Multi → Trigramme → Bigramme → Einzelwörter
|
||||
- Bei DXF-zu-DXF Übersetzung bleibt das Original-Attribut immer unverändert
|
||||
- Layer und ATTDEF werden nur bei Bedarf erstellt (lazy creation)
|
||||
- Alle Ausgabedateien landen im `PROJECT_WORK` Verzeichnis
|
||||
- Die `.txt` Ausgabe eignet sich für schnelle Übersicht und Textverarbeitung
|
||||
- Die `.json` Ausgabe wird für DXF-zu-DXF Übersetzung verwendet
|
||||
- Die `.xlsx` Ausgabe eignet sich für externe Übersetzungsdienstleister
|
||||
|
||||
---
|
||||
|
||||
## Anhang A: Python-Modul translate.py
|
||||
|
||||
### Kommandozeilen-Parameter
|
||||
|
||||
#### Eingabe-Modi (mutual exclusive)
|
||||
|
||||
- `--extract` / `-e`: Extrahiere Texte aus DXF/DWG (benötigt `--filename`)
|
||||
- `--fromtxt FILE.txt`: Filtere Texte aus Textdatei
|
||||
- `--fromjson FILE.json`: Re-prozessiere JSON (benötigt `--translate`)
|
||||
- `--retranslate-json FILE.json`: Re-übersetzt translations Block mit aktueller Config (benötigt `--translate`)
|
||||
- `--todxf OUTPUT.dxf`: DXF-zu-DXF Übersetzung (benötigt `--filename`)
|
||||
|
||||
#### Hauptparameter
|
||||
|
||||
- `--filename FILE` / `-f FILE`: Eingabe-DXF/DWG-Datei
|
||||
- `--outname NAME` / `-o NAME`: Name der Ausgabedatei (ohne Endung bei mehreren Formaten)
|
||||
- `--translate LANG`: Übersetzungssprache (CS, EN, FR, etc.) oder mehrere kommasepariert (CS,EN,FR)
|
||||
- `--lang_source LANG`: Quellsprache für Block-Attribute (Standard: DE)
|
||||
- `--export-type TYPE`: Exportformat(e): `json` (Standard), `excel`, `text` oder komma-separiert (z.B. `excel,json,text`)
|
||||
- `--translation-json FILE`: JSON-Datei mit Übersetzungen für `--todxf`
|
||||
- `--debug` / `-d`: Debug-Ausgabe für Pattern-Matching
|
||||
|
||||
### Wichtige Funktionen
|
||||
|
||||
#### extract_text_from_dxf(filename, text_attr_name='TEXT-D')
|
||||
Extrahiert alle TEXT, MTEXT und Block-Attribute aus einer DXF-Datei.
|
||||
|
||||
**Parameter:**
|
||||
- `filename`: Pfad zur DXF-Datei
|
||||
- `text_attr_name`: Name des Text-Attributs in Blöcken (Standard: "TEXT-D")
|
||||
|
||||
**Rückgabe:**
|
||||
- Alphabetisch sortierte Liste aller gefundenen Texte (ohne Duplikate)
|
||||
|
||||
#### filter_texts(texts, wildcard_patterns, regex_patterns, debug=False)
|
||||
Filtert Texte basierend auf Wildcard- und Regex-Mustern.
|
||||
|
||||
**Parameter:**
|
||||
- `texts`: Liste der zu filternden Texte
|
||||
- `wildcard_patterns`: Liste der Wildcard-Muster
|
||||
- `regex_patterns`: Liste der Regex-Muster
|
||||
- `debug`: Debug-Ausgabe aktivieren
|
||||
|
||||
**Rückgabe:**
|
||||
- Tuple mit (akzeptierte Texte, ignorierte Texte)
|
||||
|
||||
#### translate_text(text, multi, trigramme, bigramme, single)
|
||||
Übersetzt einen Text durch Ersetzen von Multi-Phrasen, Trigrammen, Bigrammen und Einzelwörtern.
|
||||
|
||||
**Parameter:**
|
||||
- `text`: Zu übersetzender Text
|
||||
- `multi`: Dictionary mit Multi-Wort-Phrasen
|
||||
- `trigramme`: Dictionary mit Drei-Wort-Phrasen
|
||||
- `bigramme`: Dictionary mit Zwei-Wort-Phrasen
|
||||
- `single`: Dictionary mit Einzelwörtern
|
||||
|
||||
**Rückgabe:**
|
||||
- Übersetzter Text (leer wenn keine Übersetzung gefunden)
|
||||
|
||||
#### translate_dxf_texts(input_dxf, output_dxf, translations, ...)
|
||||
Übersetzt alle TEXT, MTEXT Objekte und Text-Attribute in Blöcken einer DXF-Datei.
|
||||
|
||||
**Parameter:**
|
||||
- `input_dxf`: Pfad zur Quell-DXF
|
||||
- `output_dxf`: Pfad zur Ziel-DXF
|
||||
- `translations`: Dictionary mit source -> target Mappings
|
||||
- `wildcard_patterns`: Wildcard-Muster zum Filtern
|
||||
- `regex_patterns`: Regex-Muster zum Filtern
|
||||
- `text_source_attr`: Quell-Attributname (Standard: "TEXT-D")
|
||||
- `text_target_attr`: Ziel-Attributname (Standard: "TEXT-CS")
|
||||
- `target_layer`: Ziel-Layername für neue Attribute
|
||||
|
||||
#### retranslate_json_file(json_path, translation_dicts_all, translation_languages)
|
||||
Re-übersetzt eine JSON-Datei mit neuen Übersetzungs-Configs.
|
||||
|
||||
**Parameter:**
|
||||
- `json_path`: Pfad zur JSON-Datei
|
||||
- `translation_dicts_all`: Dict mit {LANG: (multi, trigramme, bigramme, single)}
|
||||
- `translation_languages`: Liste der Sprachen
|
||||
|
||||
### Interne Arbeitsweise
|
||||
|
||||
1. **Extraktion**: Texte werden aus DXF gelesen und in einem Set gespeichert (Duplikate werden entfernt)
|
||||
2. **Filterung**: Ignore-Patterns werden angewendet (erst Wildcard, dann Regex)
|
||||
3. **Übersetzung**: Texte werden in der Reihenfolge Multi → Trigramme → Bigramme → Single übersetzt
|
||||
4. **Export**: Ergebnisse werden in gewünschte Formate geschrieben
|
||||
5. **DXF-Übersetzung**: Neue DXF wird mit übersetzten Texten erstellt (Quell-Attribute bleiben erhalten)
|
||||
|
||||
### Block-Attribute und ATTDEF-Erstellung
|
||||
|
||||
Wenn ein Block noch kein ATTDEF für das Ziel-Attribut hat:
|
||||
|
||||
1. **ATTDEF wird erstellt** in der Block-Definition
|
||||
2. **Layer wird erstellt** (falls nicht vorhanden, aus `[symbol_layer]`)
|
||||
3. **Eigenschaften werden übernommen** vom Quell-ATTDEF:
|
||||
- Position (`insert`)
|
||||
- Höhe (`height`)
|
||||
- Stil (`style`)
|
||||
- Rotation (`rotation`)
|
||||
- Layer (aus Config oder vom Quell-Attribut)
|
||||
|
||||
### Erforderliche Block-Attribute
|
||||
|
||||
Blöcke müssen folgende Attribute haben, um verarbeitet zu werden:
|
||||
- `IO`
|
||||
- `ID`
|
||||
- `VERW`
|
||||
- `BEZEICHNUNG`
|
||||
- `KENNZEICHNUNG`
|
||||
- Quell-Textattribut (z.B. `TEXT-D`)
|
||||
|
||||
---
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [CLAUDE.md](../CLAUDE.md) - Allgemeine Projektdokumentation
|
||||
- `cfg/translator.cfg` - Hauptkonfiguration
|
||||
- `translation/*.cfg` - Sprachspezifische Übersetzungs-Configs
|
||||
- `bin/tr2dxf.bat` - Zentrale Batch-Datei für Übersetzungen
|
||||
- `bin/tr2dxf_*.bat` - Sprachspezifische Wrapper-Skripte
|
||||
@@ -0,0 +1,14 @@
|
||||
"""
|
||||
Kabellaengen Library Package
|
||||
|
||||
Dieses Package enthält alle Module für die Kabelrouting-Automatisierung.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Füge das lib Verzeichnis zum Python-Pfad hinzu,
|
||||
# damit relative Imports zwischen den Modulen funktionieren
|
||||
_lib_dir = Path(__file__).parent
|
||||
if str(_lib_dir) not in sys.path:
|
||||
sys.path.insert(0, str(_lib_dir))
|
||||
@@ -0,0 +1,295 @@
|
||||
import ezdxf
|
||||
from ezdxf import colors
|
||||
from ezdxf.enums import TextEntityAlignment
|
||||
import math
|
||||
|
||||
def create_grounding_symbol(filename="erdung.dxf"):
|
||||
"""Erstellt ein Schutzerde-Symbol nach DIN EN 60617"""
|
||||
doc = ezdxf.new('R2010')
|
||||
msp = doc.modelspace()
|
||||
|
||||
# Block erstellen
|
||||
block = doc.blocks.new(name='ERDUNG')
|
||||
|
||||
# Mittelpunkt (relativ zum Block)
|
||||
cx, cy = 0, 0
|
||||
|
||||
# Vertikale Linie (Erdungsleiter)
|
||||
block.add_line((cx, cy + 60), (cx, cy - 20))
|
||||
|
||||
# Drei horizontale Linien (Erdsymbol)
|
||||
# Obere Linie (längste)
|
||||
block.add_line((cx - 40, cy - 20), (cx + 40, cy - 20))
|
||||
# Mittlere Linie
|
||||
block.add_line((cx - 25, cy - 35), (cx + 25, cy - 35))
|
||||
# Untere Linie (kürzeste)
|
||||
block.add_line((cx - 15, cy - 50), (cx + 15, cy - 50))
|
||||
|
||||
# Beschriftung PE
|
||||
block.add_text("PE", dxfattribs={
|
||||
'height': 12,
|
||||
'insert': (cx, cy + 70),
|
||||
'halign': TextEntityAlignment.CENTER
|
||||
})
|
||||
|
||||
# Attribute definieren
|
||||
block.add_attdef(tag='REALE_POSITION', insert=(cx, cy - 70), dxfattribs={
|
||||
'height': 8,
|
||||
'prompt': 'Reale Position:',
|
||||
'default': 'x',
|
||||
'halign': TextEntityAlignment.CENTER,
|
||||
'invisible': 1 # Unsichtbar, nur für Daten
|
||||
})
|
||||
|
||||
block.add_attdef(tag='NAME', insert=(cx, cy - 85), dxfattribs={
|
||||
'height': 10,
|
||||
'prompt': 'Name:',
|
||||
'default': '',
|
||||
'halign': TextEntityAlignment.CENTER
|
||||
})
|
||||
|
||||
block.add_attdef(tag='KENNZEICHNUNG', insert=(cx, cy - 100), dxfattribs={
|
||||
'height': 8,
|
||||
'prompt': 'Kennzeichnung:',
|
||||
'default': '=A01+UH00-X01',
|
||||
'halign': TextEntityAlignment.CENTER,
|
||||
'invisible': 1 # Unsichtbar, nur für Daten
|
||||
})
|
||||
|
||||
# Block-Instanz einfügen
|
||||
msp.add_blockref('ERDUNG', (125, 125))
|
||||
|
||||
doc.saveas(filename)
|
||||
print(f"✓ {filename} erstellt")
|
||||
|
||||
def create_switchboard_symbol(filename="schaltschrank.dxf"):
|
||||
"""Erstellt ein schematisches Schaltschrank-Symbol für Lagepläne"""
|
||||
doc = ezdxf.new('R2010')
|
||||
msp = doc.modelspace()
|
||||
|
||||
# Block erstellen
|
||||
block = doc.blocks.new(name='SCHALTSCHRANK')
|
||||
|
||||
# Mittelpunkt (relativ zum Block)
|
||||
cx, cy = 0, 0
|
||||
|
||||
# Rechteck für Schaltschrank (60x80mm)
|
||||
width, height = 60, 80
|
||||
x1, y1 = cx - width/2, cy - height/2
|
||||
x2, y2 = cx + width/2, cy + height/2
|
||||
|
||||
# Außenrahmen
|
||||
block.add_lwpolyline([
|
||||
(x1, y1), (x2, y1), (x2, y2), (x1, y2), (x1, y1)
|
||||
], dxfattribs={'closed': True})
|
||||
|
||||
# Innere Unterteilung (Fächer)
|
||||
block.add_line((x1, cy - 15), (x2, cy - 15))
|
||||
block.add_line((x1, cy + 15), (x2, cy + 15))
|
||||
|
||||
# Türgriff-Symbol (vertikale Linie links)
|
||||
block.add_line((x1 + 5, cy - 25), (x1 + 5, cy + 25))
|
||||
|
||||
# Beschriftung
|
||||
block.add_text("Schaltschrank", dxfattribs={
|
||||
'height': 10,
|
||||
'insert': (cx, y2 + 15),
|
||||
'halign': TextEntityAlignment.CENTER
|
||||
})
|
||||
|
||||
# Attribute definieren
|
||||
block.add_attdef(tag='REALE_POSITION', insert=(cx, y1 - 15), dxfattribs={
|
||||
'height': 8,
|
||||
'prompt': 'Reale Position:',
|
||||
'default': 'x',
|
||||
'halign': TextEntityAlignment.CENTER,
|
||||
'invisible': 1
|
||||
})
|
||||
|
||||
block.add_attdef(tag='NAME', insert=(cx, y1 - 30), dxfattribs={
|
||||
'height': 10,
|
||||
'prompt': 'Name:',
|
||||
'default': '',
|
||||
'halign': TextEntityAlignment.CENTER
|
||||
})
|
||||
|
||||
block.add_attdef(tag='KENNZEICHNUNG', insert=(cx, y1 - 45), dxfattribs={
|
||||
'height': 8,
|
||||
'prompt': 'Kennzeichnung:',
|
||||
'default': '=A01+UH00-X01',
|
||||
'halign': TextEntityAlignment.CENTER,
|
||||
'invisible': 1
|
||||
})
|
||||
|
||||
# Block-Instanz einfügen
|
||||
msp.add_blockref('SCHALTSCHRANK', (125, 125))
|
||||
|
||||
doc.saveas(filename)
|
||||
print(f"✓ {filename} erstellt")
|
||||
|
||||
def create_subdistribution_symbol(filename="unterverteiler.dxf"):
|
||||
"""Erstellt ein Unterverteiler-Symbol (ähnlich Schaltschrank, kleiner)"""
|
||||
doc = ezdxf.new('R2010')
|
||||
msp = doc.modelspace()
|
||||
|
||||
# Block erstellen
|
||||
block = doc.blocks.new(name='UNTERVERTEILER')
|
||||
|
||||
# Mittelpunkt (relativ zum Block)
|
||||
cx, cy = 0, 0
|
||||
|
||||
# Rechteck für Unterverteiler (45x60mm - kleiner als Schaltschrank)
|
||||
width, height = 45, 60
|
||||
x1, y1 = cx - width/2, cy - height/2
|
||||
x2, y2 = cx + width/2, cy + height/2
|
||||
|
||||
# Außenrahmen
|
||||
block.add_lwpolyline([
|
||||
(x1, y1), (x2, y1), (x2, y2), (x1, y2), (x1, y1)
|
||||
], dxfattribs={'closed': True})
|
||||
|
||||
# Innere Unterteilung (weniger Fächer)
|
||||
block.add_line((x1, cy), (x2, cy))
|
||||
|
||||
# Türgriff-Symbol
|
||||
block.add_line((x1 + 4, cy - 15), (x1 + 4, cy + 15))
|
||||
|
||||
# Beschriftung UV (Unterverteiler)
|
||||
block.add_text("UV", dxfattribs={
|
||||
'height': 12,
|
||||
'insert': (cx, cy),
|
||||
'halign': TextEntityAlignment.CENTER,
|
||||
'valign': TextEntityAlignment.MIDDLE
|
||||
})
|
||||
|
||||
# Zusätzliche Beschriftung
|
||||
block.add_text("Unterverteiler", dxfattribs={
|
||||
'height': 10,
|
||||
'insert': (cx, y2 + 15),
|
||||
'halign': TextEntityAlignment.CENTER
|
||||
})
|
||||
|
||||
# Attribute definieren
|
||||
block.add_attdef(tag='REALE_POSITION', insert=(cx, y1 - 15), dxfattribs={
|
||||
'height': 8,
|
||||
'prompt': 'Reale Position:',
|
||||
'default': 'x',
|
||||
'halign': TextEntityAlignment.CENTER,
|
||||
'invisible': 1
|
||||
})
|
||||
|
||||
block.add_attdef(tag='NAME', insert=(cx, y1 - 30), dxfattribs={
|
||||
'height': 10,
|
||||
'prompt': 'Name:',
|
||||
'default': '',
|
||||
'halign': TextEntityAlignment.CENTER
|
||||
})
|
||||
|
||||
block.add_attdef(tag='KENNZEICHNUNG', insert=(cx, y1 - 45), dxfattribs={
|
||||
'height': 8,
|
||||
'prompt': 'Kennzeichnung:',
|
||||
'default': '=A01+UH00-X01',
|
||||
'halign': TextEntityAlignment.CENTER,
|
||||
'invisible': 1
|
||||
})
|
||||
|
||||
# Block-Instanz einfügen
|
||||
msp.add_blockref('UNTERVERTEILER', (125, 125))
|
||||
|
||||
doc.saveas(filename)
|
||||
print(f"✓ {filename} erstellt")
|
||||
|
||||
def create_motor_symbol(filename="motor.dxf"):
|
||||
"""Erstellt ein allgemeines Motor-Symbol (M im Kreis) nach DIN EN 60617"""
|
||||
doc = ezdxf.new('R2010')
|
||||
msp = doc.modelspace()
|
||||
|
||||
# Block erstellen
|
||||
block = doc.blocks.new(name='MOTOR')
|
||||
|
||||
# Mittelpunkt (relativ zum Block)
|
||||
cx, cy = 0, 0
|
||||
radius = 30
|
||||
|
||||
# Kreis
|
||||
block.add_circle((cx, cy), radius)
|
||||
|
||||
# Buchstabe "M" in der Mitte
|
||||
block.add_text("M", dxfattribs={
|
||||
'height': 25,
|
||||
'insert': (cx, cy),
|
||||
'halign': TextEntityAlignment.CENTER,
|
||||
'valign': TextEntityAlignment.MIDDLE
|
||||
})
|
||||
|
||||
# Anschlussklemmen (drei Linien für Drehstrom - optional)
|
||||
# Oben
|
||||
block.add_line((cx, cy + radius), (cx, cy + radius + 20))
|
||||
# Links unten
|
||||
angle1 = math.radians(210)
|
||||
x1 = cx + radius * math.cos(angle1)
|
||||
y1 = cy + radius * math.sin(angle1)
|
||||
block.add_line((x1, y1), (x1 - 15, y1 - 10))
|
||||
# Rechts unten
|
||||
angle2 = math.radians(330)
|
||||
x2 = cx + radius * math.cos(angle2)
|
||||
y2 = cy + radius * math.sin(angle2)
|
||||
block.add_line((x2, y2), (x2 + 15, y2 - 10))
|
||||
|
||||
# Beschriftung
|
||||
block.add_text("Motor", dxfattribs={
|
||||
'height': 10,
|
||||
'insert': (cx, cy - radius - 25),
|
||||
'halign': TextEntityAlignment.CENTER
|
||||
})
|
||||
|
||||
# Attribute definieren
|
||||
block.add_attdef(tag='REALE_POSITION', insert=(cx, cy - radius - 40), dxfattribs={
|
||||
'height': 8,
|
||||
'prompt': 'Reale Position:',
|
||||
'default': 'x',
|
||||
'halign': TextEntityAlignment.CENTER,
|
||||
'invisible': 1
|
||||
})
|
||||
|
||||
block.add_attdef(tag='NAME', insert=(cx, cy - radius - 55), dxfattribs={
|
||||
'height': 10,
|
||||
'prompt': 'Name:',
|
||||
'default': '',
|
||||
'halign': TextEntityAlignment.CENTER
|
||||
})
|
||||
|
||||
block.add_attdef(tag='KENNZEICHNUNG', insert=(cx, cy - radius - 70), dxfattribs={
|
||||
'height': 8,
|
||||
'prompt': 'Kennzeichnung:',
|
||||
'default': '=A01+UH00-X01',
|
||||
'halign': TextEntityAlignment.CENTER,
|
||||
'invisible': 1
|
||||
})
|
||||
|
||||
# Block-Instanz einfügen
|
||||
msp.add_blockref('MOTOR', (125, 125))
|
||||
|
||||
doc.saveas(filename)
|
||||
print(f"✓ {filename} erstellt")
|
||||
|
||||
# Hauptprogramm
|
||||
if __name__ == "__main__":
|
||||
print("Erstelle DXF Elektrosymbole nach DIN EN 60617 mit Attributen...\n")
|
||||
|
||||
create_grounding_symbol()
|
||||
create_switchboard_symbol()
|
||||
create_subdistribution_symbol()
|
||||
create_motor_symbol()
|
||||
|
||||
print("\n✓ Alle Symbole wurden erfolgreich erstellt!")
|
||||
print("\nDateien:")
|
||||
print(" - erdung.dxf")
|
||||
print(" - schaltschrank.dxf")
|
||||
print(" - unterverteiler.dxf")
|
||||
print(" - motor.dxf")
|
||||
print("\nJedes Symbol ist als Block mit folgenden Attributen definiert:")
|
||||
print(" - REALE_POSITION (Standard: 'x', unsichtbar)")
|
||||
print(" - NAME (Standard: leer, sichtbar unter dem Symbol)")
|
||||
print(" - KENNZEICHNUNG (Standard: '=A01+UH00-X01', unsichtbar)")
|
||||
print("\nDie Attribute können in CAD-Programmen bearbeitet werden.")
|
||||
@@ -0,0 +1,368 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Tests für create_numbers.py Funktionen
|
||||
"""
|
||||
|
||||
import sys
|
||||
sys.stdout.reconfigure(encoding='utf-8')
|
||||
import unittest
|
||||
|
||||
from create_numbers import sort_symbols_by_direction
|
||||
|
||||
def create_test_symbols():
|
||||
"""
|
||||
Erstellt 16 Test-Symbole auf einem 4x4 Raster.
|
||||
|
||||
Raster-Layout (Y-Achse nach oben, wie in DXF üblich):
|
||||
Y=300: (0,300) (100,300) (200,300) (300,300) <- Oben
|
||||
Y=200: (0,200) (100,200) (200,200) (300,200)
|
||||
Y=100: (0,100) (100,100) (200,100) (300,100)
|
||||
Y=0: (0,0) (100,0) (200,0) (300,0) <- Unten
|
||||
X=0 X=100 X=200 X=300
|
||||
^ ^
|
||||
Links Rechts
|
||||
"""
|
||||
symbols = []
|
||||
symbol_id = 1
|
||||
|
||||
# Erstelle 4x4 Raster
|
||||
for y in [0, 100, 200, 300]:
|
||||
for x in [0, 100, 200, 300]:
|
||||
symbols.append({
|
||||
'id': symbol_id,
|
||||
'position': (x, y),
|
||||
'entity': None, # Für den Test nicht benötigt
|
||||
'attributes': {'IO': f'SYM-{symbol_id}@@'},
|
||||
'layer': 'TEST_LAYER'
|
||||
})
|
||||
symbol_id += 1
|
||||
|
||||
return symbols
|
||||
|
||||
class TestEntitySorting(unittest.TestCase):
|
||||
"""Tests for running all combinations of sort_symbols_by_direction."""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
"""Wird einmal vor allen Tests ausgeführt."""
|
||||
print("="*70)
|
||||
print("Test Suite: sort_symbols_by_direction")
|
||||
print("="*70)
|
||||
print()
|
||||
sys.stdout.flush()
|
||||
|
||||
def test_top_bottom_left_right(self):
|
||||
"""
|
||||
Test TOP_BOTTOM/LEFT_RIGHT: Von oben nach unten, in jeder Zeile von links nach rechts
|
||||
"""
|
||||
symbols = create_test_symbols()
|
||||
sorted_symbols = sort_symbols_by_direction(symbols, "TOP_BOTTOM/LEFT_RIGHT")
|
||||
|
||||
# Erwartete Reihenfolge: Zeile Y=300, dann Y=200, dann Y=100, dann Y=0
|
||||
# In jeder Zeile: X=0, X=100, X=200, X=300
|
||||
expected_positions = [
|
||||
(0, 300), (100, 300), (200, 300), (300, 300), # Zeile Y=300 (oben)
|
||||
(0, 200), (100, 200), (200, 200), (300, 200), # Zeile Y=200
|
||||
(0, 100), (100, 100), (200, 100), (300, 100), # Zeile Y=100
|
||||
(0, 0), (100, 0), (200, 0), (300, 0) # Zeile Y=0 (unten)
|
||||
]
|
||||
|
||||
actual_positions = [s['position'] for s in sorted_symbols]
|
||||
|
||||
assert actual_positions == expected_positions, f"Fehler! Erwartet: {expected_positions}, Erhalten: {actual_positions}"
|
||||
|
||||
|
||||
def test_top_bottom_right_left(self):
|
||||
"""
|
||||
Test TOP_BOTTOM/RIGHT_LEFT: Von oben nach unten, in jeder Zeile von rechts nach links
|
||||
"""
|
||||
symbols = create_test_symbols()
|
||||
sorted_symbols = sort_symbols_by_direction(symbols, "TOP_BOTTOM/RIGHT_LEFT")
|
||||
|
||||
# Erwartete Reihenfolge: Zeile Y=300, dann Y=200, dann Y=100, dann Y=0
|
||||
# In jeder Zeile: X=300, X=200, X=100, X=0
|
||||
expected_positions = [
|
||||
(300, 300), (200, 300), (100, 300), (0, 300), # Zeile Y=300 (oben)
|
||||
(300, 200), (200, 200), (100, 200), (0, 200), # Zeile Y=200
|
||||
(300, 100), (200, 100), (100, 100), (0, 100), # Zeile Y=100
|
||||
(300, 0), (200, 0), (100, 0), (0, 0) # Zeile Y=0 (unten)
|
||||
]
|
||||
|
||||
actual_positions = [s['position'] for s in sorted_symbols]
|
||||
|
||||
assert actual_positions == expected_positions, f"Fehler! Erwartet: {expected_positions}, Erhalten: {actual_positions}"
|
||||
|
||||
|
||||
def test_bottom_top_left_right(self):
|
||||
"""
|
||||
Test BOTTOM_TOP/LEFT_RIGHT: Von unten nach oben, in jeder Zeile von links nach rechts
|
||||
"""
|
||||
symbols = create_test_symbols()
|
||||
sorted_symbols = sort_symbols_by_direction(symbols, "BOTTOM_TOP/LEFT_RIGHT")
|
||||
|
||||
# Erwartete Reihenfolge: Zeile Y=0, dann Y=100, dann Y=200, dann Y=300
|
||||
# In jeder Zeile: X=0, X=100, X=200, X=300
|
||||
expected_positions = [
|
||||
(0, 0), (100, 0), (200, 0), (300, 0), # Zeile Y=0 (unten)
|
||||
(0, 100), (100, 100), (200, 100), (300, 100), # Zeile Y=100
|
||||
(0, 200), (100, 200), (200, 200), (300, 200), # Zeile Y=200
|
||||
(0, 300), (100, 300), (200, 300), (300, 300) # Zeile Y=300 (oben)
|
||||
]
|
||||
|
||||
actual_positions = [s['position'] for s in sorted_symbols]
|
||||
|
||||
assert actual_positions == expected_positions, f"Fehler! Erwartet: {expected_positions}, Erhalten: {actual_positions}"
|
||||
|
||||
|
||||
def test_bottom_top_right_left(self):
|
||||
"""
|
||||
Test BOTTOM_TOP/RIGHT_LEFT: Von unten nach oben, in jeder Zeile von rechts nach links
|
||||
"""
|
||||
symbols = create_test_symbols()
|
||||
sorted_symbols = sort_symbols_by_direction(symbols, "BOTTOM_TOP/RIGHT_LEFT")
|
||||
|
||||
# Erwartete Reihenfolge: Zeile Y=0, dann Y=100, dann Y=200, dann Y=300
|
||||
# In jeder Zeile: X=300, X=200, X=100, X=0
|
||||
expected_positions = [
|
||||
(300, 0), (200, 0), (100, 0), (0, 0), # Zeile Y=0 (unten)
|
||||
(300, 100), (200, 100), (100, 100), (0, 100), # Zeile Y=100
|
||||
(300, 200), (200, 200), (100, 200), (0, 200), # Zeile Y=200
|
||||
(300, 300), (200, 300), (100, 300), (0, 300) # Zeile Y=300 (oben)
|
||||
]
|
||||
|
||||
actual_positions = [s['position'] for s in sorted_symbols]
|
||||
|
||||
assert actual_positions == expected_positions, f"Fehler! Erwartet: {expected_positions}, Erhalten: {actual_positions}"
|
||||
|
||||
|
||||
def test_left_right(self):
|
||||
"""
|
||||
Test LEFT_RIGHT: Spaltenweise von links nach rechts
|
||||
"""
|
||||
symbols = create_test_symbols()
|
||||
sorted_symbols = sort_symbols_by_direction(symbols, "LEFT_RIGHT")
|
||||
|
||||
# Spalte für Spalte: X=0, dann X=100, dann X=200, dann X=300
|
||||
# Innerhalb jeder Spalte: Y aufsteigend (0, 100, 200, 300)
|
||||
expected_positions = [
|
||||
(0, 0), (0, 100), (0, 200), (0, 300), # Spalte X=0
|
||||
(100, 0), (100, 100), (100, 200), (100, 300), # Spalte X=100
|
||||
(200, 0), (200, 100), (200, 200), (200, 300), # Spalte X=200
|
||||
(300, 0), (300, 100), (300, 200), (300, 300) # Spalte X=300
|
||||
]
|
||||
|
||||
actual_positions = [s['position'] for s in sorted_symbols]
|
||||
|
||||
assert actual_positions == expected_positions, f"Fehler! Erwartet: {expected_positions}, Erhalten: {actual_positions}"
|
||||
|
||||
|
||||
def test_right_left(self):
|
||||
"""
|
||||
Test RIGHT_LEFT: Spaltenweise von rechts nach links
|
||||
"""
|
||||
symbols = create_test_symbols()
|
||||
sorted_symbols = sort_symbols_by_direction(symbols, "RIGHT_LEFT")
|
||||
|
||||
# Spalte für Spalte: X=300, dann X=200, dann X=100, dann X=0
|
||||
# Innerhalb jeder Spalte: Y aufsteigend (0, 100, 200, 300)
|
||||
expected_positions = [
|
||||
(300, 0), (300, 100), (300, 200), (300, 300), # Spalte X=300
|
||||
(200, 0), (200, 100), (200, 200), (200, 300), # Spalte X=200
|
||||
(100, 0), (100, 100), (100, 200), (100, 300), # Spalte X=100
|
||||
(0, 0), (0, 100), (0, 200), (0, 300) # Spalte X=0
|
||||
]
|
||||
|
||||
actual_positions = [s['position'] for s in sorted_symbols]
|
||||
|
||||
assert actual_positions == expected_positions, f"Fehler! Erwartet: {expected_positions}, Erhalten: {actual_positions}"
|
||||
|
||||
|
||||
def test_top_bottom(self):
|
||||
"""
|
||||
Test TOP_BOTTOM: Default ist TOP_BOTTOM/LEFT_RIGHT
|
||||
"""
|
||||
symbols = create_test_symbols()
|
||||
sorted_symbols = sort_symbols_by_direction(symbols, "TOP_BOTTOM")
|
||||
|
||||
# Sollte identisch mit TOP_BOTTOM/LEFT_RIGHT sein
|
||||
expected_positions = [
|
||||
(0, 300), (100, 300), (200, 300), (300, 300),
|
||||
(0, 200), (100, 200), (200, 200), (300, 200),
|
||||
(0, 100), (100, 100), (200, 100), (300, 100),
|
||||
(0, 0), (100, 0), (200, 0), (300, 0)
|
||||
]
|
||||
|
||||
actual_positions = [s['position'] for s in sorted_symbols]
|
||||
|
||||
assert actual_positions == expected_positions, f"Fehler! Erwartet: {expected_positions}, Erhalten: {actual_positions}"
|
||||
|
||||
|
||||
def test_bottom_top(self):
|
||||
"""
|
||||
Test BOTTOM_TOP: Default ist BOTTOM_TOP/LEFT_RIGHT
|
||||
"""
|
||||
symbols = create_test_symbols()
|
||||
sorted_symbols = sort_symbols_by_direction(symbols, "BOTTOM_TOP")
|
||||
|
||||
# Sollte identisch mit BOTTOM_TOP/LEFT_RIGHT sein
|
||||
expected_positions = [
|
||||
(0, 0), (100, 0), (200, 0), (300, 0),
|
||||
(0, 100), (100, 100), (200, 100), (300, 100),
|
||||
(0, 200), (100, 200), (200, 200), (300, 200),
|
||||
(0, 300), (100, 300), (200, 300), (300, 300)
|
||||
]
|
||||
|
||||
actual_positions = [s['position'] for s in sorted_symbols]
|
||||
|
||||
assert actual_positions == expected_positions, f"Fehler! Erwartet: {expected_positions}, Erhalten: {actual_positions}"
|
||||
|
||||
|
||||
def test_left_right_top_bottom(self):
|
||||
"""
|
||||
Test LEFT_RIGHT/TOP_BOTTOM: Umgekehrte Reihenfolge, identisch mit TOP_BOTTOM/LEFT_RIGHT
|
||||
"""
|
||||
symbols = create_test_symbols()
|
||||
sorted_symbols = sort_symbols_by_direction(symbols, "LEFT_RIGHT/TOP_BOTTOM")
|
||||
|
||||
expected_positions = [
|
||||
(0, 300), (0, 200), (0, 100), (0, 0),
|
||||
(100, 300), (100, 200), (100, 100), (100, 0),
|
||||
(200, 300), (200, 200), (200, 100), (200, 0),
|
||||
(300, 300), (300, 200), (300, 100), (300, 0)
|
||||
]
|
||||
|
||||
actual_positions = [s['position'] for s in sorted_symbols]
|
||||
|
||||
assert actual_positions == expected_positions, f"Fehler! Erwartet: {expected_positions}, Erhalten: {actual_positions}"
|
||||
|
||||
|
||||
def test_right_left_top_bottom(self):
|
||||
"""
|
||||
Test RIGHT_LEFT/TOP_BOTTOM: Umgekehrte Reihenfolge, identisch mit TOP_BOTTOM/RIGHT_LEFT
|
||||
"""
|
||||
symbols = create_test_symbols()
|
||||
sorted_symbols = sort_symbols_by_direction(symbols, "RIGHT_LEFT/TOP_BOTTOM")
|
||||
|
||||
expected_positions = [
|
||||
(300, 300), (300, 200), (300, 100), (300, 0),
|
||||
(200, 300), (200, 200), (200, 100), (200, 0),
|
||||
(100, 300), (100, 200), (100, 100), (100, 0),
|
||||
(0, 300), (0, 200), (0, 100), (0, 0)
|
||||
]
|
||||
|
||||
actual_positions = [s['position'] for s in sorted_symbols]
|
||||
|
||||
assert actual_positions == expected_positions, f"Fehler! Erwartet: {expected_positions}, Erhalten: {actual_positions}"
|
||||
|
||||
|
||||
def test_left_right_bottom_top(self):
|
||||
"""
|
||||
Test LEFT_RIGHT/BOTTOM_TOP: Umgekehrte Reihenfolge, identisch mit BOTTOM_TOP/LEFT_RIGHT
|
||||
"""
|
||||
symbols = create_test_symbols()
|
||||
sorted_symbols = sort_symbols_by_direction(symbols, "LEFT_RIGHT/BOTTOM_TOP")
|
||||
|
||||
expected_positions = [
|
||||
(0, 0), (0, 100), (0, 200), (0, 300),
|
||||
(100, 0), (100, 100), (100, 200), (100, 300),
|
||||
(200, 0), (200, 100), (200, 200), (200, 300),
|
||||
(300, 0), (300, 100), (300, 200), (300, 300),
|
||||
]
|
||||
|
||||
actual_positions = [s['position'] for s in sorted_symbols]
|
||||
|
||||
assert actual_positions == expected_positions, f"Fehler! Erwartet: {expected_positions}, Erhalten: {actual_positions}"
|
||||
|
||||
|
||||
def test_right_left_bottom_top(self):
|
||||
"""
|
||||
Test RIGHT_LEFT/BOTTOM_TOP: Umgekehrte Reihenfolge, identisch mit BOTTOM_TOP/RIGHT_LEFT
|
||||
"""
|
||||
symbols = create_test_symbols()
|
||||
sorted_symbols = sort_symbols_by_direction(symbols, "RIGHT_LEFT/BOTTOM_TOP")
|
||||
|
||||
# Sollte identisch mit BOTTOM_TOP/RIGHT_LEFT sein
|
||||
expected_positions = [
|
||||
(300, 0), (300, 100), (300, 200), (300, 300),
|
||||
(200, 0), (200, 100), (200, 200), (200, 300),
|
||||
(100, 0), (100, 100), (100, 200), (100, 300),
|
||||
(0, 0), (0, 100), (0, 200), (0, 300),
|
||||
]
|
||||
|
||||
actual_positions = [s['position'] for s in sorted_symbols]
|
||||
|
||||
assert actual_positions == expected_positions, f"Fehler! Erwartet: {expected_positions}, Erhalten: {actual_positions}"
|
||||
|
||||
|
||||
def test_fallback(self):
|
||||
"""
|
||||
Test Fallback (unbekannte DIRECTION): Default ist TOP_BOTTOM/LEFT_RIGHT
|
||||
"""
|
||||
symbols = create_test_symbols()
|
||||
sorted_symbols = sort_symbols_by_direction(symbols, "UNKNOWN_DIRECTION")
|
||||
|
||||
# Sollte identisch mit TOP_BOTTOM/LEFT_RIGHT sein
|
||||
expected_positions = [
|
||||
(0, 300), (100, 300), (200, 300), (300, 300),
|
||||
(0, 200), (100, 200), (200, 200), (300, 200),
|
||||
(0, 100), (100, 100), (200, 100), (300, 100),
|
||||
(0, 0), (100, 0), (200, 0), (300, 0)
|
||||
]
|
||||
|
||||
actual_positions = [s['position'] for s in sorted_symbols]
|
||||
|
||||
assert actual_positions == expected_positions, f"Fehler! Erwartet: {expected_positions}, Erhalten: {actual_positions}"
|
||||
|
||||
|
||||
|
||||
|
||||
# print("\n16 Symbole auf 4x4 Raster:")
|
||||
# print(" X-Koordinaten: 0, 100, 200, 300")
|
||||
# print(" Y-Koordinaten: 0, 100, 200, 300")
|
||||
# print("\nUnterstützte Richtungen (beide Reihenfolgen):")
|
||||
# print(" - TOP_BOTTOM/LEFT_RIGHT = LEFT_RIGHT/TOP_BOTTOM")
|
||||
# print(" - TOP_BOTTOM/RIGHT_LEFT = RIGHT_LEFT/TOP_BOTTOM")
|
||||
# print(" - BOTTOM_TOP/LEFT_RIGHT = LEFT_RIGHT/BOTTOM_TOP")
|
||||
# print(" - BOTTOM_TOP/RIGHT_LEFT = RIGHT_LEFT/BOTTOM_TOP")
|
||||
# print("\nEinfache Richtungen:")
|
||||
# print(" - LEFT_RIGHT: Spaltenweise links→rechts (sortiert nach X, dann Y)")
|
||||
# print(" - RIGHT_LEFT: Spaltenweise rechts→links (sortiert nach -X, dann Y)")
|
||||
# print(" - TOP_BOTTOM → TOP_BOTTOM/LEFT_RIGHT (zeilenweise)")
|
||||
# print(" - BOTTOM_TOP → BOTTOM_TOP/LEFT_RIGHT (zeilenweise)")
|
||||
|
||||
# # Test kombinierte Richtungen (Y/X Reihenfolge)
|
||||
# test_top_bottom_left_right()
|
||||
# test_top_bottom_right_left()
|
||||
# test_bottom_top_left_right()
|
||||
# test_bottom_top_right_left()
|
||||
|
||||
# # Test einfache Richtungen
|
||||
# test_left_right()
|
||||
# test_right_left()
|
||||
# test_top_bottom()
|
||||
# test_bottom_top()
|
||||
|
||||
# # Test umgekehrte Reihenfolge (X/Y Reihenfolge)
|
||||
# test_left_right_top_bottom()
|
||||
# test_right_left_top_bottom()
|
||||
# test_left_right_bottom_top()
|
||||
# test_right_left_bottom_top()
|
||||
|
||||
# # Test Fallback
|
||||
# test_fallback()
|
||||
|
||||
|
||||
# print("\n" + "="*70)
|
||||
# print("✓✓✓ ALLE 13 TESTS BESTANDEN ✓✓✓")
|
||||
# print("="*70)
|
||||
# print("\nZusammenfassung:")
|
||||
# print(" - Alle 4 kombinierten Richtungen (Y/X) funktionieren")
|
||||
# print(" - Alle 4 kombinierten Richtungen (X/Y) funktionieren")
|
||||
# print(" - Alle 4 einfachen Richtungen mappen korrekt")
|
||||
# print(" - Fallback funktioniert")
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||