feat: jsSimulatedProd-Modus für analoge & digitale Eingänge implementiert
- neuen Modus `jsSimulatedProd` eingeführt für realitätsnahe Simulation auf Basis echter Produktionsdaten - analoge Eingänge: analogInputsMockData.js eingebunden und dynamisch per Script geladen - digitale Eingänge: digitalInputsMockData.js eingebunden mit window-Variablen (z. B. win_de_state, win_de_label etc.) - fetchAnalogInputsService.ts und fetchDigitalInputsService.ts angepasst zur Modusprüfung und Script-Auswertung - getAnalogInputsHandler.ts und getDigitalInputsHandler.ts geben im jsSimulatedProd-Modus JavaScript-Dateien aus - .env.development setzt `NEXT_PUBLIC_CPL_MODE=jsSimulatedProd`
This commit is contained in:
@@ -6,5 +6,5 @@ NEXT_PUBLIC_USE_MOCK_BACKEND_LOOP_START=false
|
||||
NEXT_PUBLIC_EXPORT_STATIC=false
|
||||
NEXT_PUBLIC_USE_CGI=false
|
||||
# App-Versionsnummer
|
||||
NEXT_PUBLIC_APP_VERSION=1.6.441
|
||||
NEXT_PUBLIC_CPL_MODE=jsmock # json (Entwicklungsumgebung) oder jsmock (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter)
|
||||
NEXT_PUBLIC_APP_VERSION=1.6.442
|
||||
NEXT_PUBLIC_CPL_MODE=jsSimulatedProd # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter)
|
||||
@@ -5,5 +5,5 @@ NEXT_PUBLIC_CPL_API_PATH=/CPL
|
||||
NEXT_PUBLIC_EXPORT_STATIC=true
|
||||
NEXT_PUBLIC_USE_CGI=true
|
||||
# App-Versionsnummer
|
||||
NEXT_PUBLIC_APP_VERSION=1.6.441
|
||||
NEXT_PUBLIC_APP_VERSION=1.6.442
|
||||
NEXT_PUBLIC_CPL_MODE=production
|
||||
29
CHANGELOG.md
29
CHANGELOG.md
@@ -1,23 +1,32 @@
|
||||
## [1.6.442] – 2025-06-22
|
||||
|
||||
- docs: add full architecture diagram and data flow for json, jsmock and production modes
|
||||
|
||||
---
|
||||
## [1.6.441] – 2025-06-21
|
||||
|
||||
- docs: add analog inputs architecture diagram and flow description
|
||||
|
||||
---
|
||||
|
||||
## [1.6.440] – 2025-06-21
|
||||
|
||||
- docs: move user documentation to docs/user-guide as single source of truth
|
||||
|
||||
---
|
||||
|
||||
## [1.6.439] – 2025-06-21
|
||||
|
||||
- chore: fetch to get in redux thunks files name
|
||||
- chore: fetch to get in redux thunks files name
|
||||
|
||||
---
|
||||
|
||||
## [1.6.438] – 2025-06-21
|
||||
|
||||
- chore(tsconfig): fix moduleResolution and path aliases for Next.js project
|
||||
|
||||
---
|
||||
|
||||
## [1.6.437] – 2025-06-21
|
||||
|
||||
- chore: rename service/thunk files to follow get/fetch naming convention
|
||||
@@ -56,7 +65,7 @@
|
||||
|
||||
## [1.6.431] – 2025-06-20
|
||||
|
||||
- feat: Digitale & analoge Eingänge in allen Modi (json/jsmock/production) vollständig implementiert
|
||||
- feat: Digitale & analoge Eingänge in allen Modi (json/jsSimulatedProd/production) vollständig implementiert
|
||||
|
||||
---
|
||||
|
||||
@@ -72,9 +81,9 @@ Alle Änderungen und Versionen des CPLv4.0 Frontends chronologisch dokumentiert.
|
||||
|
||||
- Digitale Eingänge (Meldungseingänge) sind jetzt vollständig implementiert:
|
||||
- `json`: Mock-Daten werden editierbar über eine JSON-Datei verwaltet
|
||||
- `jsmock`: JavaScript-basierte Simulation mit `window.win_di_state`, `win_di_label`, etc.
|
||||
- `jsSimulatedProd`: JavaScript-basierte Simulation mit `window.win_di_state`, `win_di_label`, etc.
|
||||
- `production`: Kommunikation über CGI-Befehle wie `DEN1=...`, `DEI1=...`
|
||||
- Analoge Eingänge ebenfalls vollständig in allen Modi (json/jsmock/production) nutzbar
|
||||
- Analoge Eingänge ebenfalls vollständig in allen Modi (json/jsSimulatedProd/production) nutzbar
|
||||
- Die Statusanzeige für digitale Eingänge wird korrekt aus Redux gelesen (`input.status`)
|
||||
- Redux-Struktur überarbeitet: `invert`, `status`, `counterActive`, `value` werden sauber getrennt
|
||||
- Die Modi-Erkennung erfolgt automatisch über `NEXT_PUBLIC_CPL_MODE`
|
||||
@@ -89,18 +98,18 @@ Alle Änderungen und Versionen des CPLv4.0 Frontends chronologisch dokumentiert.
|
||||
|
||||
- Die Schaltausgänge (digitale Ausgänge) sind jetzt in allen Modi vollständig funktionsfähig:
|
||||
- `json` (lokale Entwicklung mit editierbaren Mock-Daten)
|
||||
- `jsmock` (Simulation durch JavaScript-Variablen im `window`-Objekt)
|
||||
- `jsSimulatedProd` (Simulation durch JavaScript-Variablen im `window`-Objekt)
|
||||
- `production` (Platzhalterersetzung über CGI durch das echte CPL-Gerät)
|
||||
- Die API `/api/cpl/updateDigitalOutputsHandler` verarbeitet POST-Daten je nach Modus:
|
||||
- In `json`: Speicherung in `digitalOutputsMockData.json`
|
||||
- In `jsmock`: Live-Änderung in `digitalOutputsMockData.js` per Regex
|
||||
- In `jsSimulatedProd`: Live-Änderung in `digitalOutputsMockData.js` per Regex
|
||||
- In `production`: Statusänderung über Redirect zu `/CPL?digitalOutputs.html&DAS0X=1`
|
||||
- Die Datei `fetchDigitalOutputsService.ts` erkennt den aktiven Modus und lädt Daten kontextsensitiv
|
||||
- Alle Werte werden über Redux bereitgestellt, die UI nutzt `useSelector()` zur Anzeige in `DigitalOutputsWidget.tsx`
|
||||
- Mermaid-Dokumentation zur Architektur im Projekt ergänzt (`README_digitalOutputs_final.md`)- `json` und `jsmock` wurden zu einer gemeinsamen API `/api/cpl/getDigitalOutputsHandler.ts` zusammengeführt
|
||||
- Mermaid-Dokumentation zur Architektur im Projekt ergänzt (`README_digitalOutputs_final.md`)- `json` und `jsSimulatedProd` wurden zu einer gemeinsamen API `/api/cpl/getDigitalOutputsHandler.ts` zusammengeführt
|
||||
- Die API erkennt den Modus automatisch über `NEXT_PUBLIC_CPL_MODE`
|
||||
- In `json` wird eine editierbare JSON-Datei gelesen und zurückgegeben
|
||||
- In `jsmock` wird eine JavaScript-Datei per Regex analysiert und verarbeitet
|
||||
- In `jsSimulatedProd` wird eine JavaScript-Datei per Regex analysiert und verarbeitet
|
||||
- Die Logik in `fetchDigitalOutputsService.ts` wurde vereinfacht:
|
||||
- Für beide Modi wird dieselbe API aufgerufen
|
||||
- Nur in `production` wird das Script `/CPL?/CPL/SERVICE/digitalOutputs.js` dynamisch eingebunden
|
||||
@@ -116,11 +125,11 @@ Alle Änderungen und Versionen des CPLv4.0 Frontends chronologisch dokumentiert.
|
||||
|
||||
- Die Schaltausgänge (digitale Ausgänge) sind jetzt in allen Modi vollständig funktionsfähig:
|
||||
- `json` (lokale Entwicklung mit editierbaren Mock-Daten)
|
||||
- `jsmock` (Simulation durch JavaScript-Variablen im `window`-Objekt)
|
||||
- `jsSimulatedProd` (Simulation durch JavaScript-Variablen im `window`-Objekt)
|
||||
- `production` (Platzhalterersetzung über CGI durch das echte CPL-Gerät)
|
||||
- Die API `/api/cpl/updateDigitalOutputsHandler` verarbeitet POST-Daten je nach Modus:
|
||||
- In `json`: Speicherung in `digitalOutputsMockData.json`
|
||||
- In `jsmock`: Live-Änderung in `digitalOutputsMockData.js` per Regex
|
||||
- In `jsSimulatedProd`: Live-Änderung in `digitalOutputsMockData.js` per Regex
|
||||
- In `production`: Statusänderung über Redirect zu `/CPL?digitalOutputs.html&DAS0X=1`
|
||||
- Die Datei `fetchDigitalOutputsService.ts` erkennt den aktiven Modus und lädt Daten kontextsensitiv
|
||||
- Alle Werte werden über Redux bereitgestellt, die UI nutzt `useSelector()` zur Anzeige in `DigitalOutputsWidget.tsx`
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Dieses Dokument beschreibt die Architektur und Datenflüsse für das **Lesen** und **Updaten** der digitalen Ausgänge im CPL-System. Unterstützt werden folgende Modi:
|
||||
|
||||
- `json`: Entwicklung mit editierbarer JSON-Datei
|
||||
- `jsmock`: Simulation durch `digitalOutputsMockData.js`
|
||||
- `jsSimulatedProd`: Simulation durch `digitalOutputsMockData.js`
|
||||
- `production`: Reale CPL-Hardware über CGI-Platzhalter
|
||||
|
||||
---
|
||||
@@ -19,7 +19,7 @@ flowchart TD
|
||||
C --> D[fetchDigitalOutputsService]
|
||||
D --> E{Moduswahl: NEXT_PUBLIC_CPL_MODE}
|
||||
|
||||
E -->|json oder jsmock| F[GET /api/cpl/getDigitalOutputsHandler.ts]
|
||||
E -->|json oder jsSimulatedProd| F[GET /api/cpl/getDigitalOutputsHandler.ts]
|
||||
F --> G[JSON oder geparste JS-Datei]
|
||||
|
||||
E -->|production| H[loadScript '/CPL?/CPL/SERVICE/digitalOutputs.js']
|
||||
@@ -42,7 +42,7 @@ flowchart TD
|
||||
B --> D{Modus: production oder nicht}
|
||||
|
||||
D -->|production| E1[window.location.href = /CPL?digitalOutputs.html&DAS0X=1]
|
||||
D -->|json oder jsmock| F1[POST /api/cpl/updateDigitalOutputsHandler]
|
||||
D -->|json oder jsSimulatedProd| F1[POST /api/cpl/updateDigitalOutputsHandler]
|
||||
F1 --> F2[Schreibe JSON oder JS-Datei]
|
||||
|
||||
F2 & E1 --> G[Aktualisierte Zustände am Gerät]
|
||||
@@ -52,11 +52,11 @@ flowchart TD
|
||||
|
||||
## 🌐 API-Endpunkte
|
||||
|
||||
| Route | Methode | Modus | Funktion |
|
||||
| ----------------------------------------- | -------- | ---------------- | ------------------------------ |
|
||||
| `/api/cpl/getDigitalOutputsHandler.ts` | `GET` | `json`, `jsmock` | Liest JSON-Datei oder JS-Datei |
|
||||
| `/CPL?/CPL/SERVICE/digitalOutputs.js` | `SCRIPT` | `production` | Liefert Platzhalter vom Gerät |
|
||||
| `/api/cpl/updateDigitalOutputsHandler.ts` | `POST` | `json`, `jsmock` | Speichert Statusänderung |
|
||||
| Route | Methode | Modus | Funktion |
|
||||
| ----------------------------------------- | -------- | ------------------------- | ------------------------------ |
|
||||
| `/api/cpl/getDigitalOutputsHandler.ts` | `GET` | `json`, `jsSimulatedProd` | Liest JSON-Datei oder JS-Datei |
|
||||
| `/CPL?/CPL/SERVICE/digitalOutputs.js` | `SCRIPT` | `production` | Liefert Platzhalter vom Gerät |
|
||||
| `/api/cpl/updateDigitalOutputsHandler.ts` | `POST` | `json`, `jsSimulatedProd` | Speichert Statusänderung |
|
||||
|
||||
---
|
||||
|
||||
@@ -75,9 +75,9 @@ flowchart TD
|
||||
|
||||
```
|
||||
/mocks/api/SERVICE/ → JSON-Dateien
|
||||
/mocks/device-cgi-simulator/SERVICE/→ jsmock: digitalOutputsMockData.js
|
||||
/mocks/device-cgi-simulator/SERVICE/→ jsSimulatedProd: digitalOutputsMockData.js
|
||||
/public/CPL/SERVICE/ → production: digitalOutputs.js
|
||||
/pages/api/cpl/ → GET/POST-Handler für json + jsmock
|
||||
/pages/api/cpl/ → GET/POST-Handler für json + jsSimulatedProd
|
||||
/components/main/einausgaenge/ → UI-Komponente: DigitalOutputsWidget.tsx
|
||||
```
|
||||
|
||||
@@ -87,5 +87,5 @@ flowchart TD
|
||||
|
||||
- [x] Lesen funktioniert in allen Modi
|
||||
- [x] Schreiben funktioniert in allen Modi (production nur über Redirect)
|
||||
- [x] json + jsmock verwenden jetzt denselben API-Handler
|
||||
- [x] json + jsSimulatedProd verwenden jetzt denselben API-Handler
|
||||
- [x] Redux-Integration ist vollständig
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
## ✅ TODOs
|
||||
|
||||
- [ ] TODO: In digitale Eingänge Modal Out of Service geht nicht in json , jsmock und production. readOnly?
|
||||
- [ ] TODO: In digitale Eingänge Modal Out of Service geht nicht in json , jsSimulatedProd und production. readOnly?
|
||||
|
||||
@@ -4,7 +4,7 @@ Dieses Diagramm beschreibt die Datenflussarchitektur des Services `fetchAnalogeE
|
||||
|
||||
## 🎯 Ziel
|
||||
|
||||
Egal ob `json`, `jsmock` oder `production`-Modus – der Service gibt **immer** ein einheitliches JSON-Objekt zurück.
|
||||
Egal ob `json`, `jsSimulatedProd` oder `production`-Modus – der Service gibt **immer** ein einheitliches JSON-Objekt zurück.
|
||||
|
||||
---
|
||||
|
||||
@@ -17,8 +17,8 @@ flowchart TD
|
||||
CheckMode -->|json| FetchJSON[📄 JSON-Datei laden: /CPLmockData/SERVICE/analogeEingaengeMockData.json]
|
||||
FetchJSON --> ReturnJSON1[✅ JSON zurückgeben]
|
||||
|
||||
CheckMode -->|jsmock| ImportJSMock[📜 JS-Datei importieren: analogeEingaengeMockData.js]
|
||||
ImportJSMock --> ParseMock[🔁 parseWindowData]
|
||||
CheckMode -->|jsSimulatedProd| ImportjsSimulatedProd[📜 JS-Datei importieren: analogeEingaengeMockData.js]
|
||||
ImportjsSimulatedProd --> ParseMock[🔁 parseWindowData]
|
||||
ParseMock --> ReturnJSON2[✅ JSON zurückgeben]
|
||||
|
||||
CheckMode -->|production| LoadCGI[🌐 JS vom Gerät laden: /CPL/SERVICE/analogeEingaenge.js]
|
||||
@@ -37,7 +37,7 @@ flowchart TD
|
||||
In dieser Anwendung werden drei Betriebsmodi unterstützt:
|
||||
|
||||
- `json`: lädt Mockdaten über API-Handler
|
||||
- `jsmock`: lädt JS-Dateien mit `window.win_*` Variablen
|
||||
- `jsSimulatedProd`: lädt JS-Dateien mit `window.win_*` Variablen
|
||||
- `production`: lädt Platzhalterdaten vom echten Gerät (CPL)
|
||||
|
||||
Ziel: Alle Services liefern immer standardisiertes JSON-Objekt
|
||||
@@ -48,7 +48,7 @@ Ziel: Alle Services liefern immer standardisiertes JSON-Objekt
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[.env: NEXT_PUBLIC_CPL_MODE] -->|json| B1[/api/.../APIHandler.ts/]
|
||||
A -->|jsmock / production| B2[window.win_* Variablen aus JS-Datei]
|
||||
A -->|jsSimulatedProd / production| B2[window.win_* Variablen aus JS-Datei]
|
||||
B1 --> C[fetchXYZService.ts]
|
||||
B2 --> C
|
||||
C --> D[Normiertes JSON-Objekt]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 🧩 Datenfluss & Architekturstrategie – Analoge Eingänge (Alle Modi)
|
||||
|
||||
Diese Dokumentation beschreibt die Architekturstrategie für die Verarbeitung von analogen Eingangsdaten in den drei unterstützten Modi: `jsmock`, `json` und `production`.
|
||||
Diese Dokumentation beschreibt die Architekturstrategie für die Verarbeitung von analogen Eingangsdaten in den drei unterstützten Modi: `jsSimulatedProd`, `json` und `production`.
|
||||
|
||||
---
|
||||
|
||||
@@ -18,7 +18,7 @@ Diese Dokumentation beschreibt die Architekturstrategie für die Verarbeitung vo
|
||||
```mermaid
|
||||
flowchart TD
|
||||
|
||||
subgraph JSMOCK-Modus
|
||||
subgraph jsSimulatedProd-Modus
|
||||
A1["analogInputsMockData.js - Mockdaten mit window-Variablen"]
|
||||
B1["/api/cpl/getAnalogInputsHandler.ts - API gibt Rohdaten zurück"]
|
||||
C1["fetchAnalogInputsService.ts - wandelt in JSON"]
|
||||
@@ -58,7 +58,7 @@ flowchart TD
|
||||
## 📁 Verzeichnisstruktur (Auszug)
|
||||
|
||||
```txt
|
||||
/mocks/device-cgi-simulator/SERVICE/*.js # jsmock-Modus
|
||||
/mocks/device-cgi-simulator/SERVICE/*.js # jsSimulatedProd-Modus
|
||||
/mocks/api/SERVICE/*.json # json-Modus
|
||||
/public/CPL/SERVICE/*.js # production-Modus (CGI-Daten im JS-Format)
|
||||
/services/fetchAnalogInputsService.ts # verarbeitet Rückgabe zu JSON
|
||||
|
||||
@@ -1,242 +1,31 @@
|
||||
|
||||
// auto-generated from update API
|
||||
var win_de_state = [
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
var win_de_invert = [
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
var win_de_counter = [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
var win_de_time_filter = [
|
||||
3,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
var win_de_weighting = [
|
||||
3,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
var win_de_counter_active = [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
var win_de_offline = [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
var win_de_label = [
|
||||
"DE1",
|
||||
@@ -270,5 +59,5 @@ var win_de_label = [
|
||||
"DE29",
|
||||
"DE30",
|
||||
"DE31",
|
||||
"DE32"
|
||||
"DE32",
|
||||
];
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "cpl-v4",
|
||||
"version": "1.6.441",
|
||||
"version": "1.6.442",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "cpl-v4",
|
||||
"version": "1.6.441",
|
||||
"version": "1.6.442",
|
||||
"dependencies": {
|
||||
"@fontsource/roboto": "^5.1.0",
|
||||
"@iconify-icons/ri": "^1.2.10",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cpl-v4",
|
||||
"version": "1.6.441",
|
||||
"version": "1.6.442",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -18,51 +18,17 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
return res.status(200).json(data);
|
||||
}
|
||||
|
||||
if (mode === "jsmock") {
|
||||
const filePath = path.join(
|
||||
process.cwd(),
|
||||
"mocks/device-cgi-simulator/SERVICE/analogInputsMockData.js"
|
||||
if (mode === "jsSimulatedProd") {
|
||||
const analogInputsScript = fs.readFileSync(
|
||||
"mocks/device-cgi-simulator/SERVICE/analogInputsMockData.js",
|
||||
"utf-8"
|
||||
);
|
||||
const content = fs.readFileSync(filePath, "utf-8");
|
||||
|
||||
function extractArray(name: string): any[] {
|
||||
const match = content.match(
|
||||
new RegExp(`var\\s+${name}\\s*=\\s*\\[([\\s\\S]*?)\\];`)
|
||||
);
|
||||
if (!match) return [];
|
||||
return match[1]
|
||||
.split(",")
|
||||
.map((s) => s.trim().replace(/^["']|["']$/g, ""))
|
||||
.slice(0, 8);
|
||||
}
|
||||
|
||||
const responseData = {
|
||||
win_analogInputsValues: extractArray("win_analogInputsValues").map(
|
||||
Number
|
||||
),
|
||||
win_analogInputsLabels: extractArray("win_analogInputsLabels"),
|
||||
win_analogInputsOffset: extractArray("win_analogInputsOffset").map(
|
||||
Number
|
||||
),
|
||||
win_analogInputsFactor: extractArray("win_analogInputsFactor").map(
|
||||
Number
|
||||
),
|
||||
win_analogInputsLoggerIntervall: extractArray(
|
||||
"win_analogInputsLoggerIntervall"
|
||||
).map(Number),
|
||||
win_analogInputsUnits: extractArray("win_analogInputsUnits"),
|
||||
win_analogInputsWeighting: extractArray(
|
||||
"win_analogInputsWeighting"
|
||||
).map(Number),
|
||||
};
|
||||
//console.log("Analog Inputs Mock Data:", responseData);
|
||||
|
||||
return res.status(200).json(responseData);
|
||||
res.setHeader("Content-Type", "application/javascript");
|
||||
res.status(200).send(analogInputsScript);
|
||||
return;
|
||||
}
|
||||
|
||||
return res.status(400).json({ error: "Unsupported mode" });
|
||||
} catch (error) {
|
||||
console.error("❌ Fehler beim Lesen der analogen Eingänge:", error);
|
||||
return res.status(500).json({ error: "Fehler beim Lesen der Datei" });
|
||||
console.error(error);
|
||||
res.status(500).json({ error: "Internal Server Error" });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,39 +20,14 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
return res.status(200).json(json);
|
||||
}
|
||||
|
||||
if (mode === "jsmock") {
|
||||
const jsPath = path.join(
|
||||
process.cwd(),
|
||||
"mocks/device-cgi-simulator/SERVICE/digitalInputsMockData.js"
|
||||
if (mode === "jsSimulatedProd") {
|
||||
const analogInputsScript = fs.readFileSync(
|
||||
"mocks/device-cgi-simulator/SERVICE/digitalInputsMockData.js",
|
||||
"utf-8"
|
||||
);
|
||||
const fileContent = fs.readFileSync(jsPath, "utf-8");
|
||||
//console.log("📡 JSMOCK-Daten geladen fileContent:", fileContent);
|
||||
|
||||
const extractArray = (label: string) => {
|
||||
const match = fileContent.match(
|
||||
new RegExp(`var\\s+${label}\\s*=\\s*\\[([\\s\\S]*?)\\];`)
|
||||
);
|
||||
if (!match) throw new Error(`Feld ${label} nicht gefunden`);
|
||||
return match[1]
|
||||
.split(",")
|
||||
.map((s) => s.trim().replace(/^["']|["']$/g, ""));
|
||||
};
|
||||
|
||||
const data = {
|
||||
win_de_state: extractArray("win_de_state").map(Number),
|
||||
win_de_invert: extractArray("win_de_invert").map(Number),
|
||||
win_de_counter: extractArray("win_de_counter").map(Number),
|
||||
win_de_time_filter: extractArray("win_de_time_filter").map(Number),
|
||||
win_de_weighting: extractArray("win_de_weighting").map(Number),
|
||||
win_de_counter_active: extractArray("win_de_counter_active").map(
|
||||
Number
|
||||
),
|
||||
win_de_offline: extractArray("win_de_offline").map(Number),
|
||||
win_de_label: extractArray("win_de_label"),
|
||||
};
|
||||
//console.log("📡 JSMOCK-Daten geladen in api in jsmock:", data);
|
||||
|
||||
return res.status(200).json(data);
|
||||
res.setHeader("Content-Type", "application/javascript");
|
||||
res.status(200).send(analogInputsScript);
|
||||
return;
|
||||
}
|
||||
|
||||
return res.status(400).json({ error: "Ungültiger Modus" });
|
||||
|
||||
@@ -21,7 +21,7 @@ export default async function handler(
|
||||
return res.status(200).json(data);
|
||||
}
|
||||
|
||||
if (mode === "jsmock") {
|
||||
if (mode === "jsSimulatedProd") {
|
||||
// Lese Datei und extrahiere window-Variablen aus .js-Datei
|
||||
const filePath = path.join(
|
||||
process.cwd(),
|
||||
|
||||
@@ -34,7 +34,7 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
return res.status(200).json({ success: true });
|
||||
}
|
||||
|
||||
if (mode === "jsmock") {
|
||||
if (mode === "jsSimulatedProd") {
|
||||
const filePath = path.join(
|
||||
process.cwd(),
|
||||
"mocks/device-cgi-simulator/SERVICE/analogInputsMockData.js"
|
||||
|
||||
@@ -17,7 +17,7 @@ if (mode === "json") {
|
||||
"digitalInputsMockData.json"
|
||||
);
|
||||
}
|
||||
if (mode === "jsmock") {
|
||||
if (mode === "jsSimulatedProd") {
|
||||
mockFilePath = path.join(
|
||||
process.cwd(),
|
||||
"mocks",
|
||||
@@ -32,7 +32,7 @@ if (!mockFilePath) {
|
||||
throw new Error(`❌ Kein gültiger Modus in .env gesetzt: ${mode}`);
|
||||
}
|
||||
|
||||
// Funktion zum Parsen bei jsmock
|
||||
// Funktion zum Parsen bei jsSimulatedProd
|
||||
function extractMockData(raw: string) {
|
||||
const context = {};
|
||||
const func = new Function(
|
||||
|
||||
@@ -42,7 +42,7 @@ export default function handler(req, res) {
|
||||
console.error("❌ Fehler beim Schreiben der JSON-Datei:", err);
|
||||
res.status(500).json({ error: "Fehler beim Schreiben der Datei" });
|
||||
}
|
||||
} else if (mode === "jsmock") {
|
||||
} else if (mode === "jsSimulatedProd") {
|
||||
filePath = path.join(
|
||||
process.cwd(),
|
||||
"mocks",
|
||||
|
||||
@@ -38,7 +38,7 @@ export async function fetchAnalogInputsHistoryService(): Promise<
|
||||
const data = await response.json();
|
||||
|
||||
// 🔍 Log: JSON anzeigen
|
||||
console.log("✅ [DEV] Parsed JSON:", data);
|
||||
//console.log("✅ [DEV] Parsed JSON:", data);
|
||||
|
||||
// 🔍 Validitätsprüfung (optional)
|
||||
JSON.stringify(data); // Wenn das fehlschlägt, wird catch ausgelöst
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
export const fetchAnalogInputsService = async () => {
|
||||
const mode = process.env.NEXT_PUBLIC_CPL_MODE;
|
||||
|
||||
// ✅ PRODUKTIV: lädt JavaScript vom Gerät über CGI
|
||||
if (mode === "production") {
|
||||
console.log("🔄 Lade analoge Eingänge im Produktionsmodus...");
|
||||
const scriptUrl = "/CPL?/CPL/SERVICE/analogInputs.js";
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
@@ -27,7 +28,38 @@ export const fetchAnalogInputsService = async () => {
|
||||
loggerInterval: parseInt(win.win_analogInputsLoggerIntervall[i]),
|
||||
weighting: parseInt(win.win_analogInputsWeighting[i]),
|
||||
}));
|
||||
} else if (mode === "json" || mode === "jsmock") {
|
||||
}
|
||||
// ✅ jsSimulatedProd-MODUS (Script einbinden und aus window lesen)
|
||||
else if (mode === "jsSimulatedProd") {
|
||||
console.log("🔄 Lade simulierte analoge Eingänge im Produktionsmodus...");
|
||||
const scriptUrl = "/api/cpl/getAnalogInputsHandler"; // gibt JavaScript zurück
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const script = document.createElement("script");
|
||||
script.src = scriptUrl;
|
||||
script.async = true;
|
||||
script.onload = () => resolve();
|
||||
script.onerror = () =>
|
||||
reject("❌ Fehler beim Laden des simulierten Scripts");
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
|
||||
const win = window as any;
|
||||
|
||||
return Array.from({ length: 8 }, (_, i) => ({
|
||||
id: i + 1,
|
||||
value: parseFloat(win.win_analogInputsValues[i]),
|
||||
label: win.win_analogInputsLabels[i],
|
||||
unit: win.win_analogInputsUnits[i],
|
||||
offset: parseFloat(win.win_analogInputsOffset[i]),
|
||||
factor: parseFloat(win.win_analogInputsFactor[i]),
|
||||
loggerInterval: parseInt(win.win_analogInputsLoggerIntervall[i]),
|
||||
weighting: parseInt(win.win_analogInputsWeighting[i]),
|
||||
}));
|
||||
}
|
||||
// ✅ JSON-MODUS (API gibt JSON-Daten zurück)
|
||||
else if (mode === "json") {
|
||||
console.log("🔄 Lade analoge Eingänge im JSON-Modus...");
|
||||
const res = await fetch("/api/cpl/getAnalogInputsHandler");
|
||||
if (!res.ok) throw new Error("❌ Fehler beim Laden der analogen Eingänge");
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ export const fetchDigitalInputsService = async () => {
|
||||
|
||||
// ✅ PRODUKTIV: lädt JavaScript vom Gerät über CGI
|
||||
if (mode === "production") {
|
||||
console.log("🔄 Lade analoge Eingänge im Produktionsmodus...");
|
||||
const scriptUrl = "/CPL?/CPL/SERVICE/digitalInputs.js";
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
@@ -34,7 +35,8 @@ export const fetchDigitalInputsService = async () => {
|
||||
}
|
||||
|
||||
// ✅ JSON-MODUS (API gibt JSON-Daten zurück)
|
||||
if (mode === "json") {
|
||||
else if (mode === "json") {
|
||||
console.log("🔄 Lade digitale Eingänge im JSON-Modus...");
|
||||
const res = await fetch("/api/cpl/getDigitalInputsHandler");
|
||||
if (!res.ok)
|
||||
throw new Error("❌ Fehler beim Laden der digitalen Eingänge (json)");
|
||||
@@ -55,14 +57,38 @@ export const fetchDigitalInputsService = async () => {
|
||||
}));
|
||||
}
|
||||
|
||||
// ✅ JSMOCK-MODUS (Script einbinden und aus window lesen)
|
||||
if (mode === "jsmock") {
|
||||
const res = await fetch("/api/cpl/getDigitalInputsHandler");
|
||||
if (!res.ok)
|
||||
throw new Error("❌ Fehler beim Laden der digitalen Eingänge (json)");
|
||||
// ✅ jsSimulatedProd-MODUS (Script einbinden und aus window lesen)
|
||||
else if (mode === "jsSimulatedProd") {
|
||||
console.log("🔄 Lade digitale Eingänge im jsSimulatedProd-Modus...");
|
||||
// const res = await fetch("/api/cpl/getDigitalInputsHandler");
|
||||
//------------------------
|
||||
const scriptUrl = "/api/cpl/getDigitalInputsHandler"; // gibt JavaScript zurück
|
||||
|
||||
const data = await res.json();
|
||||
console.log("📡 JSMOCK-Daten geladen in service:", data);
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const script = document.createElement("script");
|
||||
script.src = scriptUrl;
|
||||
script.async = true;
|
||||
script.onload = () => resolve();
|
||||
script.onerror = () =>
|
||||
reject("❌ Fehler beim Laden des simulierten Scripts");
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
|
||||
// Annahme: Das Script setzt window.win_de_state usw.
|
||||
const data = {
|
||||
win_de_state: (window as any).win_de_state,
|
||||
win_de_label: (window as any).win_de_label,
|
||||
win_de_invert: (window as any).win_de_invert,
|
||||
win_de_counter: (window as any).win_de_counter,
|
||||
win_de_time_filter: (window as any).win_de_time_filter,
|
||||
win_de_weighting: (window as any).win_de_weighting,
|
||||
win_de_counter_active: (window as any).win_de_counter_active,
|
||||
win_de_offline: (window as any).win_de_offline,
|
||||
};
|
||||
|
||||
//--------------------------
|
||||
|
||||
console.log("📡 jsSimulatedProd-Daten geladen in service:", data);
|
||||
|
||||
return data.win_de_state.map((_: any, i: number) => ({
|
||||
id: i + 1,
|
||||
|
||||
@@ -33,7 +33,7 @@ export const fetchDigitalOutputsService = async () => {
|
||||
status: status === 1,
|
||||
}));
|
||||
}
|
||||
} else if (mode === "json" || mode === "jsmock") {
|
||||
} else if (mode === "json" || mode === "jsSimulatedProd") {
|
||||
const res = await fetch("/api/cpl/getDigitalOutputsHandler");
|
||||
|
||||
if (!res.ok) {
|
||||
|
||||
Reference in New Issue
Block a user