From 2009eb1a2c6e74ae8cb4a9a25eb2fb10283aa245 Mon Sep 17 00:00:00 2001 From: Michael Stangl Date: Tue, 30 Jun 2026 11:04:50 +0200 Subject: [PATCH] =?UTF-8?q?Readme=20der=20lisp=20Tests=20aktualisiert.=20F?= =?UTF-8?q?oerderer=20Tests=20korrigiert.=20Flaches=20.json=20ben=C3=B6tig?= =?UTF-8?q?t.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/LispTests.md | 404 +++++++++++++++------------- tests/test_foerderer.lsp | 17 +- tests/testdata/foerderer_tests.json | 88 +++++- 3 files changed, 305 insertions(+), 204 deletions(-) diff --git a/doc/LispTests.md b/doc/LispTests.md index 840707c..7803cdb 100644 --- a/doc/LispTests.md +++ b/doc/LispTests.md @@ -5,234 +5,281 @@ Die SSG_LIB AutoLISP-Makros werden ueber einen zweistufigen Hybrid-Ansatz getestet: 1. **AutoLISP** (in BricsCAD): Liest JSON-Testfaelle, fuehrt die Funktionen aus, - schreibt Ergebnisse als JSON und DXF. + schreibt Ergebnisse als JSON und DXF/DWG. 2. **Python** (pytest + ezdxf): Validiert die Ergebnisse automatisch gegen - erwartete Werte und optionale Referenz-DXFs. + erwartete Werte und optionale Referenzdaten. -``` +```text Python (pytest) AutoLISP (BricsCAD) Python (pytest) =============== ==================== =============== Testfall-Definitionen --> Ausfuehrung der --> Validierung: als JSON bereitstellen LISP-Funktionen - JSON-Ergebnisse - + DXF + results.json - DXF-Geometrie + + DXF/DWG + results.json - DXF-Geometrie - Referenz-Vergleich ``` ## Verzeichnisstruktur -``` +```text tests/ -├── testdata/ # JSON-Testfall-Definitionen (versioniert) -│ ├── kreisel_tests.json -│ ├── vario_tests.json -│ └── omniflo_tests.json -├── reference/ # Abgenommene Referenz-DXFs (versioniert) -│ └── kreisel_ref.dxf -├── output/ # Generierte Ergebnisse (in .gitignore) -│ ├── kreisel_tests.dxf -│ └── kreisel_results.json -├── ssg_testrunner.lsp # LISP Test-Runner +├── alltests.json # Zentrale Testregistry (welche Module + Speicherformat) +├── test_run_all.lsp # C:SSG_RUN_ALL_TESTS - fuehrt alle Tests aus +├── test_kreisel.lsp # C:TEST_KREISEL - Kreisel-Testrunner +├── test_foerderer.lsp # C:TEST_FOERDERER - Variofoerderer-Testrunner +├── test_kseinaus.lsp # C:TEST_KSEINAUS - KreiselEinAus-Testrunner +├── test_omniflo.lsp # C:TEST_OMNIFLO - Omniflo-Testrunner ├── conftest.py # pytest Fixtures ├── test_kreisel.py # pytest Kreisel-Validierung -├── test_vario.py # pytest Vario-Validierung ├── test_omniflo.py # pytest Omniflo-Validierung -└── requirements.txt # Python-Abhaengigkeiten (ezdxf, pytest) +├── create_testbase.py # Hilfsskript (optional, i.d.R. nicht benoetigt) +├── requirements.txt # Python-Abhaengigkeiten (ezdxf, pytest) +├── testdata/ # JSON-Testfall-Definitionen (versioniert) +│ ├── kreisel_tests.json +│ ├── foerderer_tests.json +│ └── omniflo_tests.json +├── reference/ # Abgenommene Referenzdaten (versioniert) +│ └── omniflo_export_reference.csv +└── output/ # Generierte Ergebnisse (nicht in Git) + ├── kreisel_results.json + ├── kreisel_tests.dxf + ├── foerderer_results.json + ├── foerderer_tests.dwg + ├── kseinaus_results.json + ├── omniflo_results.json + ├── omniflo_tests.dxf + └── omniflo_export.csv ``` +## Testregistry (alltests.json) + +Die Datei `tests/alltests.json` ist die zentrale Registry aller Testmodule. +`SSG_RUN_ALL_TESTS` liest sie beim Start — die Testliste ist nicht hartcodiert. + +```json +[ + { "name": "kreisel", "save": "dxf", "module": "KreiselInsert" }, + { "name": "foerderer", "save": "dwg", "module": "VarioFoerderer" }, + { "name": "kseinaus", "save": null, "module": "VarioFoerderer" }, + { "name": "omniflo", "save": "dxf", "module": "OmniModulInsert" } +] +``` + +| Feld | Typ | Bedeutung | +| --- | --- | --- | +| `name` | String | Basisname des Testmoduls (Pflicht) | +| `save` | `"dxf"` / `"dwg"` / `null` | Speicherformat der Zeichnung | +| `module` | String | LISP-Modul (wird von ssg-ensure geladen) | + +Aus dem `name` werden alle Dateinamen abgeleitet: + +| Element | Schema | Beispiel (`kreisel`) | +| --- | --- | --- | +| LISP-Datei | `tests/test_.lsp` | `tests/test_kreisel.lsp` | +| BricsCAD-Befehl | `TEST_` | `TEST_KREISEL` | +| Export-Funktion | `:export-results` | `kreisel:export-results` | +| JSON-Ergebnis | `output/_results.json` | `output/kreisel_results.json` | +| DXF/DWG-Datei | `output/_tests.dxf/.dwg` | `output/kreisel_tests.dxf` | + ## Schritt 1: Testfaelle definieren (JSON) -Jedes Modul hat eine eigene JSON-Datei in `tests/testdata/`. Aufbau: +Jedes Modul hat eine eigene JSON-Datei in `tests/testdata/`. Format: **flaches JSON-Array** +(kompatibel mit `omni:load-json`). Kein Nesting, keine Wrapper-Objekte. + +### Kreisel-Format (kreisel_tests.json) ```json -{ - "module": "Kreisel", - "version": "1.0", - "description": "ILS Kreisel Testfaelle", - "tests": [ - { - "id": "KR_Horiz_ObenUnten", - "function": "draw-module", - "params": { - "basepoint": [500.0, 5000.0, 2500.0], - "abstand": 4200.0, - "rotation": 270.0, - "attribs": { - "KREISELART": "STANDARD", - "NAME": "TEST_H_ObenUnten" - } - }, - "expect": { - "attributes": { - "KREISELART": "STANDARD", - "DREHUNG": "270", - "ABSTAND": "4200" - }, - "block_prefix": "KR_", - "min_entities": 6 - } - } - ] -} +[ + { + "id": "KR_Kreuz_Q1_0Grad", + "function": "insert", + "x": 500, "y": 500, "z": 2500, + "abstand": 2000, + "rotation": 0.0, + "typ": "STANDARD", + "expect_block_prefix": "KREISEL_", + "expect_hoehe": "2500", + "expect_kreiselart": "STANDARD" + } +] ``` -### Felder +Felder: -| Feld | Beschreibung | -|---|---| -| `id` | Eindeutiger Testfall-Name | -| `function` | Aufzurufende LISP-Funktion | -| `params` | Uebergabewerte an die Funktion | -| `expect.attributes` | Erwartete Block-Attribute nach Ausfuehrung | -| `expect.block_prefix` | Erwartetes Praefix des erzeugten Block-Namens | -| `expect.min_entities` | Mindestanzahl Entities im erzeugten Block | +- `id` — Eindeutiger Testfall-Name +- `function` — `"insert"` oder `"connect"` +- Eingabeparameter: `x`, `y`, `z`, `abstand`, `rotation`, `typ` +- `expect_*` — Erwartete Ergebniswerte (fuer Python-Validierung) -## Schritt 2: LISP Test-Runner (ssg_testrunner.lsp) +### Foerderer-Format (foerderer_tests.json) -Der LISP Test-Runner liest die JSON-Testfaelle, fuehrt die Funktionen in -BricsCAD aus und schreibt die Ergebnisse. - -### Aufruf in BricsCAD - -``` -Command: TESTRUN "kreisel" +```json +[ + { "y_abstand": 400 }, + { + "test_id": "VF_Auf_0", + "richtung": "Auf", + "deltaL": 7000, + "deltaH": 0 + } +] ``` -Der Befehl: -1. Liest `tests/testdata/kreisel_tests.json` -2. Erstellt eine neue leere Zeichnung -3. Fuehrt fuer jeden Testfall die angegebene Funktion mit den Parametern aus -4. Sammelt Ergebnisse: Block-Handle, tatsaechliche Attribute, Insertionspunkt -5. Schreibt `tests/output/kreisel_results.json` -6. Speichert die Zeichnung als `tests/output/kreisel_tests.dxf` +- Erster Eintrag (ohne `test_id`): Konfiguration (`y_abstand` zwischen Foerderern) +- Felder: `test_id`, `richtung` (`"Auf"` / `"Ab"`), `deltaL`, `deltaH` +- Ergebnisstatus: `GEBAUT`, `NICHT_GEBAUT`, `GEOMETRISCH_UNMOEGLICH` + +### Omniflo-Format (omniflo_tests.json) + +```json +[ + { + "id": "821104025", + "type": "bogen", + "sivasnr": "821104025", + "x": 219.4, "y": 223.06, + "hoehe": 2000, + "drehung": 0.0, + "description": "APB 110 R 550/22,5 – 84/522", + "row": "Boegen 22.5" + } +] +``` + +## Schritt 2: LISP-Testrunner ausfuehren (BricsCAD) + +### Alle Tests auf einmal + +```lisp +(load (strcat (getenv "DXFMAKRO") "/tests/test_run_all.lsp")) +SSG_RUN_ALL_TESTS +``` + +`SSG_RUN_ALL_TESTS` liest `alltests.json` und fuehrt fuer jedes Modul aus: + +1. Zeichnung leeren (ERASE ALL + PURGE x5) +2. `test_.lsp` laden und `TEST_` ausfuehren +3. JSON-Export: `:export-results` aufrufen (immer) +4. Zeichnung speichern gemaess `save`-Feld (`"dxf"`, `"dwg"` oder kein Speichern) +5. Bei Fehler: weiter mit naechstem Test (Fehlerisolation) + +### Einzeltest (z.B. nur Kreisel) + +```lisp +(load (strcat (getenv "DXFMAKRO") "/tests/test_kreisel.lsp")) +TEST_KREISEL +(kreisel:export-results (strcat (getenv "DXFMAKRO") "/tests/output")) +``` ### Ausgabe: results.json ```json [ { - "test_id": "KR_Horiz_ObenUnten", - "status": "executed", - "block_handle": "A3F", - "block_name": "KR_STANDARD_01", - "insert_point": [500.0, 5000.0, 2500.0], - "rotation": 270.0, - "actual_attributes": { - "KREISELART": "STANDARD", - "DREHUNG": "270", - "ABSTAND": "4200", - "NAME": "TEST_H_ObenUnten" - } + "test_id": "KR_Kreuz_Q1_0Grad", + "status": "GEBAUT", + "block_name": "KREISEL_STANDARD", + "insert_point": [500.0, 500.0, 2500.0], + "rotation": 0.0, + "actual_kreiselart": "STANDARD", + "actual_hoehe": "2500" } ] ``` ## Schritt 3: Python-Validierung (pytest) -Die Python-Tests lesen `results.json` und die erzeugte DXF-Datei und pruefen: +```cmd +bin\run_tests.bat --runall +``` -### 3a. Attribut-Pruefung (results.json) +Oder einzelnes Testmodul: -Vergleicht `actual_attributes` aus results.json gegen `expect.attributes` -aus den Testdefinitionen. Keine BricsCAD-Instanz noetig. +```cmd +bin\run_tests.bat --runall test_kreisel.py +``` -### 3b. Geometrie-Pruefung (ezdxf) +### test_kreisel.py -Oeffnet die erzeugte DXF-Datei mit der Python-Bibliothek `ezdxf` und prueft: +| Klasse | Prueft | +| --- | --- | +| `TestKreiselAttributes` | Attribute (KREISELART, HOEHE), Block-Prefixe, Status | +| `TestKreiselGeometry` | DXF-Bloecke, Positionen, Kreis-Radien (400mm) | +| `TestKreiselReference` | Block-Anzahl und -Typen gegen Referenz-DXF | -- **Block-Existenz**: Alle erwarteten Bloecke im Modelspace vorhanden -- **Entity-Anzahl**: Mindestanzahl Entities pro Block -- **Kreisradien**: AN8/SP8-Kreise haben korrekten Radius (400mm) -- **Linienlaengen**: Tangenten haben korrekte Laenge (= Abstand) -- **Layer-Zuordnung**: Entities auf korrektem Layer -- **Insertionspunkte**: Bloecke an erwarteter Position +### test_omniflo.py -### 3c. Referenz-Vergleich +| Klasse | Prueft | +| --- | --- | +| `TestOmnifloExportUnit` | Mock-Export: Merkmale, Datentypen, Vollstaendigkeit (ohne BricsCAD) | +| `TestOmnifloExportCSV` | CSV aus BricsCAD: Header, Spalten, JSON-Merkmale | -Vergleicht die Ergebnis-DXF gegen eine abgenommene Referenz-DXF: - -- Gleiche Anzahl Bloecke im Modelspace -- Gleiche Block-Typen -- Gleiche Attributwerte +Tests, deren Eingabedaten fehlen (kein BricsCAD-Lauf), werden automatisch +uebersprungen (`pytest.skip`). ## Schritt 4: Referenz-Management -### Neue Referenz erstellen (erster Lauf oder nach Aenderung) - -```bash -# 1. Tests in BricsCAD ausfuehren -# Command: TESTRUN "kreisel" - -# 2. Ergebnis-DXF visuell pruefen (in BricsCAD oeffnen) - -# 3. Wenn OK: Als neue Referenz speichern -copy tests\output\kreisel_tests.dxf tests\reference\kreisel_ref.dxf +```cmd +# Aktuelle Ergebnisse als neue Referenz speichern +bin\run_tests.bat --set-as-reference ``` -### Referenz aktualisieren +Kopiert alle Dateien aus `output/` nach `reference/`. Nur bei bestandenen Tests verwenden. -Wenn sich die LISP-Logik aendert und die neuen Ergebnisse korrekt sind: +## Modulspezifische Testfaelle -```bash -# 1. Tests in BricsCAD ausfuehren -# 2. Ergebnis visuell pruefen -# 3. Python-Tests zeigen Referenz-Abweichung: -pytest tests/test_kreisel.py -v -# FAILED test_block_count_matches_reference - 6 != 5 +### Kreisel (kreisel_tests.json) -# 4. Neue Referenz speichern -copy tests\output\kreisel_tests.dxf tests\reference\kreisel_ref.dxf +| Test-ID | Beschreibung | Params | +| --- | --- | --- | +| KR_Kreuz_Q1_0Grad | Standard Kreisel, 0 Grad | rot=0, z=2500, abstand=2000 | +| KR_Kreuz_Q2_90Grad | Standard Kreisel, 90 Grad | rot=90, z=2500, abstand=3000 | +| KR_Kreuz_Q3_180Grad | Standard Kreisel, 180 Grad | rot=180, z=2500, abstand=4000 | +| KR_Kreuz_Q4_270Grad | Standard Kreisel, 270 Grad | rot=270, z=2500, abstand=5000 | +| KR_Schraeg_Q1_30Grad | Standard Kreisel, schraeg | rot=30, z=3000, abstand=3000 | +| KR_Pin_Q1_0Grad | Pin-Kreisel, 0 Grad | rot=0, typ=PIN, z=1500 | +| KR_Pin_Q1_90Grad | Pin-Kreisel, 90 Grad | rot=90, typ=PIN, z=1500 | +| KR_Pin_Q1_30Grad_Schraeg | Pin-Kreisel, schraeg | rot=30, typ=PIN, z=1500 | -# 5. Tests erneut ausfuehren - jetzt PASS -pytest tests/test_kreisel.py -v -``` +### Foerderer (foerderer_tests.json) -## Ausfuehrung +| Test-ID | Richtung | deltaL | deltaH | +| --- | --- | --- | --- | +| VF_Auf_0 | Auf | 7000 | 0 | +| VF_Auf_1000 | Auf | 7000 | 1000 | +| VF_Auf_2000 | Auf | 7000 | 2000 | +| VF_Auf_3000 | Auf | 7000 | 3000 | +| VF_Auf_4000 | Auf | 7000 | 4000 | +| VF_Auf_5000 | Auf | 7000 | 5000 | +| VF_Ab_0 | Ab | 7000 | 0 (GEOMETRISCH_UNMOEGLICH) | +| VF_Ab_1000 | Ab | 7000 | 1000 | +| VF_Ab_2000 | Ab | 7000 | 2000 | +| VF_Ab_3000 | Ab | 7000 | 3000 | +| VF_Ab_4000 | Ab | 7000 | 4000 | +| VF_Ab_5000 | Ab | 7000 | 5000 | -### Kompletter Testlauf +### Omniflo (omniflo_tests.json) -```bash -# Umgebung setzen -bin\setenv.bat - -# 1. Testdaten-DXF erzeugen (Python, optional wenn Basis-DXF benoetigt) -python tests/create_testbase.py - -# 2. BricsCAD starten und Tests ausfuehren -# In BricsCAD: TESTRUN "kreisel" -# In BricsCAD: TESTRUN "vario" -# In BricsCAD: TESTRUN "omniflo" - -# 3. Python-Validierung -pytest tests/ -v -``` - -### Nur Python-Validierung (ohne BricsCAD) - -```bash -# Setzt voraus, dass output/ bereits erzeugt wurde -pytest tests/ -v -``` - -### Einzelnes Modul testen - -```bash -pytest tests/test_kreisel.py -v -``` +Testfaelle basieren auf echten Sivas-Nummern (Boegen und Zusatzmodule). +Beispiele: `821104025`, `821104025+0_B10090`, `821104025+0_B10091`, ... ## Umgebungsvariablen -| Variable | Pfad | Beschreibung | -|---|---|---| -| `DXFM_TESTS` | `/tests` | Test-Wurzelverzeichnis | -| `DXFM_TESTDATA` | `/tests/testdata` | JSON-Testdefinitionen | -| `DXFM_TESTOUT` | `/tests/output` | Generierte Ergebnisse | -| `DXFM_TESTREF` | `/tests/reference` | Abgenommene Referenzen | +Werden via `bin\setenv.bat` gesetzt. Fuer Tests relevant: + +| Variable | Beschreibung | +| --- | --- | +| `DXFMAKRO` | Projektwurzel | +| `DXFM_TESTS` | tests/-Verzeichnis | +| `DXFM_TESTDATA` | testdata/-Verzeichnis | +| `DXFM_TESTOUT` | output/-Verzeichnis | +| `DXFM_TESTREF` | reference/-Verzeichnis | +| `DXFM_OMNIFLO` | Pfad zu Omniflo-DXF-Dateien | ## Abhaengigkeiten ### Python (tests/requirements.txt) -``` +```text ezdxf>=1.0 pytest>=7.0 ``` @@ -240,34 +287,13 @@ pytest>=7.0 ### AutoLISP - SSG_LIB muss geladen sein (Menue per `_MENULOAD` eingerichtet, siehe CLAUDE.md) -- `ssg_testrunner.lsp` wird manuell per `(load "...")` oder ueber das Menue geladen +- `test_run_all.lsp` laedt die einzelnen Testrunner automatisch -## Modulspezifische Testfaelle +## Neuen Test erstellen -### Kreisel (kreisel_tests.json) +1. **Testdaten**: `testdata/_tests.json` erstellen (flaches JSON-Array) +2. **LISP-Testrunner**: `test_.lsp` erstellen mit `c:TEST_` und `:export-results` +3. **Testregistry**: Eintrag in `alltests.json` hinzufuegen +4. **Python-Validierung** (optional): `test_.py` und Fixtures in `conftest.py` -| Test-ID | Beschreibung | Params | -|---|---|---| -| KR_Horiz_ObenUnten | Horizontaler Kreisel, oben nach unten | rot=270, art=STANDARD | -| KR_Horiz_UntenOben | Horizontaler Kreisel, unten nach oben | rot=90, art=PIN | -| KR_Vert_LinksRechts | Vertikaler Kreisel, links nach rechts | rot=0, art=PIN | -| KR_Vert_RechtsLinks | Vertikaler Kreisel, rechts nach links | rot=180, art=STANDARD | -| KR_Insert_Schraeg | Kreisel mit 10 Grad Drehung | rot=10, abstand=6000 | - -### Vario (vario_tests.json) - -| Test-ID | Beschreibung | Params | -|---|---|---| -| VF_Gerade_1Segment | Einzelnes gerades Segment | laenge=2000 | -| VF_Gerade_3Segmente | Drei gerade Segmente | laenge=6000 | -| VF_Gefaelle_Standard | Gefaellestrecke Standard | hoehe=500 | -| VF_Bogen_Links | Linksbogen | winkel=90 | -| VF_Bogen_Rechts | Rechtsbogen | winkel=-90 | - -### Omniflo (omniflo_tests.json) - -| Test-ID | Beschreibung | Params | -|---|---|---| -| OM_Bogen_90 | 90-Grad Bogen | winkel=90 | -| OM_Weiche_Links | Linksweiche | seite=L | -| OM_Weiche_Rechts | Rechtsweiche | seite=R | +Detailliertes Vorgehen und Codevorlagen: siehe `tests/README.md`. diff --git a/tests/test_foerderer.lsp b/tests/test_foerderer.lsp index e112d9f..32b13e4 100644 --- a/tests/test_foerderer.lsp +++ b/tests/test_foerderer.lsp @@ -86,13 +86,25 @@ (setvar "ATTREQ" 0) (setvar "ATTDIA" 0) + ;; Debug-Logging starten + (dbgopen "test_foerderer.dbg" "DXFM_LOG") + ;; Testdaten aus JSON laden (setq json-datei - (strcat (vl-string-translate "\\" "/" (getenv "DXFMAKRO")) - "/tests/testdata/foerderer_tests.json")) + (strcat (getenv "DXFMAKRO") + "\\tests\\testdata\\foerderer_tests.json")) + + (dbgmsg (strcat "DXFMAKRO=" (if (getenv "DXFMAKRO") (getenv "DXFMAKRO") "nil"))) + (dbgmsg (strcat "json-datei=" json-datei)) + (dbgmsg (strcat "file-exists=" (if (findfile json-datei) "JA" "NEIN"))) + (dbgflush) + (setq testdaten (ssg-load-json json-datei)) (if (null testdaten) (progn + (dbgmsg "FEHLER: testdaten ist nil nach ssg-load-json") + (dbgflush) + (dbgclose) (alert (strcat "Testdaten nicht gefunden:\n" json-datei)) (ssg-end) (exit) @@ -200,6 +212,7 @@ ;; Ergebnisse in globaler Variable speichern (setq *foerderer-test-results* (reverse results-list)) + (dbgclose) (ssg-end) (princ "\n================================================================") (princ "\n TEST_FOERDERER abgeschlossen.") diff --git a/tests/testdata/foerderer_tests.json b/tests/testdata/foerderer_tests.json index 091157f..84e7692 100644 --- a/tests/testdata/foerderer_tests.json +++ b/tests/testdata/foerderer_tests.json @@ -1,15 +1,77 @@ [ - { "y_abstand": 400 }, - { "test_id": "VF_Auf_0", "richtung": "Auf", "deltaL": 7000, "deltaH": 0 }, - { "test_id": "VF_Auf_1000", "richtung": "Auf", "deltaL": 7000, "deltaH": 1000 }, - { "test_id": "VF_Auf_2000", "richtung": "Auf", "deltaL": 7000, "deltaH": 2000 }, - { "test_id": "VF_Auf_3000", "richtung": "Auf", "deltaL": 7000, "deltaH": 3000 }, - { "test_id": "VF_Auf_4000", "richtung": "Auf", "deltaL": 7000, "deltaH": 4000 }, - { "test_id": "VF_Auf_5000", "richtung": "Auf", "deltaL": 7000, "deltaH": 5000 }, - { "test_id": "VF_Ab_0", "richtung": "Ab", "deltaL": 7000, "deltaH": 0 }, - { "test_id": "VF_Ab_1000", "richtung": "Ab", "deltaL": 7000, "deltaH": 1000 }, - { "test_id": "VF_Ab_2000", "richtung": "Ab", "deltaL": 7000, "deltaH": 2000 }, - { "test_id": "VF_Ab_3000", "richtung": "Ab", "deltaL": 7000, "deltaH": 3000 }, - { "test_id": "VF_Ab_4000", "richtung": "Ab", "deltaL": 7000, "deltaH": 4000 }, - { "test_id": "VF_Ab_5000", "richtung": "Ab", "deltaL": 7000, "deltaH": 5000 } + { + "y_abstand": 400 + }, + { + "test_id": "VF_Auf_0", + "richtung": "Auf", + "deltaL": 7000, + "deltaH": 0 + }, + { + "test_id": "VF_Auf_1000", + "richtung": "Auf", + "deltaL": 7000, + "deltaH": 1000 + }, + { + "test_id": "VF_Auf_2000", + "richtung": "Auf", + "deltaL": 7000, + "deltaH": 2000 + }, + { + "test_id": "VF_Auf_3000", + "richtung": "Auf", + "deltaL": 7000, + "deltaH": 3000 + }, + { + "test_id": "VF_Auf_4000", + "richtung": "Auf", + "deltaL": 7000, + "deltaH": 4000 + }, + { + "test_id": "VF_Auf_5000", + "richtung": "Auf", + "deltaL": 7000, + "deltaH": 5000 + }, + { + "test_id": "VF_Ab_0", + "richtung": "Ab", + "deltaL": 7000, + "deltaH": 0 + }, + { + "test_id": "VF_Ab_1000", + "richtung": "Ab", + "deltaL": 7000, + "deltaH": 1000 + }, + { + "test_id": "VF_Ab_2000", + "richtung": "Ab", + "deltaL": 7000, + "deltaH": 2000 + }, + { + "test_id": "VF_Ab_3000", + "richtung": "Ab", + "deltaL": 7000, + "deltaH": 3000 + }, + { + "test_id": "VF_Ab_4000", + "richtung": "Ab", + "deltaL": 7000, + "deltaH": 4000 + }, + { + "test_id": "VF_Ab_5000", + "richtung": "Ab", + "deltaL": 7000, + "deltaH": 5000 + } ]