Compare commits

...

5 Commits

Author SHA1 Message Date
m.stangl 40eb51a6fd Erzeugt einen sortierten DataFrame. Bei leerer Liste (z.B. SPS ohne Ausgänge) wird ein leerer DataFrame mit den erwarteten Spalten erzeugt, damit Sortierung und spätere Spaltenzugriffe nicht mit KeyError abbrechen. 2026-10-21 10:31:02 +02:00
s.ayadi 22e9796593 Installtools und Liste der python packages an die neuere Arte der Python installation angepasst 2026-10-20 14:01:33 +02:00
m.schellhammer 79a7d2d750 merge durchgeführt 2026-10-15 10:40:29 +02:00
m.schellhammer 3142a58966 Merge branch 'main' of http://gitea.schoenenberger.de/mistangl/kabellaengen 2026-10-13 11:01:54 +02:00
m.schellhammer a4efd41cc2 ERWEITERT:
929055247 = GETR.MOT. SA57DRN80MK4, M5A, 0,55KW, 50HZ O.BR.
929055170 = GETR.MOT. SA57DRN80MK4, M6B, 0,55KW 50HZ O.BR.
400102555 = Camera DM280 mit Halter (CPC) - BG
929055161 = GETR.MOT. SA57DRN80MK4, M1A,0,55KW, 50HZ, O.BREMSE
610554012 = ENCODER KPL. FÜR CP2100 (WEGEVERFOLGUNG)
2026-10-13 10:52:48 +02:00
12 changed files with 57 additions and 36 deletions
+1
View File
@@ -15,6 +15,7 @@ dist/
downloads/
eggs/
.eggs/
.vscode/settings.json
lib64/
parts/
sdist/
+3 -2
View File
@@ -1,7 +1,8 @@
{
"python.languageServer": "None",
"python.languageServer": "Default",
"cSpell.words": [
"DXFATTRIBS",
"ezdxf"
]
],
"iis.configDir": ""
}
-1
View File
@@ -245,7 +245,6 @@ Key Python packages (see [lib/requirements.txt](lib/requirements.txt)):
- `pandas` - Data manipulation
- `matplotlib` - Graph visualization
- `dacite` - Dataclass conversion utilities
- `PyMuPDF` - PDF processing capabilities
- `pillow` - Image processing (flag/icon generation)
- `pytest` - Testing framework
+6 -1
View File
@@ -19,6 +19,7 @@ REM Namen der Ergebnisdateien
set ERROR_DOUBLE=%FILENAME%_errors.json
set EXCEL_RES=%FILENAME%_cables.xlsx
set DXF_RES=%FILENAME%_cables.dxf
set BOM_RES=%FILENAME%_BOM.xlsx
if exist "%~dp0_setenv.bat" (
echo Lade lokale Umgebungseinstellungen aus _setenv.bat...
@@ -63,8 +64,12 @@ if not exist "%PROJECT_WORK%\%EXCEL_RES%" (
)
echo.
move %PROJECT_WORK%\%FILENAME%_* %TARGET_DIR%
REM nur die eigenen Ergebnisdateien verschieben (kein Wildcard, sonst werden z.B. bei "easy" auch "easy_sps_*" mitgenommen)
for %%f in (%JSON_POS% %JSON_TODRAW% %DXF_RES% %EXCEL_RES% %BOM_RES% %ERROR_DOUBLE%) do (
if exist "%PROJECT_WORK%\%%f" move "%PROJECT_WORK%\%%f" "%TARGET_DIR%"
)
pause
goto :eof
:usage
+12 -5
View File
@@ -1,14 +1,21 @@
call setenv.bat
call "%~dp0setenv.bat"
if "%PROJECT%"=="" (
ECHO FEHLER: PROJECT ist nicht gesetzt!
exit /b 1
)
REM Python 3.12: numpy 1.26 / pandas 2.1 aus requirements.txt gibt es nicht fuer neuere Versionen
if not exist %PROJECT%\.venv (
ECHO Initialisiere Python virtual environment...
py -m venv %PROJECT%\.venv --upgrade-deps
uv venv %PROJECT%\.venv --python 3.12 || exit /b 1
ECHO Erfolgreich.
call %PROJECT%\.venv\Scripts\activate.bat
ECHO Installiere erforderliche Python Packages...
pip install -r %PROJECT_LIB%/requirements.txt -q
uv pip install --python %PROJECT%\.venv -r %PROJECT_LIB%/requirements.txt -q || (
ECHO FEHLER: Installation fehlgeschlagen, entferne .venv
rmdir /s /q %PROJECT%\.venv
exit /b 1
)
ECHO Erfolgreich
deactivate
) ELSE (
ECHO Erforderliche Python Packages bereits installiert!
+8 -5
View File
@@ -2,16 +2,19 @@
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/setenv.sh"
# Python 3.12: numpy 1.26 / pandas 2.1 aus requirements.txt gibt es nicht fuer neuere Versionen
if [ ! -d "$PROJECT/.venv" ]; then
echo "Initialisiere Python virtual environment..."
python3 -m venv "$PROJECT/.venv" --upgrade-deps
uv venv "$PROJECT/.venv" --python 3.12 || exit 1
echo "Erfolgreich."
source "$PROJECT/.venv/bin/activate"
echo "Installiere erforderliche Python Packages..."
pip install -r "$PROJECT_LIB/requirements.txt" -q
if ! uv pip install --python "$PROJECT/.venv" -r "$PROJECT_LIB/requirements.txt" -q; then
echo "FEHLER: Installation fehlgeschlagen, entferne .venv"
rm -rf "$PROJECT/.venv"
exit 1
fi
echo "Erfolgreich"
deactivate
else
echo "Erforderliche Python Packages bereits installiert!"
fi
+2 -1
View File
@@ -25,7 +25,8 @@ 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
REM Kann vorab gesetzt werden (z.B. von run_tests.py), damit Testergebnisse in work bleiben
if not defined PROJECT_BOM_RESULTS set PROJECT_BOM_RESULTS=Z:\Automatisierung\Konvertierungstools\3_Kabellaengen-Konvertierer
set INSTALL_DIR="%ONEDRIVE%\Desktop\Kabeltool"
if exist "%~dp0_setenv.bat" (
+1 -2
View File
@@ -205,7 +205,6 @@
827072015 = STATISCHE TROLLEYABFRAGE L=200 FÜR AP110
929055247 = GETR.MOT. SA57DRN80MK4, M5A, 0,55KW, 50HZ O.BR.
929055170 = GETR.MOT. SA57DRN80MK4, M6B, 0,55KW 50HZ O.BR.
400102555 = Camera DM280 mit Halter (CPC) - BG
929055161 = GETR.MOT. SA57DRN80MK4, M1A,0,55KW, 50HZ, O.BREMSE
610554012 = ENCODER KPL. FÜR CP2100 (WEGEVERFOLGUNG)
400102555 = Camera DM280 mit Halter (CPC) - BG
+19 -6
View File
@@ -10,6 +10,16 @@ class ExcelConverter:
self.eingaenge_identifier = ["FDI", "B", "S", "E", "I", "DI", "BA", "BB", "BC", "BD", "BE", "BF", "BG", "BH", "BJ", "BK", "BL", "BM", "BN", "BP", "BQ", "BR", "BS", "BT", "BU", "BV", "BW", "BX", "BY", "BZ", "FA", "FB", "FC", "FD", "FE", "FF", "FG", "FH", "FJ", "FK", "FL", "FM", "FN", "FP", "FQ", "FR", "FS", "FT", "FU", "FV", "FW", "FX", "FY", "FZ", "SA", "SB", "SC", "SD", "SE", "SF", "SG", "SH", "SJ", "SK", "SL", "SM", "SN", "SP", "SQ", "SR", "SS", "ST", "SU", "SV", "SW", "SX", "SY", "SZ"]
self.ausgaenge_identifier = ["K", "O", "Q", "M", "A", "P", "DQ", "CA", "CB", "CC", "CD", "CE", "CF", "CG", "CH", "CJ", "CK", "CL", "CM", "CN", "CP", "CQ", "CR", "CS", "CT", "CU", "CV", "CW", "CX", "CY", "CZ", "EA", "EB", "EC", "ED", "EE", "EF", "EG", "EH", "EJ", "EK", "EL", "EM", "EN", "EP", "EQ", "ER", "ES", "ET", "EU", "EV", "EW", "EX", "EY", "EZ", "GA", "GB", "GC", "GD", "GE", "GF", "GG", "GH", "GJ", "GK", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GV", "GW", "GX", "GY", "GZ", "HA", "HB", "HC", "HD", "HE", "HF", "HG", "HH", "HJ", "HK", "HL", "HM", "HN", "HP", "HQ", "HR", "HS", "HT", "HU", "HV", "HW", "HX", "HY", "HZ", "KA", "KB", "KC", "KD", "KE", "KF", "KG", "KH", "KJ", "KK", "KL", "KM", "KN", "KP", "KQ", "KR", "KS", "KT", "KU", "KV", "KW", "KX", "KY", "KZ", "MA", "MB", "MC", "MD", "ME", "MF", "MG", "MH", "MJ", "MK", "ML", "MM", "MN", "MP", "MQ", "MR", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "PA", "PB", "PC", "PD", "PE", "PF", "PG", "PH", "PJ", "PK", "PL", "PM", "PN", "PP", "PQ", "PR", "PS", "PT", "PU", "PV", "PW", "PX", "PY", "PZ", "QA", "QB", "QC", "QD", "QE", "QF", "QG", "QH", "QJ", "QK", "QL", "QM", "QN", "QP", "QQ", "QR", "QS", "QT", "QU", "QV", "QW", "QX", "QY", "QZ", "RA", "RB", "RC", "RD", "RE", "RF", "RG", "RH", "RJ", "RK", "RL", "RM", "RN", "RP", "RQ", "RR", "RS", "RT", "RU", "RV", "RW", "RX", "RY", "RZ", "TA", "TB", "TC", "TD", "TE", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TP", "TQ", "TR", "TS", "TT", "TU", "TV", "TW", "TX", "TY", "TZ"]
def _sortierter_df(self, eintraege, sortierung, spalten):
"""
Erzeugt einen sortierten DataFrame. Bei leerer Liste (z.B. SPS ohne Ausgänge)
wird ein leerer DataFrame mit den erwarteten Spalten erzeugt, damit Sortierung
und spätere Spaltenzugriffe nicht mit KeyError abbrechen.
"""
if not eintraege:
return pd.DataFrame(columns=spalten)
return pd.DataFrame(eintraege).sort_values(by=sortierung)
def _gleiche_finden(self, liste):
counter = {}
for eintrag in liste:
@@ -147,8 +157,9 @@ class ExcelConverter:
gleiche_ausgaenge, ausgaenge = self._verarbeite_io_liste(ausgaenge)
# DataFrames erzeugen u. sortieren
df_eingaenge = pd.DataFrame(eingaenge).sort_values(by="Name")
df_ausgaenge = pd.DataFrame(ausgaenge).sort_values(by="Name")
spalten = ['Name', 'Kommentar', 'Zeile']
df_eingaenge = self._sortierter_df(eingaenge, "Name", spalten)
df_ausgaenge = self._sortierter_df(ausgaenge, "Name", spalten)
df_gleiche_eingaenge = pd.DataFrame(gleiche_eingaenge).sort_values(by="Name") if gleiche_eingaenge else pd.DataFrame()
df_gleiche_ausgaenge = pd.DataFrame(gleiche_ausgaenge).sort_values(by="Name") if gleiche_ausgaenge else pd.DataFrame()
@@ -218,8 +229,9 @@ class ExcelConverter:
gleiche_ausgaenge, ausgaenge = self._verarbeite_io_liste(ausgaenge)
# DataFrames erstellen u. sortieren
df_eingaenge = pd.DataFrame(eingaenge).sort_values(by="Zahl")
df_ausgaenge = pd.DataFrame(ausgaenge).sort_values(by="Zahl")
spalten = ['Name', 'NameOriginal', 'NameConstant', 'Kommentar', 'Zahl', 'Zeile']
df_eingaenge = self._sortierter_df(eingaenge, "Zahl", spalten)
df_ausgaenge = self._sortierter_df(ausgaenge, "Zahl", spalten)
df_gleiche_eingaenge = pd.DataFrame(gleiche_eingaenge).sort_values(by="Zahl") if gleiche_eingaenge else pd.DataFrame()
df_gleiche_ausgaenge = pd.DataFrame(gleiche_ausgaenge).sort_values(by="Zahl") if gleiche_ausgaenge else pd.DataFrame()
@@ -362,8 +374,9 @@ class ExcelConverter:
gleiche_ausgaenge, ausgaenge = self._verarbeite_io_liste(ausgaenge)
# DataFrames erzeugen u. sortieren
df_eingaenge = pd.DataFrame(eingaenge).sort_values(by="Name")
df_ausgaenge = pd.DataFrame(ausgaenge).sort_values(by="Name")
spalten = ['Name', 'Kommentar', 'Zeile', 'Bezug']
df_eingaenge = self._sortierter_df(eingaenge, "Name", spalten)
df_ausgaenge = self._sortierter_df(ausgaenge, "Name", spalten)
df_gleiche_eingaenge = pd.DataFrame(gleiche_eingaenge).sort_values(by="Name") if gleiche_eingaenge else pd.DataFrame()
df_gleiche_ausgaenge = pd.DataFrame(gleiche_ausgaenge).sort_values(by="Name") if gleiche_ausgaenge else pd.DataFrame()
+1 -1
View File
@@ -118,7 +118,7 @@ def do_export(conv_obj:ExcelConverter, mode_str, base_input, output_dir, lines,
conv_obj.export_excel(lines, export_type, export_path, getpos_errors, getpos_warnings)
print(f"Export '{export_type}' erfolgreich: {export_path}")
except Exception as e:
print(f"Fehler bei Export '{export_type}': {e}")
print(f"Fehler bei Export '{export_type}' ({export_path}): {type(e).__name__}: {e}")
def do_exports(converter, export_mode, output_dir, base_input, lines, getpos_errors=None, getpos_warnings=None):
if export_mode:
-11
View File
@@ -1,10 +1,7 @@
build==1.2.2.post1
click==8.1.8
colorama==0.4.6
contourpy==1.3.1
cycler==0.12.1
dacite==1.9.2
dataclasses==0.6
et-xmlfile==1.1.0
ezdxf==1.4.1
fonttools==4.57.0
@@ -17,21 +14,13 @@ openpyxl==3.1.2
packaging==24.2
pandas==2.1.1
pillow==11.1.0
pip-tools==7.4.1
pluggy==1.6.0
Pygments==2.19.2
PyMuPDF==1.25.5
pyparsing==3.2.3
pyproject_hooks==1.2.0
pytest==9.0.2
python-dateutil==2.8.2
pytz==2023.3.post1
setuptools==80.0.0
shapely==2.1.0
shiboken6==6.9.0
six==1.16.0
snakeviz==2.2.2
tornado==6.5.1
typing_extensions==4.13.1
tzdata==2023.3
wheel==0.45.1
+4 -1
View File
@@ -74,8 +74,11 @@ class TestRunner:
# Execute getexdraw.bat with automated input to handle pause
cmd = [str(self.getexdraw_bat), str(dxf_file)]
# Ergebnisse in work statt im produktiven Netzlaufwerk ablegen
env = os.environ.copy()
env['PROJECT_BOM_RESULTS'] = str(self.work_dir)
# Send newline to handle the pause command
result = subprocess.run(cmd, capture_output=True, text=True, shell=True, input="\n")
result = subprocess.run(cmd, capture_output=True, text=True, shell=True, input="\n", env=env)
# Check if the expected output files were created instead of relying on return code
# The batch script always exits with code 1 due to interactive design, but files are created