feat: CGI-kompatiblen CSV-Parser für digitale Eingänge implementiert

- digitaleInputsMockData.json angepasst: CGI-nahe Simulation mit CSV-Strings und Stringwerten
- fetchDigitalInputsService.ts erweitert:
  - CSV-Zeilen werden automatisch in Arrays umgewandelt
  - Labels wie "'DE1','DE2'" werden korrekt aufgeteilt
  - Daten aus 4 CGI-Blöcken zu 32 Eingängen gemappt
- ermöglicht realitätsnahe Tests in Entwicklungsumgebung ohne Produktion
This commit is contained in:
ISA
2025-07-09 08:41:50 +02:00
parent 7797549baa
commit 14bd72756a
13 changed files with 155 additions and 548 deletions

View File

@@ -6,6 +6,6 @@ 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.565 NEXT_PUBLIC_APP_VERSION=1.6.566
NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter) NEXT_PUBLIC_CPL_MODE=json # 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_EXPORT_STATIC=true
NEXT_PUBLIC_USE_CGI=true NEXT_PUBLIC_USE_CGI=true
# App-Versionsnummer # App-Versionsnummer
NEXT_PUBLIC_APP_VERSION=1.6.565 NEXT_PUBLIC_APP_VERSION=1.6.566
NEXT_PUBLIC_CPL_MODE=production NEXT_PUBLIC_CPL_MODE=production

View File

@@ -1,3 +1,14 @@
## [1.6.566] 2025-07-09
- feat: Umstellung von CGI-Daten für analoge Eingänge von JS auf JSON
- CGI-Platzhalter in `analogInputs.json` eingeführt (z.B. <%=AAV01%>)
- Alte JS-Datei ersetzt durch reine JSON-Struktur
- Anpassung des Service-Handlers (`getAnalogInputsHandler.ts`) auf JSON-Parsing
- Reduziert Ladezeit, vereinfacht Code und entfernt unnötige Script-Einbindung
- Mock-Daten weiterhin in `analogInputsMockData.json` für Entwicklungsmodus verfügbar
---
## [1.6.565] 2025-07-08 ## [1.6.565] 2025-07-08
- Bei den Kabelüberwachung kann neben den Button “Firmware Update” noch zwei Button “Konfiguration sichern” und “Konfiguration zurücksichern” im Admin-Modus hinzukommen. - Bei den Kabelüberwachung kann neben den Button “Firmware Update” noch zwei Button “Konfiguration sichern” und “Konfiguration zurücksichern” im Admin-Modus hinzukommen.

View File

@@ -1,274 +0,0 @@
{
"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
],
"win_de_invert": [
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
],
"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
],
"win_de_time_filter": [
1,
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
],
"win_de_weighting": [
3,
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
],
"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
],
"win_de_offline": [
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
],
"win_de_label": [
"DE1",
"DE2",
"DE3",
"DE4",
"DE5",
"DE6",
"DE7",
"DE8",
"DE9",
"DE10",
"DE11",
"DE12",
"DE13",
"DE14",
"DE15",
"DE16",
"DE17",
"DE18",
"DE19",
"DE20",
"DE21",
"DE22",
"DE23",
"DE24",
"DE25",
"DE26",
"DE27",
"DE28",
"DE29",
"DE30",
"DE31",
"DE32"
]
}

View File

@@ -1,63 +0,0 @@
// 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,
];
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,
];
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,
];
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,
];
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,
];
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,
];
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,
];
var win_de_label = [
"DE1",
"DE2",
"DE3",
"DE4",
"DE5",
"DE6",
"DE7",
"DE8",
"DE9",
"DE10",
"DE11",
"DE12",
"DE13",
"DE14",
"DE15",
"DE16",
"DE17",
"DE18",
"DE19",
"DE20",
"DE21",
"DE22",
"DE23",
"DE24",
"DE25",
"DE26",
"DE27",
"DE28",
"DE29",
"DE30",
"DE31",
"DE32",
];

View File

@@ -1,64 +1,50 @@
{ {
"win_de_state": [ "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,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",
"win_de_invert": [ "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
],
"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
],
"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
],
"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
],
"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
],
"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
], ],
"win_de_label": [ "win_de_label": [
"DE1", "'DE 1','DE 2','DE 3','DE 4','DE 5','DE 6','DE 7','DE 8'",
"DE2", "'DE 9','DE 10','DE 11','DE 12','DE 13','DE 14','DE 15','DE 16'",
"DE3", "'DE 17','DE 18','DE 19','DE 20','DE 21','DE 22','DE 23','DE 24'",
"DE4", "'DE 25','DE 26','DE 27','DE 28','DE 29','DE 30','DE 31','DE 32'"
"DE5", ],
"DE6", "win_de_counter": [
"DE7", "0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000",
"DE8", "0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000",
"DE9", "0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000",
"DE10", "0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000"
"DE11", ],
"DE12", "win_de_time_filter": [
"DE13", "598.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000",
"DE14", "0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000",
"DE15", "0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000",
"DE16", "0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000"
"DE17", ],
"DE18", "win_de_weighting": [
"DE19", "998,0,0,0,0,0,0,0",
"DE20", "0,0,0,0,0,0,0,0",
"DE21", "0,0,0,0,0,0,0,0",
"DE22", "0,0,0,0,0,0,0,0"
"DE23", ],
"DE24", "win_de_invert": [
"DE25", "1,0,0,0,0,0,0,0",
"DE26", "0,0,0,0,0,0,0,0",
"DE27", "0,0,0,0,0,0,0,0",
"DE28", "0,0,0,0,0,0,0,0"
"DE29", ],
"DE30", "win_de_counter_active": [
"DE31", "0,0,0,0,0,0,0,0",
"DE32" "0,0,0,0,0,0,0,0",
"0,0,0,0,0,0,0,0",
"0,0,0,0,0,0,0,0"
],
"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"
] ]
} }

View File

@@ -8,7 +8,12 @@ const nextConfig = {
images: { images: {
unoptimized: true, unoptimized: true,
}, },
...(isExport && { output: "export" }), // ⬅️ dynamisch aktivieren ...(isExport && { output: "export" }),
// 🔧 HINZUGEFÜGT:
env: {
NEXT_PUBLIC_CPL_MODE: process.env.NEXT_PUBLIC_CPL_MODE,
},
}; };
export default nextConfig; export default nextConfig;

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.565", "version": "1.6.566",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.565", "version": "1.6.566",
"dependencies": { "dependencies": {
"@fontsource/roboto": "^5.1.0", "@fontsource/roboto": "^5.1.0",
"@headlessui/react": "^2.2.4", "@headlessui/react": "^2.2.4",

View File

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

View File

@@ -11,7 +11,7 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) {
const filePath = path.join( const filePath = path.join(
process.cwd(), process.cwd(),
"mocks", "mocks",
"api", "device-cgi-simulator",
"SERVICE", "SERVICE",
"digitalInputsMockData.json" "digitalInputsMockData.json"
); );
@@ -20,16 +20,6 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) {
return res.status(200).json(json); return res.status(200).json(json);
} }
if (mode === "jsSimulatedProd") {
const digitalInputsScript = fs.readFileSync(
"mocks/device-cgi-simulator/SERVICE/digitalInputsMockData.js",
"utf-8"
);
res.setHeader("Content-Type", "application/javascript");
res.status(200).send(digitalInputsScript);
return;
}
return res.status(400).json({ error: "Ungültiger Modus" }); return res.status(400).json({ error: "Ungültiger Modus" });
} catch (error) { } catch (error) {
console.error("❌ Fehler beim Parsen der digitalen Eingänge:", error); console.error("❌ Fehler beim Parsen der digitalen Eingänge:", error);

View File

@@ -1,40 +0,0 @@
// Zustand -> DESxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
var win_de_state=[<%=DES80%>,<%=DES81%>,<%=DES82%>,<%=DES83%>];//Zustand des digitalen Eingangs 1 = EIN, 0 = AUS
// Name -> DENxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
var win_de_label =[<%=DEN80%>,<%=DEN81%>,<%=DEN82%>,<%=DEN83%>];
//Zählerstand -> DESxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
var win_de_counter=[<%=DEC80%>,<%=DEC81%>,<%=DEC82%>,<%=DEC83%>];//Zählerstand
//Filterzeit -> DEFxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
var win_de_time_filter=[<%=DEF80%>,<%=DEF81%>,<%=DEF82%>,<%=DEF83%>];//Filterzeit
// Gewichtung -> DEGxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4
var win_de_weighting=[<%=DEG80%>,<%=DEG81%>,<%=DEG82%>,<%=DEG83%>];//Gewichtung
// Invertierung -> DEIxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4
var win_de_invert=[<%=DEI80%>,<%=DEI81%>,<%=DEI82%>,<%=DEI83%>];//Invertierung
// Zähler aktiv -> DEZxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4
var win_de_counter_active=[<%=DEZ80%>,<%=DEZ81%>,<%=DEZ82%>,<%=DEZ83%>];//Zähler aktiv
// Eingang offline -> DEAxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4
var win_de_offline=[<%=DEA80%>,<%=DEA81%>,<%=DEA82%>,<%=DEA83%>];//Eingang offline
//DECxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
//var win_flutter=[<%=DEF80%>,<%=DEF80%>,<%=DEF81%>,<%=DEF82%>];// noch nicht verwendet in Lastheft Oktober 2024
/* von https://10.10.0.222/CPL?Service/de.ACP
var de=[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 counter=[0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000];
var flutter=[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 de=[1,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];
var counter=[0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000];
var flutter=[0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000];
*/

View File

@@ -14,7 +14,13 @@ export const getDigitalInputsThunk = createAsyncThunk(
try { try {
const data = await fetchDigitalInputsService(); const data = await fetchDigitalInputsService();
if (data) { if (data) {
dispatch(setInputs(data)); // ✅ Redux mit API-Daten füllen // Map data to ensure all DigitalInput properties are present
const mappedData = data.map((item: any) => ({
...item,
flutter: item.flutter ?? false,
zaehlerAktiv: item.zaehlerAktiv ?? false,
}));
dispatch(setInputs(mappedData)); // ✅ Redux mit API-Daten füllen
} }
} catch (error) { } catch (error) {
console.error("❌ Fehler beim Laden der digitalen Eingänge:", error); console.error("❌ Fehler beim Laden der digitalen Eingänge:", error);

View File

@@ -1,109 +1,95 @@
// ✅ Service: /services/fetchDigitalInputsService.ts export interface DigitalInput {
id: number;
value: number | string;
label: string;
invert: boolean;
counter: number | string;
timeFilter: number | string;
weighting: number | string;
counterActive: boolean;
eingangOffline: boolean;
status: boolean;
flutter: boolean;
zaehlerAktiv: boolean;
}
export const fetchDigitalInputsService = async () => { // 🧠 Neu: CSV-Zeile wie "1,0,1,0" in [1,0,1,0] konvertieren
const mode = process.env.NEXT_PUBLIC_CPL_MODE; const parseCsvNumbers = (line: string): number[] =>
line.split(",").map((v) => Number(v.trim()));
// ✅ PRODUKTIV: lädt JavaScript vom Gerät über CGI // 🧠 Neu: CSV-Zeile wie "'DE1','DE2'" in ["DE1", "DE2"] umwandeln
if (mode === "production") { const parseCsvLabels = (line: string): string[] =>
console.log("🔄 Lade analoge Eingänge im Produktionsmodus..."); line.split(",").map((v) => v.trim().replace(/^'+|'+$/g, ""));
const scriptUrl = "/CPL?/CPL/SERVICE/digitalInputs.js";
await new Promise<void>((resolve, reject) => { export const fetchDigitalInputsService = async (): Promise<DigitalInput[]> => {
const script = document.createElement("script"); const mode = "production"; // ⛳ production oder json
script.src = scriptUrl;
script.async = true;
script.onload = () => resolve();
script.onerror = () =>
reject("❌ Fehler beim Laden der digitalen Eingänge (production)");
document.body.appendChild(script);
});
const win = window as any; const url =
mode === "production"
? "/CPL?/CPL/SERVICE/digitalInputs.json"
: "/api/cpl/getDigitalInputsHandler";
return Array.from({ length: 32 }, (_, i) => ({ const res = await fetch(url);
id: i + 1, if (!res.ok) {
value: win.win_de_state[i], throw new Error(`❌ Fehler beim Laden der digitalen Eingänge (${mode})`);
label: win.win_de_label[i],
invert: !!win.win_de_invert[i],
counter: win.win_de_counter[i],
timeFilter: win.win_de_time_filter[i],
weighting: win.win_de_weighting[i],
counterActive: !!win.win_de_counter_active[i],
eingangOffline: !!win.win_de_offline[i],
status: !!win.win_de_state[i],
}));
} }
// ✅ JSON-MODUS (API gibt JSON-Daten zurück) const data = await res.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)");
const data = await res.json(); // 🧠 Neu: CSV-Zeilen in Arrays umwandeln
console.log("📡 JSON-Daten geladen in service:", data); const state = data.win_de_state.flatMap(parseCsvNumbers);
return data.win_de_state.map((_: any, i: number) => ({ const label = data.win_de_label.flatMap(parseCsvLabels);
id: i + 1, const invert = data.win_de_invert.flatMap(parseCsvNumbers);
value: data.win_de_state[i], const counter = data.win_de_counter.flatMap((line: string) =>
label: data.win_de_label[i], line.split(",").map((v) => v.trim())
invert: !!data.win_de_invert[i], );
counter: data.win_de_counter[i], const timeFilter = data.win_de_time_filter.flatMap((line: string) =>
timeFilter: data.win_de_time_filter[i], line.split(",").map((v) => v.trim())
weighting: data.win_de_weighting[i], );
counterActive: !!data.win_de_counter_active[i], const weighting = data.win_de_weighting.flatMap((line: string) =>
eingangOffline: !!data.win_de_offline[i], line.split(",").map((v) => v.trim())
status: !!data.win_de_state[i], );
})); const counterActive = data.win_de_counter_active.flatMap(parseCsvNumbers);
const offline = data.win_de_offline.flatMap(parseCsvNumbers);
interface CsvData {
state: number[];
label: string[];
invert: number[];
counter: (number | string)[];
timeFilter: (number | string)[];
weighting: (number | string)[];
counterActive: number[];
offline: number[];
} }
// ✅ jsSimulatedProd-MODUS (Script einbinden und aus window lesen) // Removed redundant DigitalInputResult interface
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
await new Promise<void>((resolve, reject) => { const csvData: CsvData = {
const script = document.createElement("script"); state,
script.src = scriptUrl; label,
script.async = true; invert,
script.onload = () => resolve(); counter,
script.onerror = () => timeFilter,
reject("❌ Fehler beim Laden des simulierten Scripts"); weighting,
document.body.appendChild(script); counterActive,
}); offline,
};
// Annahme: Das Script setzt window.win_de_state usw. return csvData.state.map(
const data = { (_, i): DigitalInput => ({
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, id: i + 1,
value: data.win_de_state[i], value: csvData.state[i],
label: data.win_de_label[i], label: csvData.label[i],
invert: !!data.win_de_invert[i], invert: !!csvData.invert[i],
counter: data.win_de_counter[i], counter: csvData.counter[i],
timeFilter: data.win_de_time_filter[i], timeFilter: csvData.timeFilter[i],
weighting: data.win_de_weighting[i], weighting: csvData.weighting[i],
counterActive: !!data.win_de_counter_active[i], counterActive: !!csvData.counterActive[i],
eingangOffline: !!data.win_de_offline[i], eingangOffline: !!csvData.offline[i],
status: !!data.win_de_state[i], status: !!csvData.state[i],
})); flutter: false,
} zaehlerAktiv: false,
})
// ❌ Unbekannter Modus );
throw new Error(`❌ Unbekannter NEXT_PUBLIC_CPL_MODE: ${mode}`);
}; };