From 0806e6c02f548a232d4319401fdbdf336de96cc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20F=C3=ADsica?= Date: Wed, 25 Jun 2025 19:50:26 +0200 Subject: [PATCH 1/6] Implement the necessary buttons --- .../lib/models/PodData/Measurement.ts | 5 ++-- common-front/lib/store/measurementsStore.ts | 23 +++++++++++++++ .../MeasurementView/MeasurementView.tsx | 29 +++++++++++++++++++ .../components/ReceiveTable/ReceiveTable.tsx | 15 ++++++++++ 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/common-front/lib/models/PodData/Measurement.ts b/common-front/lib/models/PodData/Measurement.ts index 5e55ca9cc..3b47ffebc 100644 --- a/common-front/lib/models/PodData/Measurement.ts +++ b/common-front/lib/models/PodData/Measurement.ts @@ -19,11 +19,12 @@ export type NumericMeasurement = AbstractMeasurement & { warningRange: [number | null, number | null]; }; -export type NumericValue = { +export interface NumericValue { last: number; average: number; showLatest: boolean; -}; + log?: boolean; // Añadido para control de log +} export type BooleanMeasurement = AbstractMeasurement & { type: 'bool'; diff --git a/common-front/lib/store/measurementsStore.ts b/common-front/lib/store/measurementsStore.ts index 315179d40..03cf182f6 100644 --- a/common-front/lib/store/measurementsStore.ts +++ b/common-front/lib/store/measurementsStore.ts @@ -62,6 +62,8 @@ export interface MeasurementsStore { getEnumMeasurementInfo: (id: MeasurementId) => EnumMeasurementInfo; getMeasurementFallback: (id: MeasurementId) => Measurement; clearMeasurements: (board: string) => void; + setLogAll: (log: boolean) => void; + getLogVariables: () => string[]; } export const useMeasurementsStore = create((set, get) => ({ @@ -240,6 +242,27 @@ export const useMeasurementsStore = create((set, get) => ({ } ); }, + + setLogAll: (log: boolean) => { + const measurementsDraft = get().measurements; + for (const id in measurementsDraft) { + const m = measurementsDraft[id]; + if (isNumericType(m.type)) { + (m.value as any).log = log; + } + } + set((state) => ({ + ...state, + measurements: measurementsDraft, + })); + }, + + getLogVariables: () => { + const measurements = get().measurements; + return Object.values(measurements) + .filter(m => isNumericType(m.type) && (m.value as any).log) + .map(m => m.id); + }, })); function createMeasurementsFromPodDataAdapter( diff --git a/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx b/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx index 97bd6bbc8..aceba420f 100644 --- a/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx +++ b/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import styles from './MeasurementView.module.scss'; import { Measurement, @@ -31,11 +32,30 @@ export const MeasurementView = ({ measurement }: Props) => { setShowMeasurementLatest(event.currentTarget.checked); }; + const setLog = (log: boolean) => { + if (isNumeric && typeof measurement.value === 'object') { + (measurement.value as any).log = log; + useMeasurementsStore.setState({ measurements: { ...useMeasurementsStore.getState().measurements } }); + } + }; + // Estado visual del checkbox de log + const logChecked = isNumeric && typeof measurement.value === 'object' && (measurement.value as any).log === true; + + // Sincronizar con los botones globales + React.useEffect(() => { + const handler = (e: any) => { + setLog(e.detail); + }; + window.addEventListener('log-all', handler); + return () => window.removeEventListener('log-all', handler); + }, [setLog]); + return ( <> {measurement.name} {isNumeric && ( <> + { title="Show latest value" onInput={onLatestValueChange} /> + setLog(e.currentTarget.checked)} + /> + {measurement.units} {measurement.type} diff --git a/ethernet-view/src/components/ReceiveTable/ReceiveTable.tsx b/ethernet-view/src/components/ReceiveTable/ReceiveTable.tsx index 17dc07dde..73d7ae772 100644 --- a/ethernet-view/src/components/ReceiveTable/ReceiveTable.tsx +++ b/ethernet-view/src/components/ReceiveTable/ReceiveTable.tsx @@ -12,6 +12,21 @@ export const ReceiveTable = ({ boards }: Props) => { return (
+
+
+ + +
{boards From d9ebd4dba276330d52bd3bed2f578ea7a71e53d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20F=C3=ADsica?= Date: Wed, 25 Jun 2025 21:31:16 +0200 Subject: [PATCH 2/6] Log enabled by default on all variables --- .../PacketView/MeasurementView/MeasurementView.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx b/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx index aceba420f..9132f3c08 100644 --- a/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx +++ b/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx @@ -38,10 +38,11 @@ export const MeasurementView = ({ measurement }: Props) => { useMeasurementsStore.setState({ measurements: { ...useMeasurementsStore.getState().measurements } }); } }; - // Estado visual del checkbox de log - const logChecked = isNumeric && typeof measurement.value === 'object' && (measurement.value as any).log === true; - // Sincronizar con los botones globales + const logChecked = isNumeric && typeof measurement.value === 'object' // Checked by default + ? (measurement.value as any).log !== false + : false; + React.useEffect(() => { const handler = (e: any) => { setLog(e.detail); @@ -65,10 +66,10 @@ export const MeasurementView = ({ measurement }: Props) => { /> setLog(e.currentTarget.checked)} /> From e24740bc6e9ae578cbb7c0e6049fc1c949327d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20F=C3=ADsica?= Date: Wed, 25 Jun 2025 22:40:59 +0200 Subject: [PATCH 3/6] Fixed for non-numeric values, and moved the checkbox to the left --- .../lib/models/PodData/Measurement.ts | 6 ++- common-front/lib/store/measurementsStore.ts | 7 +-- .../MeasurementView/MeasurementView.tsx | 53 +++++++++++-------- 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/common-front/lib/models/PodData/Measurement.ts b/common-front/lib/models/PodData/Measurement.ts index 3b47ffebc..74b38c7ff 100644 --- a/common-front/lib/models/PodData/Measurement.ts +++ b/common-front/lib/models/PodData/Measurement.ts @@ -19,21 +19,23 @@ export type NumericMeasurement = AbstractMeasurement & { warningRange: [number | null, number | null]; }; -export interface NumericValue { +export type NumericValue = { last: number; average: number; showLatest: boolean; - log?: boolean; // Añadido para control de log + log?: boolean; } export type BooleanMeasurement = AbstractMeasurement & { type: 'bool'; value: boolean; + log?: boolean; }; export type EnumMeasurement = AbstractMeasurement & { type: 'enum'; value: string; + log?: boolean; }; // export type ArrayMeasurement = AbstractMeasurement & { diff --git a/common-front/lib/store/measurementsStore.ts b/common-front/lib/store/measurementsStore.ts index 03cf182f6..6c801aa50 100644 --- a/common-front/lib/store/measurementsStore.ts +++ b/common-front/lib/store/measurementsStore.ts @@ -1,7 +1,6 @@ import { Measurement, NumericMeasurement, - isNumericMeasurement, } from '../models'; import { getBooleanMeasurement, @@ -247,9 +246,7 @@ export const useMeasurementsStore = create((set, get) => ({ const measurementsDraft = get().measurements; for (const id in measurementsDraft) { const m = measurementsDraft[id]; - if (isNumericType(m.type)) { - (m.value as any).log = log; - } + (m.value as any).log = log; } set((state) => ({ ...state, @@ -260,7 +257,7 @@ export const useMeasurementsStore = create((set, get) => ({ getLogVariables: () => { const measurements = get().measurements; return Object.values(measurements) - .filter(m => isNumericType(m.type) && (m.value as any).log) + .filter(m => (m.value as any).log) .map(m => m.id); }, })); diff --git a/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx b/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx index 9132f3c08..dac0f0ad4 100644 --- a/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx +++ b/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx @@ -32,16 +32,21 @@ export const MeasurementView = ({ measurement }: Props) => { setShowMeasurementLatest(event.currentTarget.checked); }; + const [localLogChecked, setLocalLogChecked] = React.useState(true); + const setLog = (log: boolean) => { - if (isNumeric && typeof measurement.value === 'object') { + if (typeof measurement.value === 'object' && measurement.value !== null && 'log' in measurement.value) { (measurement.value as any).log = log; - useMeasurementsStore.setState({ measurements: { ...useMeasurementsStore.getState().measurements } }); + } else { + setLocalLogChecked(log); } + useMeasurementsStore.setState({ measurements: { ...useMeasurementsStore.getState().measurements } }); }; - const logChecked = isNumeric && typeof measurement.value === 'object' // Checked by default - ? (measurement.value as any).log !== false - : false; + const logChecked = + typeof measurement.value === 'object' && measurement.value !== null && 'log' in measurement.value + ? (measurement.value as any).log !== false + : localLogChecked; React.useEffect(() => { const handler = (e: any) => { @@ -53,25 +58,29 @@ export const MeasurementView = ({ measurement }: Props) => { return ( <> - {measurement.name} + + setLog(e.currentTarget.checked)} + /> + + {measurement.name} + + {isNumeric && ( <> - - - setLog(e.currentTarget.checked)} - /> + + {measurement.units} From 7d1e5a3282af405dc3106e6b7abdc865f7e71a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20F=C3=ADsica?= Date: Wed, 25 Jun 2025 23:30:56 +0200 Subject: [PATCH 4/6] Fixed logic for sending variables to the backend --- common-front/lib/broker/BrokerStructure.ts | 1 + common-front/lib/models/PodData/Measurement.ts | 4 +--- common-front/lib/store/measurementsStore.ts | 4 ++-- common-front/lib/wsHandler/HandlerMessages.ts | 1 + .../src/components/Logger/useLogger.ts | 14 +++++++++----- .../MeasurementView/MeasurementView.tsx | 18 ++++++------------ 6 files changed, 20 insertions(+), 22 deletions(-) diff --git a/common-front/lib/broker/BrokerStructure.ts b/common-front/lib/broker/BrokerStructure.ts index da75ee1f4..390ebe0e5 100644 --- a/common-front/lib/broker/BrokerStructure.ts +++ b/common-front/lib/broker/BrokerStructure.ts @@ -25,6 +25,7 @@ export type BrokerStructure = { }; "message/update": { request: never; response: MessageAdapter }; "logger/enable": { request: boolean; response: boolean }; + "logger/variables": { request: string[]; response: boolean }; "blcu/upload": { request: BootloaderUploadRequest; response: BootloaderUploadResponse; diff --git a/common-front/lib/models/PodData/Measurement.ts b/common-front/lib/models/PodData/Measurement.ts index 74b38c7ff..74d46852c 100644 --- a/common-front/lib/models/PodData/Measurement.ts +++ b/common-front/lib/models/PodData/Measurement.ts @@ -9,6 +9,7 @@ export type Measurement = type AbstractMeasurement = { id: string; name: string; + log?: boolean; }; export type NumericMeasurement = AbstractMeasurement & { @@ -23,19 +24,16 @@ export type NumericValue = { last: number; average: number; showLatest: boolean; - log?: boolean; } export type BooleanMeasurement = AbstractMeasurement & { type: 'bool'; value: boolean; - log?: boolean; }; export type EnumMeasurement = AbstractMeasurement & { type: 'enum'; value: string; - log?: boolean; }; // export type ArrayMeasurement = AbstractMeasurement & { diff --git a/common-front/lib/store/measurementsStore.ts b/common-front/lib/store/measurementsStore.ts index 6c801aa50..fb5fb2e5d 100644 --- a/common-front/lib/store/measurementsStore.ts +++ b/common-front/lib/store/measurementsStore.ts @@ -246,7 +246,7 @@ export const useMeasurementsStore = create((set, get) => ({ const measurementsDraft = get().measurements; for (const id in measurementsDraft) { const m = measurementsDraft[id]; - (m.value as any).log = log; + m.log = log; } set((state) => ({ ...state, @@ -257,7 +257,7 @@ export const useMeasurementsStore = create((set, get) => ({ getLogVariables: () => { const measurements = get().measurements; return Object.values(measurements) - .filter(m => (m.value as any).log) + .filter(m => m.log !== false) .map(m => m.id); }, })); diff --git a/common-front/lib/wsHandler/HandlerMessages.ts b/common-front/lib/wsHandler/HandlerMessages.ts index 2c1c4f44a..4c145005c 100644 --- a/common-front/lib/wsHandler/HandlerMessages.ts +++ b/common-front/lib/wsHandler/HandlerMessages.ts @@ -19,6 +19,7 @@ export type HandlerMessages = { "message/update": Subscription; "logger/enable": PostRequest; "logger/response": Subscription; + "logger/variables": PostRequest; "blcu/upload": Exchange; "blcu/download": Exchange< BootloaderDownloadRequest, diff --git a/ethernet-view/src/components/Logger/useLogger.ts b/ethernet-view/src/components/Logger/useLogger.ts index 4d9e2b169..69f982ba4 100644 --- a/ethernet-view/src/components/Logger/useLogger.ts +++ b/ethernet-view/src/components/Logger/useLogger.ts @@ -1,21 +1,25 @@ import { useSubscribe, useWsHandler } from "common"; import { useState } from "react"; +import { useMeasurementsStore } from "common"; export function useLogger() { const [state, setState] = useState(false); const handler = useWsHandler(); - const log = (enable: boolean) => { - handler.post("logger/enable", enable); - }; + function getLoggedVariableIds() { + return useMeasurementsStore.getState().getLogVariables(); + } function startLogging() { - log(true); + const variables = getLoggedVariableIds(); + console.log('[LOGGER] Enviando variables al backend:', variables); + handler.post("logger/variables", variables); + handler.post("logger/enable", true); } function stopLogging() { - log(false); + handler.post("logger/enable", false); } useSubscribe("logger/response", (result) => { diff --git a/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx b/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx index dac0f0ad4..a1991c47a 100644 --- a/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx +++ b/ethernet-view/src/components/ReceiveTable/BoardView/PacketView/MeasurementView/MeasurementView.tsx @@ -32,21 +32,15 @@ export const MeasurementView = ({ measurement }: Props) => { setShowMeasurementLatest(event.currentTarget.checked); }; - const [localLogChecked, setLocalLogChecked] = React.useState(true); - const setLog = (log: boolean) => { - if (typeof measurement.value === 'object' && measurement.value !== null && 'log' in measurement.value) { - (measurement.value as any).log = log; - } else { - setLocalLogChecked(log); - } - useMeasurementsStore.setState({ measurements: { ...useMeasurementsStore.getState().measurements } }); + useMeasurementsStore.setState(state => { + const measurements = { ...state.measurements }; + measurements[measurement.id] = { ...measurements[measurement.id], log }; + return { ...state, measurements }; + }); }; - const logChecked = - typeof measurement.value === 'object' && measurement.value !== null && 'log' in measurement.value - ? (measurement.value as any).log !== false - : localLogChecked; + const logChecked = useMeasurementsStore(state => state.measurements[measurement.id]?.log !== false); React.useEffect(() => { const handler = (e: any) => { From 5f860322f6c7bab4ed01556b9a4d04ae43cec49c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20F=C3=ADsica?= Date: Wed, 25 Jun 2025 23:31:21 +0200 Subject: [PATCH 5/6] Remove temp console.log --- ethernet-view/src/components/Logger/useLogger.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/ethernet-view/src/components/Logger/useLogger.ts b/ethernet-view/src/components/Logger/useLogger.ts index 69f982ba4..c4fc57df9 100644 --- a/ethernet-view/src/components/Logger/useLogger.ts +++ b/ethernet-view/src/components/Logger/useLogger.ts @@ -13,7 +13,6 @@ export function useLogger() { function startLogging() { const variables = getLoggedVariableIds(); - console.log('[LOGGER] Enviando variables al backend:', variables); handler.post("logger/variables", variables); handler.post("logger/enable", true); } From 25bc89b3877cd459820df9eab71b6e30802911e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20F=C3=ADsica?= Date: Thu, 26 Jun 2025 21:10:09 +0200 Subject: [PATCH 6/6] Update log-all and log-none for collapsed boards --- .../src/components/ReceiveTable/ReceiveTable.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ethernet-view/src/components/ReceiveTable/ReceiveTable.tsx b/ethernet-view/src/components/ReceiveTable/ReceiveTable.tsx index 73d7ae772..88d57526f 100644 --- a/ethernet-view/src/components/ReceiveTable/ReceiveTable.tsx +++ b/ethernet-view/src/components/ReceiveTable/ReceiveTable.tsx @@ -2,26 +2,29 @@ import styles from "./ReceiveTable.module.scss"; import { BoardView } from "./BoardView/BoardView"; import { Header } from "./Header/Header"; import { TableUpdater } from "./TableUpdater"; -import { Board } from "common"; +import { Board, useMeasurementsStore} from "common"; type Props = { boards: Board[]; }; export const ReceiveTable = ({ boards }: Props) => { + const handleLogAll = (log: boolean) => { + useMeasurementsStore.getState().setLogAll(log); + }; return (