feat: digitalOutputs separate jsSimulatedProd mode
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.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)
|
||||
@@ -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
|
||||
12
CHANGELOG.md
12
CHANGELOG.md
@@ -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
|
||||
|
||||
@@ -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
4
package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cpl-v4",
|
||||
"version": "1.6.442",
|
||||
"version": "1.6.443",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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" });
|
||||
|
||||
@@ -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 [];
|
||||
|
||||
Reference in New Issue
Block a user