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_EXPORT_STATIC=false
|
||||||
NEXT_PUBLIC_USE_CGI=false
|
NEXT_PUBLIC_USE_CGI=false
|
||||||
# App-Versionsnummer
|
# 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)
|
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_EXPORT_STATIC=true
|
||||||
NEXT_PUBLIC_USE_CGI=true
|
NEXT_PUBLIC_USE_CGI=true
|
||||||
# App-Versionsnummer
|
# App-Versionsnummer
|
||||||
NEXT_PUBLIC_APP_VERSION=1.6.442
|
NEXT_PUBLIC_APP_VERSION=1.6.443
|
||||||
NEXT_PUBLIC_CPL_MODE=production
|
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
|
## [1.6.442] – 2025-06-22
|
||||||
|
|
||||||
- docs: add full architecture diagram and data flow for json, jsmock and production modes
|
- 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_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",
|
"name": "cpl-v4",
|
||||||
"version": "1.6.442",
|
"version": "1.6.443",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "cpl-v4",
|
"name": "cpl-v4",
|
||||||
"version": "1.6.442",
|
"version": "1.6.443",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/roboto": "^5.1.0",
|
"@fontsource/roboto": "^5.1.0",
|
||||||
"@iconify-icons/ri": "^1.2.10",
|
"@iconify-icons/ri": "^1.2.10",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cpl-v4",
|
"name": "cpl-v4",
|
||||||
"version": "1.6.442",
|
"version": "1.6.443",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
|||||||
@@ -21,12 +21,12 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode === "jsSimulatedProd") {
|
if (mode === "jsSimulatedProd") {
|
||||||
const analogInputsScript = fs.readFileSync(
|
const digitalInputsScript = fs.readFileSync(
|
||||||
"mocks/device-cgi-simulator/SERVICE/digitalInputsMockData.js",
|
"mocks/device-cgi-simulator/SERVICE/digitalInputsMockData.js",
|
||||||
"utf-8"
|
"utf-8"
|
||||||
);
|
);
|
||||||
res.setHeader("Content-Type", "application/javascript");
|
res.setHeader("Content-Type", "application/javascript");
|
||||||
res.status(200).send(analogInputsScript);
|
res.status(200).send(digitalInputsScript);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import { NextApiRequest, NextApiResponse } from "next";
|
import { NextApiRequest, NextApiResponse } from "next";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
|
import { readFileSync } from "fs";
|
||||||
|
|
||||||
export default async function handler(
|
export default async function handler(
|
||||||
req: NextApiRequest,
|
req: NextApiRequest,
|
||||||
@@ -22,25 +23,12 @@ export default async function handler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode === "jsSimulatedProd") {
|
if (mode === "jsSimulatedProd") {
|
||||||
// Lese Datei und extrahiere window-Variablen aus .js-Datei
|
const digitalOutputsScript = readFileSync(
|
||||||
const filePath = path.join(
|
|
||||||
process.cwd(),
|
|
||||||
"mocks/device-cgi-simulator/SERVICE/digitalOutputsMockData.js"
|
"mocks/device-cgi-simulator/SERVICE/digitalOutputsMockData.js"
|
||||||
);
|
);
|
||||||
const fileContent = await fs.readFile(filePath, "utf-8");
|
res.setHeader("Content-Type", "application/javascript");
|
||||||
|
res.status(200).send(digitalOutputsScript);
|
||||||
const stateMatch = fileContent.match(/win_da_state\s*=\s*\[([^\]]*)\]/);
|
return;
|
||||||
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 });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.status(400).json({ error: "Unsupported mode" });
|
return res.status(400).json({ error: "Unsupported mode" });
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export const fetchDigitalOutputsService = async () => {
|
|||||||
status: status === 1,
|
status: status === 1,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
} else if (mode === "json" || mode === "jsSimulatedProd") {
|
} else if (mode === "json") {
|
||||||
const res = await fetch("/api/cpl/getDigitalOutputsHandler");
|
const res = await fetch("/api/cpl/getDigitalOutputsHandler");
|
||||||
|
|
||||||
if (!res.ok) {
|
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 {
|
} else {
|
||||||
console.warn(`⚠️ Unbekannter Modus: ${mode}`);
|
console.warn(`⚠️ Unbekannter Modus: ${mode}`);
|
||||||
return [];
|
return [];
|
||||||
|
|||||||
Reference in New Issue
Block a user