From addd9fa6bc271d9c901d5a1c7144ede96d64d63e Mon Sep 17 00:00:00 2001 From: Miguel Date: Fri, 15 Aug 2025 11:01:20 +0200 Subject: [PATCH] feat: Enhance event logging for plot sessions, improve zoom functionality, and update dataset configurations --- application_events.json | 179 +++++++++++++++++++++++- config/data/plot_definitions.json | 13 +- config/data/plot_variables.json | 37 +++-- frontend/src/components/ChartjsPlot.jsx | 154 +++++++++++++------- system_state.json | 6 +- 5 files changed, 322 insertions(+), 67 deletions(-) diff --git a/application_events.json b/application_events.json index d6dafca..adc6053 100644 --- a/application_events.json +++ b/application_events.json @@ -4357,8 +4357,183 @@ "trigger_variable": null, "auto_started": true } + }, + { + "timestamp": "2025-08-15T00:55:29.278884", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'Clock' created and started", + "details": { + "session_id": "Clock", + "variables": [ + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 60, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T00:56:04.171748", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'Clock' created and started", + "details": { + "session_id": "Clock", + "variables": [ + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 60, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T00:56:33.247778", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-15T00:56:33.360494", + "level": "info", + "event_type": "dataset_activated", + "message": "Dataset activated: DAR", + "details": { + "dataset_id": "DAR", + "variables_count": 2, + "streaming_count": 2, + "prefix": "gateway_phoenix" + } + }, + { + "timestamp": "2025-08-15T00:56:33.369004", + "level": "info", + "event_type": "dataset_activated", + "message": "Dataset activated: Fast", + "details": { + "dataset_id": "Fast", + "variables_count": 2, + "streaming_count": 1, + "prefix": "fast" + } + }, + { + "timestamp": "2025-08-15T00:56:33.375426", + "level": "info", + "event_type": "csv_recording_started", + "message": "CSV recording started: 2 datasets activated", + "details": { + "activated_datasets": 2, + "total_datasets": 3 + } + }, + { + "timestamp": "2025-08-15T00:56:43.455835", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'Clock' created and started", + "details": { + "session_id": "Clock", + "variables": [ + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 60, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T00:56:50.145968", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S" + ], + "time_window": 360, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T00:57:04.660061", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'Clock' created and started", + "details": { + "session_id": "Clock", + "variables": [ + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 60, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T00:57:09.226184", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'Clock' created and started", + "details": { + "session_id": "Clock", + "variables": [ + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 60, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T10:44:49.036843", + "level": "info", + "event_type": "datasets_resumed_after_reconnection", + "message": "Automatically resumed streaming for 2 datasets after PLC reconnection", + "details": { + "resumed_datasets": 2, + "total_attempted": 2 + } + }, + { + "timestamp": "2025-08-15T10:45:35.434594", + "level": "info", + "event_type": "datasets_resumed_after_reconnection", + "message": "Automatically resumed streaming for 2 datasets after PLC reconnection", + "details": { + "resumed_datasets": 2, + "total_attempted": 2 + } + }, + { + "timestamp": "2025-08-15T10:47:54.448887", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } } ], - "last_updated": "2025-08-15T00:53:37.664354", - "total_entries": 390 + "last_updated": "2025-08-15T10:47:54.448887", + "total_entries": 403 } \ No newline at end of file diff --git a/config/data/plot_definitions.json b/config/data/plot_definitions.json index 1832b26..92f69bd 100644 --- a/config/data/plot_definitions.json +++ b/config/data/plot_definitions.json @@ -7,12 +7,23 @@ "point_hover_radius": 4, "point_radius": 0, "stepped": true, - "time_window": 360, + "time_window": 36, "trigger_enabled": false, "trigger_on_true": true, "trigger_variable": null, "y_max": null, "y_min": null + }, + { + "id": "Clock", + "line_tension": 0, + "name": "Clock", + "point_hover_radius": 4, + "point_radius": 1, + "stepped": true, + "time_window": 60, + "trigger_enabled": false, + "trigger_on_true": true } ] } \ No newline at end of file diff --git a/config/data/plot_variables.json b/config/data/plot_variables.json index 08ae190..2281c79 100644 --- a/config/data/plot_variables.json +++ b/config/data/plot_variables.json @@ -4,26 +4,45 @@ "plot_id": "plot_1", "variables": [ { - "variable_name": "UR29_Brix", - "label": "Brix", "color": "#3498db", + "enabled": true, + "label": "Brix", "line_width": 2, - "y_axis": "left", - "enabled": true + "variable_name": "UR29_Brix", + "y_axis": "left" }, { - "variable_name": "UR29_ma", - "label": "ma", "color": "#dce740", + "enabled": true, + "label": "ma", "line_width": 2, - "y_axis": "left", - "enabled": true + "variable_name": "UR29_ma", + "y_axis": "left" }, + { + "color": "#3498db", + "enabled": true, + "line_width": 2, + "variable_name": "AUX Blink_1.0S", + "y_axis": "right" + } + ] + }, + { + "plot_id": "Clock", + "variables": [ { "variable_name": "AUX Blink_1.0S", "color": "#3498db", "line_width": 2, - "y_axis": "right", + "y_axis": "left", + "enabled": true + }, + { + "variable_name": "AUX Blink_1.6S", + "color": "#87db33", + "line_width": 2, + "y_axis": "left", "enabled": true } ] diff --git a/frontend/src/components/ChartjsPlot.jsx b/frontend/src/components/ChartjsPlot.jsx index 0e7f5f0..0281a29 100644 --- a/frontend/src/components/ChartjsPlot.jsx +++ b/frontend/src/components/ChartjsPlot.jsx @@ -1,5 +1,5 @@ import React, { useRef, useEffect, useState, useCallback } from 'react'; -import { Box, Text, useColorModeValue } from '@chakra-ui/react'; +import { Box, Text, Switch, FormLabel, HStack, useColorModeValue } from '@chakra-ui/react'; // Global dependencies check - run once let dependenciesChecked = false; @@ -66,11 +66,9 @@ const ChartjsPlot = ({ session, height = '400px' }) => { const [dataPointsCount, setDataPointsCount] = useState(0); const [isRefreshing, setIsRefreshing] = useState(false); const [isLoadingHistorical, setIsLoadingHistorical] = useState(false); + const [isZoomEnabled, setIsZoomEnabled] = useState(true); const resolvedConfigRef = useRef(null); - // Data preservation system for zoom operations - const dataBackupRef = useRef(new Map()); - // Chart health monitoring const chartHealthRef = useRef({ lastDataTimestamp: 0, @@ -238,7 +236,6 @@ const ChartjsPlot = ({ session, height = '400px' }) => { sessionId: session?.session_id, sessionActive: session?.is_active, sessionPaused: session?.is_paused, - dataBackupSize: dataBackupRef.current.size, health: chartHealthRef.current, datasets: chartRef.current?.data?.datasets?.length || 0, realtimeConfig: !!chartRef.current?.options?.scales?.x?.realtime @@ -615,7 +612,6 @@ const ChartjsPlot = ({ session, height = '400px' }) => { // Sort points by timestamp to ensure proper order historicalPoints.sort((a, b) => a.x - b.x); datasets[index].data = historicalPoints; - console.log(`πŸ“Š Added ${historicalPoints.length} historical points for ${variableInfo.name}`); } }); @@ -698,9 +694,9 @@ const ChartjsPlot = ({ session, height = '400px' }) => { }, ...(zoomAvailable ? { zoom: { - // Habilitar zoom/pan siempre, pero con configuraciΓ³n optimizada para streaming + // Enable/disable zoom/pan based on switch state pan: { - enabled: true, + enabled: isZoomEnabled, mode: 'x', modifierKey: 'shift', onPanComplete: function(context) { @@ -717,14 +713,14 @@ const ChartjsPlot = ({ session, height = '400px' }) => { }, zoom: { drag: { - enabled: true, + enabled: isZoomEnabled, backgroundColor: 'rgba(128,128,128,0.3)' }, wheel: { - enabled: true, + enabled: isZoomEnabled, speed: 0.1 }, - pinch: { enabled: true }, + pinch: { enabled: isZoomEnabled }, mode: 'x', onZoomComplete: function(context) { // Preserve streaming state and data after zoom @@ -848,7 +844,7 @@ const ChartjsPlot = ({ session, height = '400px' }) => { setError(error.message); setIsLoading(false); } - }, []); + }, [isZoomEnabled]); const onStreamingRefresh = useCallback(async (chart) => { const sessionId = sessionDataRef.current.sessionId; @@ -875,10 +871,6 @@ const ChartjsPlot = ({ session, height = '400px' }) => { const pointsAdded = addNewDataToStreaming(plotData, now); updatePointsCounter(plotData); - if (pointsAdded > 0) { - console.log(`πŸ“Š Plot ${sessionId}: Added ${pointsAdded} points to chart`); - } - // Auto-pause when no data arrives for several cycles; resume when data appears if (pointsAdded > 0) { sessionDataRef.current.noDataCycles = 0; @@ -990,18 +982,6 @@ const ChartjsPlot = ({ session, height = '400px' }) => { // Update health monitoring chartHealthRef.current.lastDataTimestamp = Date.now(); chartHealthRef.current.consecutiveErrors = 0; - - // Backup data periodically when significant data is added - if (pointsAdded > 5 && dataBackupRef.current) { - const backup = chart.data.datasets.map(dataset => ({ - label: dataset.label, - data: [...(dataset.data || [])], - timestamp: Date.now() - })); - - dataBackupRef.current.set('current', backup); - console.log(`πŸ“¦ Data backed up: ${backup.reduce((total, ds) => total + ds.data.length, 0)} points`); - } } else { // No new data received - increment error counter chartHealthRef.current.consecutiveErrors++; @@ -1113,7 +1093,6 @@ const ChartjsPlot = ({ session, height = '400px' }) => { // Sort points by timestamp to ensure proper order historicalPoints.sort((a, b) => a.x - b.x); chart.data.datasets[index].data = historicalPoints; - console.log(`πŸ“Š Added ${historicalPoints.length} historical points for ${variableInfo.name} on start`); } }); @@ -1206,9 +1185,45 @@ const ChartjsPlot = ({ session, height = '400px' }) => { // Get current time window (use same as initial load) const timeWindow = cfg.time_window || 3600; // Default 1 hour + const variableNames = enabledVariables.map(v => v.name); // Load fresh historical data - await loadHistoricalData(enabledVariables, timeWindow); + const historicalData = await loadHistoricalData(variableNames, timeWindow); + + if (historicalData.length > 0) { + console.log(`πŸ“Š Loaded ${historicalData.length} historical data points for reset`); + + // Group data by variable and add to appropriate dataset + const dataByVariable = {}; + historicalData.forEach(point => { + const { variable, timestamp, value } = point; + if (!dataByVariable[variable]) { + dataByVariable[variable] = []; + } + dataByVariable[variable].push({ + x: new Date(timestamp), + y: value + }); + }); + + // Add historical data to datasets + enabledVariables.forEach((variableInfo, index) => { + const historicalPoints = dataByVariable[variableInfo.name] || []; + if (historicalPoints.length > 0) { + // Sort points by timestamp to ensure proper order + historicalPoints.sort((a, b) => a.x - b.x); + chartRef.current.data.datasets[index].data = historicalPoints; + } + }); + + // Update chart with historical data + chartRef.current.update('quiet'); + + // Update data points counter + const totalHistoricalPoints = Object.values(dataByVariable).reduce((sum, points) => sum + points.length, 0); + setDataPointsCount(totalHistoricalPoints); + } + console.log('βœ… Historical data reloaded'); } @@ -1348,6 +1363,27 @@ const ChartjsPlot = ({ session, height = '400px' }) => { } }, [session?.isFullscreen, createStreamingChart]); + // Update zoom configuration when zoom enabled state changes + useEffect(() => { + if (!chartRef.current) return; + + const chart = chartRef.current; + const zoomPlugin = chart.options?.plugins?.zoom; + + if (zoomPlugin) { + // Update zoom configuration dynamically + zoomPlugin.pan.enabled = isZoomEnabled; + zoomPlugin.zoom.drag.enabled = isZoomEnabled; + zoomPlugin.zoom.wheel.enabled = isZoomEnabled; + zoomPlugin.zoom.pinch.enabled = isZoomEnabled; + + // Update the chart to apply the new configuration + chart.update('none'); + + console.log(`πŸ” Zoom/Pan ${isZoomEnabled ? 'enabled' : 'disabled'}`); + } + }, [isZoomEnabled]); + // Periodic health monitoring useEffect(() => { if (!session?.session_id || !chartRef.current) return; @@ -1569,24 +1605,35 @@ const ChartjsPlot = ({ session, height = '400px' }) => { πŸ“Š Loading historical data... )} - - {/* Data points counter */} - {dataPointsCount > 0 && ( - - πŸ“ˆ {dataPointsCount} points - - )} + + {/* Zoom/Pan Toggle Switch */} + + + πŸ” Zoom/Pan + + setIsZoomEnabled(e.target.checked)} + colorScheme="blue" + /> + {/* Reset Zoom Button */} {chartRef.current && ( @@ -1676,16 +1723,19 @@ const ChartjsPlot = ({ session, height = '400px' }) => { {/* Points counter */} - Points: {dataPointsCount} + πŸ“Š {dataPointsCount} points ); diff --git a/system_state.json b/system_state.json index 024e8b7..f88f4dd 100644 --- a/system_state.json +++ b/system_state.json @@ -3,11 +3,11 @@ "should_connect": true, "should_stream": false, "active_datasets": [ - "DAR", "Fast", - "Test" + "Test", + "DAR" ] }, "auto_recovery_enabled": true, - "last_update": "2025-08-15T00:46:30.361074" + "last_update": "2025-08-15T00:56:33.380433" } \ No newline at end of file