Digitale Eingänge Update mit Mock daten in der Entwicklungsumgebung

This commit is contained in:
ISA
2025-04-24 11:11:04 +02:00
parent eddf293ce2
commit 0b63579d56
7 changed files with 365 additions and 72 deletions

View File

@@ -1,68 +1,243 @@
// apiMockData/SERVICE/digitaleEingaengeMockData.js
// Zustand -> DESxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4 // auto-generated from update API
var win_de_state = [ 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, 1,
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,
0
]; ];
// Invertierung -> DEIxx xx = Nr Eingang 1-32
var win_de_invert = [ var win_de_invert = [
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, 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
]; ];
/*
✅ Logik für Farbe abhängig von Status + Invertierung:
Anzeige ist rot wenn Status=1 ist. Die Farbe ist nicht abhängig von der Invertierung.
Status Invertierung Anzeige
1 1 🔴 rot
1 0 🔴 rot
0 1 ✅ grün
0 0 ✅ grün
*/
//Zählerstand -> DESxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
var win_de_counter = [ 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.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, 0.0, 0,
]; //Zählerstand 0,
0,
//Filterzeit -> DEFxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4 0,
// Frage: In digitale Eingänge Filterzeit DEFxx (In Lastenheft) und Flatter var flutter DEFxx ist ein und das selbe, welche Begriff soll ich nehmen? 0,
// Antwort: Es ist die Filterzeit. Die Flatterzeit kommt später hinzu. 0,
var win_de_time_filter = [ 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,
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.0, 0.0, 0,
]; //Filterzeit 0,
0,
// Gewichtung -> DEGxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4 0,
var win_de_weighting = [ 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, 0, 0, 0,
]; //Gewichtung 0,
0,
// Zähler aktiv -> DEZxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4 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, 0, 0, 0,
]; //Zähler aktiv 0,
0,
// Eingang offline -> DEAxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4 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, 0, 0, 0,
]; //Eingang offline 0,
0
// Zähler aktiv -> DEZxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4 ];
var win_counter = [ var win_de_time_filter = [
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.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, 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_weighting = [
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_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
]; ];
// Name -> DENxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
var win_de_label = [ var win_de_label = [
"DE1", "DE1",
"DE2", "DE2",
@@ -95,12 +270,5 @@ var win_de_label = [
"DE29", "DE29",
"DE30", "DE30",
"DE31", "DE31",
"DE32", "DE32"
]; ];
// Frage: In digitale Eingänge Filterzeit DEFxx (In Lastenheft) und Flatter var flutter DEFxx ist ein und das selbe, welche Begriff soll ich nehmen?
// Antwort: Es ist die Filterzeit. Die Flatterzeit kommt später hinzu.
/* var win_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,
]; */

View File

@@ -1,4 +1,5 @@
"use client"; "use client";
// /components/main/einausgaenge/DigitalInputs.tsx
import React from "react"; import React from "react";
import { Icon } from "@iconify/react"; import { Icon } from "@iconify/react";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";

View File

@@ -27,16 +27,36 @@ export default function InputModal({ selectedInput, closeInputModal, isOpen }) {
if (!isOpen || !selectedInput || !reduxInput) return null; if (!isOpen || !selectedInput || !reduxInput) return null;
const handleInvertierungToggle = () => { const handleInvertierungToggle = async () => {
const neueInvertierung = !invertiert; const neueInvertierung = !invertiert;
setInvertiert(neueInvertierung);
dispatch( dispatch(
updateInvertierung({ id: reduxInput.id, invertierung: neueInvertierung }) updateInvertierung({ id: reduxInput.id, invertierung: neueInvertierung })
); );
setInvertiert(neueInvertierung);
// Update Mock-API
await fetch("/api/cpl/updateDigitaleEingaenge", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
id: reduxInput.id,
invertierung: neueInvertierung ? 1 : 0,
}),
});
}; };
const handleNameSpeichern = () => { const handleNameSpeichern = async () => {
dispatch(updateName({ id: reduxInput.id, name })); dispatch(updateName({ id: reduxInput.id, name }));
// Update Mock-API
await fetch("/api/cpl/updateDigitaleEingaenge", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
id: reduxInput.id,
name: name,
}),
});
}; };
return ( return (

View File

@@ -6,5 +6,5 @@
2: Patch oder Hotfix (Bugfixes oder kleine Änderungen). 2: Patch oder Hotfix (Bugfixes oder kleine Änderungen).
*/ */
const webVersion = "1.6.267"; const webVersion = "1.6.268";
export default webVersion; export default webVersion;

View File

@@ -0,0 +1,87 @@
// /pages/api/cpl/updateDigitaleEingaenge.ts
import type { NextApiRequest, NextApiResponse } from "next";
import path from "path";
import fs from "fs";
// WICHTIG: Der Mock-Datenpfad
const mockFilePath = path.join(
process.cwd(),
"apiMockData",
"SERVICE",
"digitaleEingaengeMockData.js"
);
// Funktion zum Parsen des JS-Datei-Inhalts in ein eval-fähiges Objekt
function extractMockData(raw: string) {
const context = {};
const func = new Function(
"context",
`
with (context) {
${raw}
return {
win_de_label,
win_de_invert,
win_de_state,
win_de_counter,
win_de_time_filter,
win_de_weighting,
win_de_counter_active,
win_de_offline
};
}
`
);
return func({});
}
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== "POST") {
return res.status(405).json({ error: "Only POST supported" });
}
try {
const { id, name, invertierung } = req.body;
if (typeof id !== "number" || id < 1 || id > 32) {
return res.status(400).json({ error: "Ungültige ID (132 erlaubt)" });
}
const rawContent = fs.readFileSync(mockFilePath, "utf-8");
const data = extractMockData(rawContent);
// Update der Daten
if (typeof name === "string") data.win_de_label[id - 1] = name;
if (typeof invertierung === "number")
data.win_de_invert[id - 1] = invertierung;
// Erzeuge neuen Dateiinhalt
const newContent = `
// auto-generated from update API
var win_de_state = ${JSON.stringify(data.win_de_state, null, 2)};
var win_de_invert = ${JSON.stringify(data.win_de_invert, null, 2)};
var win_de_counter = ${JSON.stringify(data.win_de_counter, null, 2)};
var win_de_time_filter = ${JSON.stringify(data.win_de_time_filter, null, 2)};
var win_de_weighting = ${JSON.stringify(data.win_de_weighting, null, 2)};
var win_de_counter_active = ${JSON.stringify(
data.win_de_counter_active,
null,
2
)};
var win_de_offline = ${JSON.stringify(data.win_de_offline, null, 2)};
var win_de_label = ${JSON.stringify(data.win_de_label, null, 2)};
`;
fs.writeFileSync(mockFilePath, newContent, "utf-8");
return res
.status(200)
.json({ message: "Update erfolgreich", id, name, invertierung });
} catch (err: any) {
console.error("Fehler beim Schreiben:", err);
return res.status(500).json({ error: "Update fehlgeschlagen" });
}
}

View File

@@ -1,4 +1,5 @@
"use client"; "use client";
// /pages/digitalInputs.tsx
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { AppDispatch, RootState } from "../redux/store"; import { AppDispatch, RootState } from "../redux/store";

View File

@@ -50,9 +50,25 @@ const digitalInputsSlice = createSlice({
input.invertierung = invertierung; input.invertierung = invertierung;
} }
}, },
updateName: (
state,
action: PayloadAction<{ id: number; name: string }>
) => {
const { id, name } = action.payload;
const input = state.inputs.find((input) => input.id === id);
if (input) {
input.name = name;
input.label = name; // falls du label mit aktualisieren willst
}
},
}, },
}); });
export const { setInputs, updateInputStatus, updateInvertierung } = export const {
digitalInputsSlice.actions; setInputs,
updateInputStatus,
updateInvertierung,
updateName, // <- hinzufügen
} = digitalInputsSlice.actions;
export default digitalInputsSlice.reducer; export default digitalInputsSlice.reducer;