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:
@@ -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";
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 (
|
||||||
|
|||||||
@@ -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;
|
|
||||||
@@ -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";
|
||||||
|
|||||||
24
redux/thunks/fetchOpcUaSettingsThunk.ts
Normal file
24
redux/thunks/fetchOpcUaSettingsThunk.ts
Normal 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));
|
||||||
|
}
|
||||||
|
);
|
||||||
@@ -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) {
|
||||||
|
|||||||
21
services/fetchOpcUaSettings.ts
Normal file
21
services/fetchOpcUaSettings.ts
Normal 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -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:");
|
||||||
|
|||||||
Reference in New Issue
Block a user