import { createSlice, PayloadAction } from "@reduxjs/toolkit"; export interface DeviceEventsState { ksx: number[]; // 32 Slots: Schleifenmessung aktiv ksy: number[]; // 32 Slots: TDR-Messung aktiv ksz: number[]; // 32 Slots: Abgleich aktiv anyLoopActive: boolean; anyTdrActive: boolean; anyAlignmentActive: boolean; loopStartedAt: number | null; // unix ms timestamp when KSX became active tdrStartedAt: number | null; // unix ms timestamp when KSY became active alignmentStartedAt: number | null; // unix ms timestamp when KSZ became active } const ZERO32 = Array.from({ length: 32 }, () => 0); const initialState: DeviceEventsState = { ksx: ZERO32.slice(), ksy: ZERO32.slice(), ksz: ZERO32.slice(), anyLoopActive: false, anyTdrActive: false, anyAlignmentActive: false, loopStartedAt: null, tdrStartedAt: null, alignmentStartedAt: null, }; export const deviceEventsSlice = createSlice({ name: "deviceEvents", initialState, reducers: { setEvents( state, action: PayloadAction<{ ksx?: number[]; ksy?: number[]; ksz?: number[] }> ) { const prevLoop = state.anyLoopActive; const prevTdr = state.anyTdrActive; const prevAlign = state.anyAlignmentActive; const to32 = (arr?: number[]) => { if (!Array.isArray(arr)) return ZERO32.slice(); const a = arr .slice(0, 32) .map((v) => (typeof v === "number" && v ? 1 : 0)); while (a.length < 32) a.push(0); return a; }; state.ksx = to32(action.payload.ksx); state.ksy = to32(action.payload.ksy); state.ksz = to32(action.payload.ksz); state.anyLoopActive = state.ksx.some((v) => v === 1); state.anyTdrActive = state.ksy.some((v) => v === 1); state.anyAlignmentActive = state.ksz.some((v) => v === 1); // Transition detection to set/reset startedAt timestamps if (!prevLoop && state.anyLoopActive) state.loopStartedAt = Date.now(); if (prevLoop && !state.anyLoopActive) state.loopStartedAt = null; if (!prevTdr && state.anyTdrActive) state.tdrStartedAt = Date.now(); if (prevTdr && !state.anyTdrActive) state.tdrStartedAt = null; if (!prevAlign && state.anyAlignmentActive) state.alignmentStartedAt = Date.now(); if (prevAlign && !state.anyAlignmentActive) state.alignmentStartedAt = null; }, resetEvents(state) { state.ksx = ZERO32.slice(); state.ksy = ZERO32.slice(); state.ksz = ZERO32.slice(); state.anyLoopActive = false; state.anyTdrActive = false; state.anyAlignmentActive = false; state.loopStartedAt = null; state.tdrStartedAt = null; state.alignmentStartedAt = null; }, }, }); export const { setEvents, resetEvents } = deviceEventsSlice.actions; export default deviceEventsSlice.reducer;