feat: Digitale Ausgänge vollständig implementiert (Lesen & Schreiben in allen Modi)
- Unterstützung für drei Modi implementiert: json, jsmock und production - fetchDigitalOutputsService.ts erkennt NEXT_PUBLIC_CPL_MODE und lädt Daten je nach Umgebung - API-Handler /api/cpl/updateDigitalOutputsHandler verarbeitet POST-Anfragen für json und jsmock - In production wird Statusänderung per Redirect (window.location.href) an das CPL gesendet - Redux-Slice für digitale Ausgänge vollständig angebunden - UI (DigitalOutputsWidget.tsx) zeigt Status und ermöglicht das Umschalten - Dokumentation als README_digitalOutputs_final.md mit UML-Diagrammen ergänzt - CHANGELOG.md auf Version 1.6.417 aktualisiert
This commit is contained in:
@@ -6,6 +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.417
|
||||
NEXT_PUBLIC_APP_VERSION=1.6.418
|
||||
NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsmock (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.417
|
||||
NEXT_PUBLIC_APP_VERSION=1.6.418
|
||||
NEXT_PUBLIC_CPL_MODE=production
|
||||
20
CHANGELOG.md
20
CHANGELOG.md
@@ -4,6 +4,26 @@ Alle Änderungen und Versionen des CPLv4.0 Frontends chronologisch dokumentiert.
|
||||
|
||||
---
|
||||
|
||||
## [1.6.417] – 2025-06-19
|
||||
|
||||
### Feature: Digitale Ausgänge vollständig implementiert (Lesen & Schreiben in 3 Modi)
|
||||
|
||||
- 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)
|
||||
- `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 `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`)
|
||||
|
||||
Alle Änderungen und Versionen des CPLv4.0 Frontends chronologisch dokumentiert.
|
||||
|
||||
---
|
||||
|
||||
## [1.6.407] – 2025-06-16
|
||||
|
||||
### Feature: Kabelname statt Bezeichnung
|
||||
|
||||
99
docs/Architektur/CPL_DataHandling.md
Normal file
99
docs/Architektur/CPL_DataHandling.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# 📦 Datenverarbeitung in CPL: JSON, jsmock, production
|
||||
|
||||
Dieses Dokument beschreibt die Architektur zur Verarbeitung von Digitalausgängen (DA) im CPL-System unter verschiedenen Modi.
|
||||
|
||||
## ✅ Unterstützte Modi
|
||||
|
||||
- `json` – Entwicklung mit lokalen Mock-JSON-Dateien (editierbar)
|
||||
- `jsmock` – Simulation des Geräts mit einer JS-Datei, die `window`-Variablen setzt
|
||||
- `production` – Echte CPL-Hardware mit CGI-Platzhaltern (JS in HTML/JS-Dateien)
|
||||
|
||||
---
|
||||
|
||||
## 🧩 Datenfluss-Überblick (UML Diagramm)
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[NEXT_PUBLIC_CPL_MODE] --> B{Modus}
|
||||
|
||||
B -->|json| C[API: fetchDigitalOutputsAPIHandler]
|
||||
C --> D[JSON-Datei (editable)]
|
||||
|
||||
B -->|jsmock| E[fetchDigitalOutputsService()]
|
||||
E --> F[<script> digitalOutputsMockData.js]
|
||||
F --> G[window.win_da_state / bezeichnung]
|
||||
|
||||
B -->|production| H[fetchDigitalOutputsService()]
|
||||
H --> I[<script> /CPL/digitalOutputs.js]
|
||||
I --> J[window.win_da_state / bezeichnung]
|
||||
|
||||
D & G & J --> K[Redux Store / Slice]
|
||||
K --> L[Redux Selector]
|
||||
L --> M[UI: DigitalOutputsWidget.tsx]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Entscheidungshilfe
|
||||
|
||||
| Modus | Quelle | Vorteil | Änderbar |
|
||||
| ------------ | ------------------------------------------ | ---------------------------- | -------------- |
|
||||
| `json` | `/mocks/api/SERVICE/*.json` | Schnell editierbar & testbar | ✅ Ja |
|
||||
| `jsmock` | `/mocks/device-cgi-simulator/SERVICE/*.js` | Realistische Simulation | ❌ Nur per API |
|
||||
| `production` | `/public/CPL/*.js` | Reale Gerätedaten | ❌ Nein |
|
||||
|
||||
---
|
||||
|
||||
## 🔁 Aktualisierung der Daten
|
||||
|
||||
### json
|
||||
|
||||
- ✅ `POST /api/cpl/updateDigitalOutputsHandler`
|
||||
- 📂 Schreibt direkt in JSON-Datei (z. B. `digitaleAusgaengeMockData.json`)
|
||||
|
||||
### jsmock
|
||||
|
||||
- ✅ `GET /api/fake-cpl/updateDigitalOutputsHandler?id=3&value=1`
|
||||
- ✍️ Ändert `.js` Datei per Regex und überschreibt `win_da_state = [...]`
|
||||
|
||||
### production
|
||||
|
||||
- ❌ Gerät entscheidet – nur lesender Zugriff über `<script>`
|
||||
- ⚙️ Änderung über CGI-URL z. B. `/digitalOutputs.html?OUT3=1`
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Tipps
|
||||
|
||||
- Verwende `setInterval()` bei `jsmock` oder `production`, um regelmäßig `<script>` neu zu laden
|
||||
- Bei `json`: nutze Redux-Thunk + Service → API → JSON
|
||||
- `fetchDigitalOutputsService.ts` kapselt alle Unterschiede sauber ab
|
||||
|
||||
---
|
||||
|
||||
## 📁 Verzeichnisse
|
||||
|
||||
```
|
||||
/mocks/api/SERVICE/ # JSON-Dateien
|
||||
/public/CPLmockData/SERVICE/ # jsmock-Skripte
|
||||
/public/CPL/SERVICE/ # Geräteplatzhalter
|
||||
/pages/api/fake-cpl/ # GET/UPDATE API für jsmock
|
||||
/pages/api/cpl/ # JSON- und Gerätelogik
|
||||
/store/digitalOutputs/ # Redux-Slice & Thunk
|
||||
```
|
||||
|
||||
## 🧩 Redux-Flow Übersicht (Mermaid)
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Component: DigitalOutputsWidget] --> B[useEffect]
|
||||
B --> C[dispatch fetchDigitalOutputsThunk]
|
||||
C --> D[fetchDigitalOutputsService]
|
||||
D --> E{Moduswahl}
|
||||
E -->|json| F[API: /api/cpl/fetchDigitalOutputsAPIHandler]
|
||||
E -->|jsmock| G[<script> digitalOutputsMockData.js]
|
||||
E -->|production| H[<script> /CPL/digitalOutputs.js]
|
||||
|
||||
F & G & H --> I[Reducer: digitalOutputsSlice]
|
||||
I --> J[useSelector] --> A
|
||||
```
|
||||
91
docs/Architektur/README_digitalOutputs.md
Normal file
91
docs/Architektur/README_digitalOutputs.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# 📦 Datenfluss-Dokumentation: Digitale Ausgänge (Lesen & Schreiben)
|
||||
|
||||
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`
|
||||
- `production`: Reale CPL-Hardware über CGI-Platzhalter
|
||||
|
||||
---
|
||||
|
||||
## 🔁 Lesen der digitalen Ausgänge
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[DigitalOutputsWidget.tsx] --> B[useEffect]
|
||||
B --> C[dispatch fetchDigitalOutputsThunk]
|
||||
C --> D[fetchDigitalOutputsService]
|
||||
D --> E{Moduswahl: NEXT_PUBLIC_CPL_MODE}
|
||||
|
||||
E -->|json| F1[GET /api/cpl/fetchDigitalOutputsHandler.ts]
|
||||
F1 --> F2[digitalOutputsMockData.json]
|
||||
|
||||
E -->|jsmock| G1[GET /api/fake-cpl/fetchDigitalOutputsDeviceMockHandler]
|
||||
G1 --> G2[digitalOutputsMockData.js → window.win_da_state]
|
||||
|
||||
E -->|production| H1[loadScript '/CPL?/CPL/SERVICE/digitalOutputs.js']
|
||||
H1 --> H2[Platzhalter-basierte win_da_state]
|
||||
|
||||
F2 & G2 & H2 --> I[Redux: digitalOutputsSlice]
|
||||
I --> J[useSelector] --> A
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✍️ Updaten der digitalen Ausgänge
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[DigitalOutputsWidget.tsx: onToggle] --> B[handleToggle id]
|
||||
B --> C[Redux: setDigitalOutputs]
|
||||
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]
|
||||
F1 --> F2[Schreibe JSON oder JS-Datei]
|
||||
|
||||
F2 & E1 --> G[Aktualisierte Zustände am Gerät]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🌐 API-Endpunkte
|
||||
|
||||
| Route | Methode | Modus | Funktion |
|
||||
| ------------------------------------------------------- | -------- | ------------- | ----------------------------- |
|
||||
| `/api/cpl/fetchDigitalOutputsHandler.ts` | `GET` | `json` | Liest JSON-Datei |
|
||||
| `/api/fake-cpl/fetchDigitalOutputsDeviceMockHandler.ts` | `GET` | `jsmock` | Liest Mock-JS-Datei |
|
||||
| `/CPL?/CPL/SERVICE/digitalOutputs.js` | `SCRIPT` | `production` | Liefert Platzhalter vom Gerät |
|
||||
| `/api/cpl/updateDigitalOutputsHandler.ts` | `POST` | `json/jsmock` | Speichert Statusänderung |
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Beispiel-JSON (Mock)
|
||||
|
||||
```json
|
||||
{
|
||||
"win_da_state": [1, 0, 1, 0],
|
||||
"win_da_bezeichnung": ["Ausgang1", "Ausgang2", "Ausgang3", "Ausgang4"]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 Verzeichnisse
|
||||
|
||||
```
|
||||
/mocks/api/SERVICE/ → JSON-Dateien
|
||||
/mocks/device-cgi-simulator/SERVICE/→ jsmock: digitalOutputsMockData.js
|
||||
/public/CPL/SERVICE/ → production: digitalOutputs.js
|
||||
/pages/api/cpl/ → JSON-/Update-Handler
|
||||
/pages/api/fake-cpl/ → jsmock-API-Handler
|
||||
/components/main/einausgaenge/ → UI-Komponente: DigitalOutputsWidget.tsx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Status
|
||||
|
||||
- [x] Lesen funktioniert in allen Modi
|
||||
- [x] Schreiben funktioniert in allen Modi (production nur über Redirect)
|
||||
- [x] Redux-Integration ist vollständig
|
||||
14
mocks/api/SERVICE/digitalOutputsMockData.json
Normal file
14
mocks/api/SERVICE/digitalOutputsMockData.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"win_da_state": [
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0
|
||||
],
|
||||
"win_da_bezeichnung": [
|
||||
"Ausgang1",
|
||||
"Ausgang2",
|
||||
"Ausgang3",
|
||||
"Ausgang4"
|
||||
]
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"win_da_state": [
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0
|
||||
],
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
win_da_state = [1, 1, 1, 0];
|
||||
win_da_bezeichnung = ["Ausgang1", "Ausgang2", "Ausgang3", "Ausgang4"];
|
||||
@@ -1,2 +1,2 @@
|
||||
win_da_state = [1, 0, 1, 0];
|
||||
win_da_bezeichnung = ["Ausgang1", "Ausgang2", "Ausgang3", "Ausgang4"];
|
||||
win_da_bezeichnung = ["Ausgang11", "Ausgang2", "Ausgang3", "Ausgang4"];
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "cpl-v4",
|
||||
"version": "1.6.417",
|
||||
"version": "1.6.418",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "cpl-v4",
|
||||
"version": "1.6.417",
|
||||
"version": "1.6.418",
|
||||
"dependencies": {
|
||||
"@fontsource/roboto": "^5.1.0",
|
||||
"@iconify-icons/ri": "^1.2.10",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cpl-v4",
|
||||
"version": "1.6.417",
|
||||
"version": "1.6.418",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// /pages/api/cpl/analogeEingaengeAPIHandler.ts
|
||||
// /pages/api/cpl/getDigitalOutputsJsonHandler.ts
|
||||
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
import path from "path";
|
||||
@@ -13,7 +13,7 @@ export default async function handler(
|
||||
"mocks",
|
||||
"api",
|
||||
"SERVICE",
|
||||
"digitaleAusgaengeMockData.json"
|
||||
"digitalOutputsMockData.json"
|
||||
);
|
||||
|
||||
try {
|
||||
@@ -1,4 +1,4 @@
|
||||
// /pages/api/cpl/updateDigitalOutputs.ts
|
||||
// /pages/api/cpl/updateDigitalOutputshandler.ts
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
@@ -29,7 +29,7 @@ export default function handler(req, res) {
|
||||
"mocks",
|
||||
"api",
|
||||
"SERVICE",
|
||||
"digitaleAusgaengeMockData.json"
|
||||
"digitalOutputsMockData.json"
|
||||
);
|
||||
|
||||
try {
|
||||
@@ -46,9 +46,9 @@ export default function handler(req, res) {
|
||||
filePath = path.join(
|
||||
process.cwd(),
|
||||
"mocks",
|
||||
"js-simulator",
|
||||
"device-cgi-simulator",
|
||||
"SERVICE",
|
||||
"digitaleAusgaengeMockData.js"
|
||||
"digitalOutputsMockData.js"
|
||||
);
|
||||
|
||||
const jsContent =
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// /pages/api/fake-cpl/SERVICE/fetchDigitalOutputsAPIHandler.ts
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
export default function handler(req, res) {
|
||||
const filePath = path.join(
|
||||
process.cwd(),
|
||||
"mocks",
|
||||
"device-cgi-simulator",
|
||||
"SERVICE",
|
||||
"digitalOutputsMockData.js"
|
||||
);
|
||||
|
||||
try {
|
||||
const content = fs.readFileSync(filePath, "utf-8");
|
||||
|
||||
const win_da_state = extractArray(content, "win_da_state");
|
||||
const win_da_bezeichnung = extractArray(content, "win_da_bezeichnung");
|
||||
|
||||
return res.status(200).json({
|
||||
win_da_state,
|
||||
win_da_bezeichnung,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("❌ Fehler beim Lesen der JS-Mock-Datei:", err);
|
||||
return res.status(500).json({ error: "Fehler beim Lesen der Mock-Datei" });
|
||||
}
|
||||
}
|
||||
|
||||
// 🔧 Hilfsfunktion: Extrahiert Array aus JS-Datei
|
||||
function extractArray(content: string, varName: string): any[] {
|
||||
const match = content.match(
|
||||
new RegExp(`${varName}\\s*=\\s*\\[(.*?)\\];`, "s")
|
||||
);
|
||||
if (!match) {
|
||||
console.warn(`⚠️ ${varName} nicht gefunden`);
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(`[${match[1]}]`);
|
||||
} catch (e) {
|
||||
console.warn(`⚠️ Fehler beim Parsen von ${varName}:`, e);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
48
pages/api/fake-cpl/SERVICE/updateDigitalOutputsHandler.ts
Normal file
48
pages/api/fake-cpl/SERVICE/updateDigitalOutputsHandler.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
// /pages/api/fake-cpl/SERVICE/updateDigitalOutputsHandler.ts
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
export default function handler(req, res) {
|
||||
if (req.method !== "GET") {
|
||||
return res.status(405).json({ error: "Nur GET erlaubt" });
|
||||
}
|
||||
|
||||
const id = parseInt(req.query.id as string);
|
||||
const value = parseInt(req.query.value as string);
|
||||
|
||||
const filePath = path.join(
|
||||
process.cwd(),
|
||||
"mocks",
|
||||
"device-cgi-simulator",
|
||||
"SERVICE",
|
||||
"digitalOutputsMockData.js"
|
||||
);
|
||||
|
||||
try {
|
||||
let content = fs.readFileSync(filePath, "utf-8");
|
||||
|
||||
const match = content.match(/win_da_state\s*=\s*\[(.*?)\];/s);
|
||||
const currentState = match ? JSON.parse(`[${match[1]}]`) : [];
|
||||
|
||||
if (isNaN(id) || isNaN(value) || id < 1 || id > currentState.length) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ error: `Ungültige Parameter: id=${id}, value=${value}` });
|
||||
}
|
||||
|
||||
// Wert aktualisieren
|
||||
currentState[id - 1] = value;
|
||||
|
||||
const updatedContent =
|
||||
`win_da_state = [${currentState.join(", ")}];\n` +
|
||||
`win_da_bezeichnung = ["A1", "A2", "A3", "A4"]; // fest für Demo`;
|
||||
|
||||
fs.writeFileSync(filePath, updatedContent, "utf-8");
|
||||
|
||||
res.status(200).json({ success: true, win_da_state: currentState });
|
||||
} catch (err) {
|
||||
console.error("❌ Fehler beim Schreiben der Mock-Datei:", err);
|
||||
res.status(500).json({ error: "Fehler beim Schreiben der Mock-Datei" });
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,4 @@
|
||||
// /public/CPL/SERVICE/da.js
|
||||
//var win_da_state=[<%=DES80%>,<%=DES81%>,<%=DES82%>,<%=DES83%>]; // alte Platzhalter aber ich bekome noch die Werte
|
||||
// /public/CPL/SERVICE/digitalOutputs.js
|
||||
var win_da_state=[<%=DAS01%>,<%=DAS02%>,<%=DAS03%>,<%=DAS04%>];
|
||||
|
||||
//var win_da_bezeichnung=["Ausgang1", "Ausgang2", "Ausgang3", "Ausgang4"];
|
||||
|
||||
var win_da_state=[<%=DAS01%>,<%=DAS02%>,<%=DAS03%>,<%=DAS04%>]; //neu aber ein Leere Array mit 4 indizes , Backend ist noch in Arbeit
|
||||
|
||||
var win_da_bezeichnung=[<%=DAN01%>,<%=DAN02%>,<%=DAN03%>,<%=DAN04%>]; //neu aber ein Leere Array mit 4 indizes , Backend ist noch in Arbeit
|
||||
var win_da_bezeichnung=[<%=DAN01%>,<%=DAN02%>,<%=DAN03%>,<%=DAN04%>];
|
||||
@@ -4,7 +4,7 @@ export const fetchDigitalOutputsService = async () => {
|
||||
const mode = process.env.NEXT_PUBLIC_CPL_MODE;
|
||||
|
||||
if (mode === "json") {
|
||||
const res = await fetch("/api/cpl/digitalOutputsAPIHandler");
|
||||
const res = await fetch("/api/cpl/getDigitalOutputsJsonHandler");
|
||||
if (!res.ok)
|
||||
throw new Error("❌ Fehler beim Laden der digitalen Ausgänge (JSON)");
|
||||
|
||||
@@ -13,7 +13,7 @@ export const fetchDigitalOutputsService = async () => {
|
||||
const labels = data.win_da_bezeichnung;
|
||||
|
||||
if (!Array.isArray(state)) {
|
||||
console.warn("⚠️ win_da_state fehlt oder ist ungültig:", state);
|
||||
console.warn("⚠️ win_da_state fehlt oder ist ungültig in json:", state);
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -27,26 +27,43 @@ export const fetchDigitalOutputsService = async () => {
|
||||
}));
|
||||
}
|
||||
|
||||
// jsmock oder production
|
||||
let scriptUrl = "";
|
||||
|
||||
if (mode === "production") {
|
||||
scriptUrl = "/CPL?/CPL/SERVICE/digitalOutputs.js";
|
||||
} else if (mode === "jsmock") {
|
||||
scriptUrl = "/CPLmockData/SERVICE/digitalOutputsMockData.js";
|
||||
} else {
|
||||
console.warn(
|
||||
`⚠️ fetchDigitalOutputsFromScript wird nur in 'jsmock' oder 'production' verwendet (aktueller Modus: ${mode})`
|
||||
if (mode === "jsmock") {
|
||||
const res = await fetch(
|
||||
"/api/fake-cpl/SERVICE/getDigitalOutputsDeviceMockHandler"
|
||||
);
|
||||
if (!res.ok)
|
||||
throw new Error("❌ Fehler beim Laden der digitalen Ausgänge (jsmock)");
|
||||
|
||||
const data = await res.json();
|
||||
const state = data.win_da_state;
|
||||
const labels = data.win_da_bezeichnung;
|
||||
|
||||
if (!Array.isArray(state)) {
|
||||
console.warn("⚠️ win_da_state fehlt oder ist ungültig in jsmock:", state);
|
||||
return [];
|
||||
}
|
||||
|
||||
return state.slice(0, 4).map((status: number, index: number) => ({
|
||||
id: index + 1,
|
||||
label:
|
||||
Array.isArray(labels) && labels[index]
|
||||
? labels[index]
|
||||
: `Ausgang ${index + 1}`,
|
||||
status: status === 1,
|
||||
}));
|
||||
}
|
||||
|
||||
if (mode === "production") {
|
||||
// Hier erwarten wir eine echte Datei aus /public/CPL/
|
||||
const scriptUrl = "/CPL?/CPL/SERVICE/digitalOutputs.js";
|
||||
|
||||
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 der digitalOutputs.js");
|
||||
script.onerror = () =>
|
||||
reject("❌ Fehler beim Laden der digitalOutputs.js");
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
|
||||
@@ -67,4 +84,8 @@ export const fetchDigitalOutputsService = async () => {
|
||||
: `Ausgang ${index + 1}`,
|
||||
status: status === 1,
|
||||
}));
|
||||
}
|
||||
|
||||
console.warn(`⚠️ Unbekannter CPL-Modus: ${mode}`);
|
||||
return [];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user