refactor: lade OPC UA Daten direkt in NetworkInfo-Komponente statt global in _app.tsx

- Thunk `fetchOpcUaSettingsThunk` wird jetzt nur bei Anzeige von NetworkInfo ausgeführt
- Reduzierte Netzwerklast und bessere Trennung von Zuständigkeiten
- Entfernt globalen OPC UA-Aufruf aus _app.tsx
This commit is contained in:
ISA
2025-03-26 10:45:00 +01:00
parent 0bbc2a25a6
commit 7b85ebc730
9 changed files with 59 additions and 100 deletions

View File

@@ -1,9 +1,16 @@
"use client"; //components/main/uebersicht/NetworkInfo.tsx "use client"; //components/main/uebersicht/NetworkInfo.tsx
import React from "react"; import React, { useEffect } from "react";
import { useSelector } from "react-redux"; import { useSelector, useDispatch } from "react-redux";
import { RootState } from "../../../redux/store"; import { RootState, AppDispatch } from "../../../redux/store";
import { fetchOpcUaSettingsThunk } from "../../../redux/thunks/fetchOpcUaSettingsThunk";
const NetworkInfo: React.FC = () => { const NetworkInfo: React.FC = () => {
const dispatch: AppDispatch = useDispatch();
// ✅ OPC UA Daten laden, wenn Komponente angezeigt wird
useEffect(() => {
dispatch(fetchOpcUaSettingsThunk());
}, [dispatch]);
// Werte direkt aus Redux holen // Werte direkt aus Redux holen
const ip = const ip =
useSelector((state: RootState) => state.systemSettings.ip) || "Unbekannt"; useSelector((state: RootState) => state.systemSettings.ip) || "Unbekannt";

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.164"; const webVersion = "1.6.165";
export default webVersion; export default webVersion;

View File

@@ -34,9 +34,6 @@ function AppContent({ Component, pageProps }: AppProps) {
//console.log("✅ Window-Variablen geladen:", variables); //console.log("✅ Window-Variablen geladen:", variables);
const { const {
opcUaZustand,
opcUaActiveClientCount,
opcUaNodesetName,
deviceName, deviceName,
mac1, mac1,
ip, ip,
@@ -67,6 +64,7 @@ function AppContent({ Component, pageProps }: AppProps) {
return () => clearInterval(intervalId); return () => clearInterval(intervalId);
} }
}, []); }, []);
//--------------------------------------------------------- //---------------------------------------------------------
return ( return (

View File

@@ -1,22 +0,0 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
interface TestState {
testData: any[];
}
const initialState: TestState = {
testData: [],
};
const testSlice = createSlice({
name: "test",
initialState,
reducers: {
setTestData: (state, action: PayloadAction<any[]>) => {
state.testData = action.payload;
},
},
});
export const { setTestData } = testSlice.actions;
export default testSlice.reducer;

View File

@@ -1,3 +1,4 @@
// /redux/thunks/fetchLast20MessagesThunk.ts
import { createAsyncThunk } from "@reduxjs/toolkit"; import { createAsyncThunk } from "@reduxjs/toolkit";
import { fetchLast20MessagesFromWindow } from "../../services/fetchLast20Messages"; import { fetchLast20MessagesFromWindow } from "../../services/fetchLast20Messages";
import { setLast20Messages } from "../slices/last20MessagesSlice"; import { setLast20Messages } from "../slices/last20MessagesSlice";

View File

@@ -0,0 +1,24 @@
// ✅ 2. Thunk: /redux/thunks/fetchOpcUaSettingsThunk.ts
import { createAsyncThunk } from "@reduxjs/toolkit";
import { fetchOpcUaSettings } from "../../services/fetchOpcUaSettings";
import {
setOpcUaZustand,
setOpcUaEncryption,
setOpcUaActiveClientCount,
setOpcUaNodesetName,
setOpcUaUsers,
} from "../slices/opcuaSettingsSlice";
export const fetchOpcUaSettingsThunk = createAsyncThunk(
"opcuaSettings/fetch",
async (_, { dispatch }) => {
const data = await fetchOpcUaSettings();
if (!data) return;
dispatch(setOpcUaZustand(data.zustand));
dispatch(setOpcUaEncryption(data.encryption));
dispatch(setOpcUaActiveClientCount(data.clientCount));
dispatch(setOpcUaNodesetName(data.nodesetName));
dispatch(setOpcUaUsers(data.users));
}
);

View File

@@ -1,3 +1,4 @@
// /services/fetchLast20Messages.ts
export async function fetchLast20MessagesFromWindow(): Promise<string | null> { export async function fetchLast20MessagesFromWindow(): Promise<string | null> {
return new Promise((resolve) => { return new Promise((resolve) => {
if (typeof window !== "undefined" && (window as any).win_last20Messages) { if (typeof window !== "undefined" && (window as any).win_last20Messages) {

View File

@@ -0,0 +1,21 @@
// ✅ 1. Service: /services/fetchOpcUaSettings.ts
export const fetchOpcUaSettings = async () => {
try {
const win = window as any;
if (!win) return null;
const data = {
zustand: win.win_opcUaZustand || "Offline",
encryption: win.win_opcUaEncryption || "None",
clientCount: win.win_opcUaActiveClientCount || 0,
nodesetName: win.win_opcUaNodesetName || "DefaultNodeset",
users: Array.isArray(win.win_opcUaUsers) ? win.win_opcUaUsers : [],
};
return data;
} catch (error) {
console.error("Fehler beim Laden der OPC UA Daten:", error);
return null;
}
};

View File

@@ -46,7 +46,6 @@ interface OpcUaSettings {
export async function loadWindowVariables(): Promise<Record<string, any>> { export async function loadWindowVariables(): Promise<Record<string, any>> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const requiredVars: string[] = [ const requiredVars: string[] = [
"win_last20Messages",
"win_deviceName", "win_deviceName",
"win_mac1", "win_mac1",
"win_ip", "win_ip",
@@ -86,21 +85,8 @@ export async function loadWindowVariables(): Promise<Record<string, any>> {
"win_kueOverflow", "win_kueOverflow",
"win_tdrLast", "win_tdrLast",
"win_appVersion", "win_appVersion",
"win_analogeEingaenge1",
"win_analogeEingaenge2",
"win_analogeEingaenge3",
"win_analogeEingaenge4",
"win_analogeEingaenge5",
"win_analogeEingaenge6",
"win_analogeEingaenge7",
"win_analogeEingaenge8",
"win_da_state", "win_da_state",
"win_da_bezeichnung", "win_da_bezeichnung",
"win_opcUaZustand",
"win_opcUaActiveClientCount",
"win_opcUaNodesetName",
"win_opcUaEncryption", // ✅ NEU: Verschlüsselung von OPC-UA
"win_opcUaUsers", // ✅ NEU: OPC-UA Benutzerliste
]; ];
const scripts: string[] = [ const scripts: string[] = [
@@ -150,7 +136,6 @@ export async function loadWindowVariables(): Promise<Record<string, any>> {
// ✅ Redux mit Systemvariablen aktualisieren // ✅ Redux mit Systemvariablen aktualisieren
loadAndStoreSystemSettings(win); loadAndStoreSystemSettings(win);
loadAndStoreOpcUaSettings(win);
resolve(variablesObj); resolve(variablesObj);
}) })
@@ -180,62 +165,6 @@ const loadAndStoreSystemSettings = (win: CustomWindow) => {
store.dispatch(setSystemSettings(settings)); store.dispatch(setSystemSettings(settings));
}; };
// ✅ Funktion zum Speichern von OPC-UA Variablen in Redux
const loadAndStoreOpcUaSettings = (win: CustomWindow) => {
// ✅ Aktuellen Redux-Status holen
const currentState = store.getState().opcuaSettings;
// ✅ Nur setzen, wenn sich der Zustand geändert hat
if (currentState.opcUaZustand !== win.win_opcUaZustand) {
store.dispatch(setOpcUaZustand(win.win_opcUaZustand || "Offline"));
}
// ✅ Nur setzen, wenn sich die Verschlüsselung geändert hat
if (currentState.encryption !== win.win_opcUaEncryption) {
store.dispatch(setOpcUaEncryption(win.win_opcUaEncryption || "None"));
}
// ✅ Nur setzen, wenn sich die Anzahl der aktiven Clients geändert hat
if (currentState.opcUaActiveClientCount !== win.win_opcUaActiveClientCount) {
store.dispatch(
setOpcUaActiveClientCount(win.win_opcUaActiveClientCount || 0)
);
}
// ✅ Nur setzen, wenn sich der Nodeset-Name geändert hat
if (currentState.opcUaNodesetName !== win.win_opcUaNodesetName) {
store.dispatch(
setOpcUaNodesetName(win.win_opcUaNodesetName || "DefaultNodeset")
);
}
// ✅ Benutzer synchronisieren (aber nicht überschreiben, wenn manuell hinzugefügt)
if (Array.isArray(win.win_opcUaUsers) && win.win_opcUaUsers.length > 0) {
const newUsers = win.win_opcUaUsers;
const currentUsers = currentState.users;
// ✅ Vorhandene Benutzer entfernen, die nicht mehr in `window` sind
currentUsers.forEach((user) => {
if (!newUsers.some((newUser) => newUser.username === user.username)) {
store.dispatch(removeOpcUaUser(user.id));
}
});
// ✅ Nur neue Benutzer hinzufügen, falls sie nicht existieren
newUsers.forEach((user) => {
if (
!currentUsers.some(
(existingUser) => existingUser.username === user.username
)
) {
store.dispatch(
addOpcUaUser({ username: user.username, password: user.password })
);
}
});
}
};
// ✅ Funktion zum Speichern der digitalen Ausgänge in Redux // ✅ Funktion zum Speichern der digitalen Ausgänge in Redux
const loadAndStoreDigitalOutputs = (win: CustomWindow) => { const loadAndStoreDigitalOutputs = (win: CustomWindow) => {
console.log("Prüfe digitale Ausgänge in window:"); console.log("Prüfe digitale Ausgänge in window:");