Add: SERVICE JSON Files

This commit is contained in:
ISA
2025-06-25 15:26:00 +02:00
parent 53c2a02224
commit 845c2dd658
23 changed files with 242 additions and 53 deletions

View File

@@ -6,7 +6,7 @@ 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.446 NEXT_PUBLIC_APP_VERSION=1.6.447
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)
#### Feature-Flags #### #### Feature-Flags ####

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.446 NEXT_PUBLIC_APP_VERSION=1.6.447
NEXT_PUBLIC_CPL_MODE=production NEXT_PUBLIC_CPL_MODE=production

View File

@@ -1,3 +1,8 @@
## [1.6.447] 2025-06-25
- feat: Zeitraum einstellbar in AnalogInputsChart mit Zoom- und Pan-Funktion umgesetzt
---
## [1.6.446] 2025-06-25 ## [1.6.446] 2025-06-25
- docs: Zusatzfunktionen (Kai, 25.06.2025) in TODO.md ergänzt - docs: Zusatzfunktionen (Kai, 25.06.2025) in TODO.md ergänzt

View File

@@ -36,6 +36,9 @@ export default function AnalogInputsChart({
}: { }: {
selectedId: number | null; selectedId: number | null;
}) { }) {
const selectedInput = useSelector(
(state: RootState) => state.selectedAnalogInput
);
const zoomEnabled = const zoomEnabled =
process.env.NEXT_PUBLIC_FEATURE_MESSWERTANZEIGE_EINGANG === "true"; process.env.NEXT_PUBLIC_FEATURE_MESSWERTANZEIGE_EINGANG === "true";
const dispatch = useDispatch<AppDispatch>(); const dispatch = useDispatch<AppDispatch>();
@@ -82,7 +85,9 @@ export default function AnalogInputsChart({
const chartData = { const chartData = {
datasets: [ datasets: [
{ {
label: `Messkurve Messwerteingang ${selectedId}`, label: `Messkurve ${selectedInput?.label ?? "Eingang"} (${
selectedInput?.unit ?? ""
})`,
data: inputData.map((point: any) => ({ data: inputData.map((point: any) => ({
x: point.t, x: point.t,
y: point.m, y: point.m,
@@ -145,7 +150,7 @@ export default function AnalogInputsChart({
y: { y: {
title: { title: {
display: true, display: true,
text: "Messwert", text: `Messwert (${selectedInput?.unit ?? ""})`,
}, },
}, },
}, },

View File

@@ -18,6 +18,7 @@ import { getAnalogInputsThunk } from "@/redux/thunks/getAnalogInputsThunk";
import { Icon } from "@iconify/react"; import { Icon } from "@iconify/react";
import settingsIcon from "@iconify/icons-mdi/settings"; import settingsIcon from "@iconify/icons-mdi/settings";
import waveformIcon from "@iconify/icons-mdi/waveform"; import waveformIcon from "@iconify/icons-mdi/waveform";
import { setSelectedAnalogInput } from "@/redux/slices/selectedAnalogInputSlice";
export default function AnalogInputsTable({ export default function AnalogInputsTable({
setSelectedId, setSelectedId,
@@ -39,9 +40,10 @@ export default function AnalogInputsTable({
(state: RootState) => state.analogInputs ?? [] (state: RootState) => state.analogInputs ?? []
); );
const handleSelect = (id: number) => { const handleSelect = (id: number, input: AnalogInput) => {
setSelectedId(id); setSelectedId(id);
setActiveId(id); setActiveId(id);
dispatch(setSelectedAnalogInput(input)); // 🧠 hier kommt die Bezeichnung in Redux
}; };
return ( return (
@@ -79,7 +81,7 @@ export default function AnalogInputsTable({
> >
<td <td
className="border p-2" className="border p-2"
onClick={() => handleSelect(e.id!)} onClick={() => handleSelect(e.id!, e)}
> >
<div className="flex items-center gap-1 "> <div className="flex items-center gap-1 ">
<Icon <Icon
@@ -91,7 +93,7 @@ export default function AnalogInputsTable({
</td> </td>
<td <td
className="border p-2 text-right" className="border p-2 text-right"
onClick={() => handleSelect(e.id!)} onClick={() => handleSelect(e.id!, e)}
> >
{typeof e.value === "number" ? e.value.toFixed(2) : "-"} {typeof e.value === "number" ? e.value.toFixed(2) : "-"}
</td> </td>
@@ -99,7 +101,7 @@ export default function AnalogInputsTable({
<td className="border p-2">{e.unit || "-"}</td> <td className="border p-2">{e.unit || "-"}</td>
<td <td
className="border p-2" className="border p-2"
onClick={() => handleSelect(e.id!)} onClick={() => handleSelect(e.id!, e)}
> >
{e.label || "----"} {e.label || "----"}
</td> </td>
@@ -107,7 +109,7 @@ export default function AnalogInputsTable({
<td className="border p-2 text-center"> <td className="border p-2 text-center">
<button <button
onClick={() => { onClick={() => {
handleSelect(e.id!); handleSelect(e.id!, e);
setSelectedInput(e); setSelectedInput(e);
setIsSettingsModalOpen(true); setIsSettingsModalOpen(true);
}} }}

View File

@@ -2,13 +2,15 @@
## 🔄 Zusatzfunktionen (prio niedrig) Kai, 25. Juni 2025 ## 🔄 Zusatzfunktionen (prio niedrig) Kai, 25. Juni 2025
- [ ] Messwertanzeige eines Eingangs: Zeitraum einstellbar, Bezeichnung und Einheit in die Messkurve, Datum in die Messkurve - [ ] TODO:Messwertanzeige eines Eingangs: Zeitraum einstellbar, Bezeichnung und Einheit in die Messkurve, Datum in die Messkurve
- [ ] Startseite Meldungen: Spalte Quelle wie bei Berichte (nicht "Modul") - Einheit in eckigen Klammern und Chart Daten mit Parameter DIA0 usw.
- [ ] Startseite Spaltenreihenfolge: Pop (farbiger Punkt), Zeitstempel, Quelle, Meldung, Status - [ ] FIXME: Kabelüberwachung vertikal angezeigt
- [ ] Berichte Spaltenreihenfolge: Pop (farbiger Punkt), Zeitstempel, Quelle, Meldung, Status - [ ] TODO: Startseite Meldungen: Spalte Quelle wie bei Berichte (nicht "Modul")
- [ ] Filter für Quelle - [ ] TODO: Startseite Spaltenreihenfolge: Pop (farbiger Punkt), Zeitstempel, Quelle, Meldung, Status
- [ ] System: Button bei jedem Messwert für Detailansicht (inkl. Kurve im Popup und Zeitauswahl) - [ ] TODO: Berichte Spaltenreihenfolge: Pop (farbiger Punkt), Zeitstempel, Quelle, Meldung, Status
- [ ] Einstellungen Benutzerverwaltung: Admin kann Adminpasswort ändern - [ ] TODO: Filter für Quelle
- [ ] Einstellungen OPC: Anzahl der aktuellen Clients (ggf. KAS-Variable einbauen) - [ ] TODO: System: Button bei jedem Messwert für Detailansicht (inkl. Kurve im Popup und Zeitauswahl)
- [ ] TODO: Einstellungen Benutzerverwaltung: Admin kann Adminpasswort ändern
- [ ] TODO: Einstellungen OPC: Anzahl der aktuellen Clients (ggf. KAS-Variable einbauen)
![Zusatzfunktionen Kai 25.06.2025](./TODOsScreenshots/Zusatzfunktionen_25-06-2025.png) ![Zusatzfunktionen Kai 25.06.2025](./TODOsScreenshots/Zusatzfunktionen_25-06-2025.png)

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.446", "version": "1.6.447",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.446", "version": "1.6.447",
"dependencies": { "dependencies": {
"@fontsource/roboto": "^5.1.0", "@fontsource/roboto": "^5.1.0",
"@iconify-icons/ri": "^1.2.10", "@iconify-icons/ri": "^1.2.10",

View File

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

View File

@@ -1,4 +1,4 @@
"use client"; ///pages/analogInputs.tsx "use client"; ///pages/analogeEingaenge.tsx
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import AnalogInputsTable from "../components/main/analogInputs/AnalogInputsTable"; import AnalogInputsTable from "../components/main/analogInputs/AnalogInputsTable";
import AnalogInputsChart from "../components/main/analogInputs/AnalogInputsChart"; import AnalogInputsChart from "../components/main/analogInputs/AnalogInputsChart";

View File

@@ -10,10 +10,10 @@ import { getKueDataThunk } from "../redux/thunks/getKueDataThunk";
function Kabelueberwachung() { function Kabelueberwachung() {
const dispatch: AppDispatch = useDispatch(); const dispatch: AppDispatch = useDispatch();
const searchParams = useSearchParams(); // URL-Parameter holen const searchParams = useSearchParams(); // URL-Parameter holen
const initialRack = parseInt(searchParams.get("rack") ?? "1") || 1; // Rack-Nummer aus URL oder 1 const initialRack = parseInt(searchParams.get("rack")) || 1; // Rack-Nummer aus URL oder 1
const [activeRack, setActiveRack] = useState(initialRack); // Nutze initialRack als Startwert const [activeRack, setActiveRack] = useState(initialRack); // Nutze initialRack als Startwert
const [alarmStatus, setAlarmStatus] = useState<boolean[]>([]); // Alarmstatus const [alarmStatus, setAlarmStatus] = useState([]); // Alarmstatus
// Redux-Variablen aus dem Store abrufen // Redux-Variablen aus dem Store abrufen
const { const {
@@ -25,23 +25,21 @@ function Kabelueberwachung() {
kueResidence, kueResidence,
kueCableBreak, kueCableBreak,
kueGroundFault, kueGroundFault,
} = useSelector((state: RootState) => state.kueDataSlice); } = useSelector((state) => state.kueDataSlice);
//---------------------------------------------------------------- //----------------------------------------------------------------
// 🚀 **TDR-Daten bereits in Redux abrufen** // 🚀 **TDR-Daten bereits in Redux abrufen**
// Redux-Variablen abrufen // Redux-Variablen abrufen
const tdrData = useSelector((state: RootState) => state.tdrChartSlice.data); const tdrData = useSelector((state) => state.tdrChartSlice.data);
const loading = useSelector( const loading = useSelector((state) => state.tdrChartSlice.loading);
(state: RootState) => state.tdrChartSlice.loading const error = useSelector((state) => state.tdrChartSlice.error);
);
const error = useSelector((state: RootState) => state.tdrChartSlice.error);
//---------------------------------------------------------------- //----------------------------------------------------------------
//---------------------------------------------------------------- //----------------------------------------------------------------
// Alarmstatus basierend auf Redux-Variablen berechnen // Alarmstatus basierend auf Redux-Variablen berechnen
const updateAlarmStatus = () => { const updateAlarmStatus = () => {
const updatedAlarmStatus = kueIso.map((_, index) => { const updatedAlarmStatus = kueIso.map((_, index) => {
return !!( return (
(kueAlarm1 && kueAlarm1[index]) || (kueAlarm1 && kueAlarm1[index]) ||
(kueAlarm2 && kueAlarm2[index]) || (kueAlarm2 && kueAlarm2[index]) ||
(kueCableBreak && kueCableBreak[index]) || (kueCableBreak && kueCableBreak[index]) ||
@@ -68,8 +66,7 @@ function Kabelueberwachung() {
})); }));
//console.log("Alle Module:", allModules); //console.log("Alle Module:", allModules);
type RackKey = "rack1" | "rack2" | "rack3" | "rack4"; const racks = {
const racks: Record<RackKey, typeof allModules> = {
rack1: allModules.slice(0, 8), rack1: allModules.slice(0, 8),
rack2: allModules.slice(8, 16), rack2: allModules.slice(8, 16),
rack3: allModules.slice(16, 24), rack3: allModules.slice(16, 24),
@@ -95,11 +92,7 @@ function Kabelueberwachung() {
); */ ); */
// Funktion zum Wechseln des Racks // Funktion zum Wechseln des Racks
interface ChangeRackFn { const changeRack = (rack) => {
(rack: number): void;
}
const changeRack: ChangeRackFn = (rack) => {
setActiveRack(rack); setActiveRack(rack);
console.log(`Aktives Rack geändert zu: ${rack}`); console.log(`Aktives Rack geändert zu: ${rack}`);
}; };
@@ -151,22 +144,23 @@ function Kabelueberwachung() {
</button> </button>
))} ))}
</div> </div>
{racks[`rack${activeRack}` as RackKey].map((slot, index) => { <div className="flex flex-row space-x-8 xl:space-x-0 2xl:space-x-8 qhd:space-x-16 ml-[5%] mt-[5%]">
const slotIndex = index + (activeRack - 1) * 8; {racks[`rack${activeRack}`].map((slot, index) => {
return ( const slotIndex = index + (activeRack - 1) * 8;
<div key={index} className="flex"> return (
<Kue705FO <div key={index} className="flex">
isolationswert={slot.isolationswert} <Kue705FO
schleifenwiderstand={slot.schleifenwiderstand} isolationswert={slot.isolationswert}
modulName={slot.modulName} schleifenwiderstand={slot.schleifenwiderstand}
kueOnline={slot.kueOnlineStatus} modulName={slot.modulName}
alarmStatus={slot.alarmStatus} kueOnline={slot.kueOnlineStatus}
slotIndex={slotIndex} alarmStatus={slot.alarmStatus}
tdrLocation={[]} // TODO: Replace with actual tdrLocation data if available slotIndex={slotIndex}
/> />
</div> </div>
); );
})} })}
</div>
</div> </div>
); );
} }

View File

@@ -0,0 +1,3 @@
{
"win_last20Messages": "<%=SAM01%>"
}

View File

@@ -0,0 +1,17 @@
{
"win_appVersion": "<%=SAV00%>",
"win_deviceName": "<%=SAN01%>",
"win_mac1": "<%=SEM01%>",
"win_ip": "<%=SEI01%>",
"win_subnet": "<%=SES01%>",
"win_gateway": "<%=SEG01%>",
"win_cplInternalTimestamp": "<%=SCL01%>",
"win_ntp1": "<%=STP01%>",
"win_ntp2": "<%=STP02%>",
"win_ntp3": "<%=STP03%>",
"win_ntpTimezone": "<%=STT00%>",
"win_ntpActive": "<%=STA00%>",
"win_opcState": "<%=SOS01%>",
"win_opcSessions": "<%=SOC01%>",
"win_opcName": "<%=SON01%>"
}

View File

@@ -0,0 +1,20 @@
{
"win_de_state": ["<%=DES80%>", "<%=DES81%>", "<%=DES82%>", "<%=DES83%>"],
"win_de_label": ["<%=DEN80%>", "<%=DEN81%>", "<%=DEN82%>", "<%=DEN83%>"],
"win_de_counter": ["<%=DEC80%>", "<%=DEC81%>", "<%=DEC82%>", "<%=DEC83%>"],
"win_de_time_filter": [
"<%=DEF80%>",
"<%=DEF81%>",
"<%=DEF82%>",
"<%=DEF83%>"
],
"win_de_weighting": ["<%=DEG80%>", "<%=DEG81%>", "<%=DEG82%>", "<%=DEG83%>"],
"win_de_invert": ["<%=DEI80%>", "<%=DEI81%>", "<%=DEI82%>", "<%=DEI83%>"],
"win_de_counter_active": [
"<%=DEZ80%>",
"<%=DEZ81%>",
"<%=DEZ82%>",
"<%=DEZ83%>"
],
"win_de_offline": ["<%=DEA80%>", "<%=DEA81%>", "<%=DEA82%>", "<%=DEA83%>"]
}

View File

@@ -0,0 +1,4 @@
{
"win_da_state": ["<%=DAS01%>", "<%=DAS02%>", "<%=DAS03%>", "<%=DAS04%>"],
"win_da_bezeichnung": ["<%=DAN01%>", "<%=DAN02%>", "<%=DAN03%>", "<%=DAN04%>"]
}

View File

@@ -0,0 +1,42 @@
{
"win_kueOnline": ["<%=KSO80%>", "<%=KSO81%>", "<%=KSO82%>", "<%=KSO83%>"],
"win_kueVersion": ["<%=KSV80%>", "<%=KSV81%>", "<%=KSV82%>", "<%=KSV83%>"],
"win_kuePSTmMinus96V": [
"<%=KSS80%>",
"<%=KSS81%>",
"<%=KSS82%>",
"<%=KSS83%>"
],
"win_kueCableBreak": ["<%=KSC80%>", "<%=KSC81%>", "<%=KSC82%>", "<%=KSC83%>"],
"win_kueGroundFault": [
"<%=KSG80%>",
"<%=KSG81%>",
"<%=KSG82%>",
"<%=KSG83%>"
],
"win_kueOverflow": ["<%=KIW80%>", "<%=KIW81%>", "<%=KIW82%>", "<%=KIW83%>"],
"win_kueIso": ["<%=KIM80%>", "<%=KIM81%>", "<%=KIM82%>", "<%=KIM83%>"],
"win_kueAlarm1": ["<%=KIA80%>", "<%=KIA81%>", "<%=KIA82%>", "<%=KIA83%>"],
"win_kueLimit1": ["<%=KIG80%>", "<%=KIG81%>", "<%=KIG82%>", "<%=KIG83%>"],
"win_kueResidence": ["<%=KRM80%>", "<%=KRM81%>", "<%=KRM82%>", "<%=KRM83%>"],
"win_kueAlarm2": ["<%=KRA80%>", "<%=KRA81%>", "<%=KRA82%>", "<%=KRA83%>"],
"win_kueLimit2Low": ["<%=KRG80%>", "<%=KRG81%>", "<%=KRG82%>", "<%=KRG83%>"],
"win_kueDelay1": ["<%=KID80%>", "<%=KID81%>", "<%=KID82%>", "<%=KID83%>"],
"win_kueLoopInterval": [
"<%=KRI80%>",
"<%=KRI81%>",
"<%=KRI82%>",
"<%=KRI83%>"
],
"win_kueID": ["<%=KSI80%>", "<%=KSI81%>", "<%=KSI82%>", "<%=KSI83%>"],
"win_kueName": ["<%=KSA80%>", "<%=KSA81%>", "<%=KSA82%>", "<%=KSA83%>"],
"win_tdrActive": ["<%=KTX80%>", "<%=KTX81%>", "<%=KTX82%>", "<%=KTX83%>"],
"win_tdrAtten": ["<%=KTD80%>", "<%=KTD81%>", "<%=KTD82%>", "<%=KTD83%>"],
"win_tdrSpeed": ["<%=KTS80%>", "<%=KTS81%>", "<%=KTS82%>", "<%=KTS83%>"],
"win_tdrTrigger": ["<%=KTE80%>", "<%=KTE81%>", "<%=KTE82%>", "<%=KTE83%>"],
"win_tdrPulse": ["<%=KTP80%>", "<%=KTP81%>", "<%=KTP82%>", "<%=KTP83%>"],
"win_tdrAmp": ["<%=KTA80%>", "<%=KTA81%>", "<%=KTA82%>", "<%=KTA83%>"],
"win_tdrLast": ["<%=KTL80%>", "<%=KTL81%>", "<%=KTL82%>", "<%=KTL83%>"],
"win_tdrLocation": ["<%=KTF80%>", "<%=KTF81%>", "<%=KTF82%>", "<%=KTF83%>"],
"win_memoryInterval": ["<%=KIL80%>", "<%=KIL81%>", "<%=KIL82%>", "<%=KIL83%>"]
}

View File

@@ -0,0 +1,50 @@
{
"kueNodeID": [
"<%=KN001%>",
"<%=KN101%>",
"<%=KN201%>",
"<%=KN301%>",
"<%=KN401%>",
"<%=KN501%>",
"<%=KN601%>",
"<%=KN701%>",
"<%=KN801%>",
"<%=KN901%>"
],
"kueLinkID": [
"<%=KP001%>",
"<%=KP101%>",
"<%=KP201%>",
"<%=KP301%>",
"<%=KP401%>",
"<%=KP501%>",
"<%=KP601%>",
"<%=KP701%>",
"<%=KP801%>",
"<%=KP901%>"
],
"kueLinkLength": [
"<%=KQ001%>",
"<%=KQ101%>",
"<%=KQ201%>",
"<%=KQ301%>",
"<%=KQ401%>",
"<%=KQ501%>",
"<%=KQ601%>",
"<%=KQ701%>",
"<%=KQ801%>",
"<%=KQ901%>"
],
"kueLinkStatus": [
"<%=KU001%>",
"<%=KU101%>",
"<%=KU201%>",
"<%=KU301%>",
"<%=KU401%>",
"<%=KU501%>",
"<%=KU601%>",
"<%=KU701%>",
"<%=KU801%>",
"<%=KU901%>"
]
}

View File

@@ -0,0 +1,5 @@
{
"win_opcUaZustand": "<%=SOS01%>",
"win_opcUaActiveClientCount": "<%=SOC01%>",
"win_opcUaNodesetName": "<%=SON01%>"
}

View File

@@ -0,0 +1,3 @@
{
"win_systemVoltTemp": ["AAV09", "AAV11", "AAV15", "AAV16", "AAV17", "AAV18"]
}

BIN
redux/slices.zip Normal file

Binary file not shown.

View File

@@ -0,0 +1,35 @@
// /redux/slices/selectedAnalogInputSlice.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
export interface SelectedAnalogInput {
id: number;
label: string;
unit?: string;
value?: number;
offset?: number;
factor?: number;
loggerInterval?: number;
weighting?: number;
}
const initialState: SelectedAnalogInput | null = null;
const selectedAnalogInputSlice = createSlice({
name: "selectedAnalogInput",
initialState,
reducers: {
setSelectedAnalogInput: (
state,
action: PayloadAction<SelectedAnalogInput>
) => {
return action.payload;
},
clearSelectedAnalogInput: () => {
return null;
},
},
});
export const { setSelectedAnalogInput, clearSelectedAnalogInput } =
selectedAnalogInputSlice.actions;
export default selectedAnalogInputSlice.reducer;

View File

@@ -24,6 +24,7 @@ import tdrReferenceChartDataBySlotReducer from "./slices/tdrReferenceChartDataBy
import loopChartTypeSlice from "./slices/loopChartTypeSlice"; import loopChartTypeSlice from "./slices/loopChartTypeSlice";
import systemVoltTempReducer from "./slices/systemVoltTempSlice"; import systemVoltTempReducer from "./slices/systemVoltTempSlice";
import analogInputsHistoryReducer from "./slices/analogInputsHistorySlice"; import analogInputsHistoryReducer from "./slices/analogInputsHistorySlice";
import selectedAnalogInputReducer from "./slices/selectedAnalogInputSlice";
const store = configureStore({ const store = configureStore({
reducer: { reducer: {
@@ -50,6 +51,7 @@ const store = configureStore({
loopChartType: loopChartTypeSlice, loopChartType: loopChartTypeSlice,
systemVoltTemp: systemVoltTempReducer, systemVoltTemp: systemVoltTempReducer,
analogInputsHistory: analogInputsHistoryReducer, analogInputsHistory: analogInputsHistoryReducer,
selectedAnalogInput: selectedAnalogInputReducer,
}, },
}); });

BIN
redux/thunks.zip Normal file

Binary file not shown.

BIN
redux/types.zip Normal file

Binary file not shown.