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:
Ismail Ali
2025-06-22 08:42:49 +02:00
parent 7d1e7ef88a
commit 041bc3e23e
20 changed files with 151 additions and 354 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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
---
## [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`

View File

@@ -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]
@@ -53,10 +53,10 @@ flowchart TD
## 🌐 API-Endpunkte
| Route | Methode | Modus | Funktion |
| ----------------------------------------- | -------- | ---------------- | ------------------------------ |
| `/api/cpl/getDigitalOutputsHandler.ts` | `GET` | `json`, `jsmock` | Liest JSON-Datei oder JS-Datei |
| ----------------------------------------- | -------- | ------------------------- | ------------------------------ |
| `/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`, `jsmock` | Speichert Statusänderung |
| `/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

View File

@@ -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?

View File

@@ -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]

View File

@@ -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

View File

@@ -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
View File

@@ -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",

View File

@@ -1,6 +1,6 @@
{
"name": "cpl-v4",
"version": "1.6.441",
"version": "1.6.442",
"private": true,
"scripts": {
"dev": "next dev",

View File

@@ -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);
res.setHeader("Content-Type", "application/javascript");
res.status(200).send(analogInputsScript);
return;
}
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);
}
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" });
}
}

View File

@@ -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" });

View File

@@ -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(),

View File

@@ -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"

View File

@@ -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(

View File

@@ -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",

View File

@@ -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

View File

@@ -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");

View File

@@ -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,

View File

@@ -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) {