feat: digitalOutputs separate jsSimulatedProd mode

This commit is contained in:
Ismail Ali
2025-06-22 09:46:13 +02:00
parent 041bc3e23e
commit ff3f418636
9 changed files with 44 additions and 26 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.442
NEXT_PUBLIC_APP_VERSION=1.6.443
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.442
NEXT_PUBLIC_APP_VERSION=1.6.443
NEXT_PUBLIC_CPL_MODE=production

View File

@@ -1,3 +1,15 @@
## [1.6.443] 2025-06-22
- 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`
---
## [1.6.442] 2025-06-22
- docs: add full architecture diagram and data flow for json, jsmock and production modes

View File

@@ -1,2 +1,2 @@
win_da_state = [1, 1, 1, 1];
win_da_bezeichnung = ["Ausgang1", "Ausgang2", "Ausgang3", "Ausgang4"];
win_da_bezeichnung = ["Ausgang2", "Ausgang2", "Ausgang3", "Ausgang4"];

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "cpl-v4",
"version": "1.6.442",
"version": "1.6.443",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "cpl-v4",
"version": "1.6.442",
"version": "1.6.443",
"dependencies": {
"@fontsource/roboto": "^5.1.0",
"@iconify-icons/ri": "^1.2.10",

View File

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

View File

@@ -21,12 +21,12 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) {
}
if (mode === "jsSimulatedProd") {
const analogInputsScript = fs.readFileSync(
const digitalInputsScript = fs.readFileSync(
"mocks/device-cgi-simulator/SERVICE/digitalInputsMockData.js",
"utf-8"
);
res.setHeader("Content-Type", "application/javascript");
res.status(200).send(analogInputsScript);
res.status(200).send(digitalInputsScript);
return;
}

View File

@@ -3,6 +3,7 @@
import { NextApiRequest, NextApiResponse } from "next";
import path from "path";
import fs from "fs/promises";
import { readFileSync } from "fs";
export default async function handler(
req: NextApiRequest,
@@ -22,25 +23,12 @@ export default async function handler(
}
if (mode === "jsSimulatedProd") {
// Lese Datei und extrahiere window-Variablen aus .js-Datei
const filePath = path.join(
process.cwd(),
const digitalOutputsScript = readFileSync(
"mocks/device-cgi-simulator/SERVICE/digitalOutputsMockData.js"
);
const fileContent = await fs.readFile(filePath, "utf-8");
const stateMatch = fileContent.match(/win_da_state\s*=\s*\[([^\]]*)\]/);
const labelMatch = fileContent.match(
/win_da_bezeichnung\s*=\s*\[([^\]]*)\]/
);
const win_da_state =
stateMatch?.[1]?.split(",").map((x) => parseInt(x.trim())) || [];
const win_da_bezeichnung =
labelMatch?.[1]?.split(",").map((x) => x.trim().replace(/["']/g, "")) ||
[];
return res.status(200).json({ win_da_state, win_da_bezeichnung });
res.setHeader("Content-Type", "application/javascript");
res.status(200).send(digitalOutputsScript);
return;
}
return res.status(400).json({ error: "Unsupported mode" });

View File

@@ -33,7 +33,7 @@ export const fetchDigitalOutputsService = async () => {
status: status === 1,
}));
}
} else if (mode === "json" || mode === "jsSimulatedProd") {
} else if (mode === "json") {
const res = await fetch("/api/cpl/getDigitalOutputsHandler");
if (!res.ok) {
@@ -57,6 +57,24 @@ export const fetchDigitalOutputsService = async () => {
}));
}
}
} else if (mode === "jsSimulatedProd") {
console.log("🔄 Lade simulierte analoge Eingänge im Produktionsmodus...");
const scriptUrl = "/api/cpl/getDigitalOutputsHandler"; // 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: 4 }, (_, i) => ({
id: i + 1,
label: win.win_da_bezeichnung[i] || `Ausgang ${i + 1}`,
status: win.win_da_state[i] === 1,
}));
} else {
console.warn(`⚠️ Unbekannter Modus: ${mode}`);
return [];