feat: Enhance event logging for plot sessions, improve zoom functionality, and update dataset configurations
This commit is contained in:
parent
438ebc1462
commit
addd9fa6bc
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
||||
}
|
||||
]
|
||||
|
|
|
@ -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...
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Data points counter */}
|
||||
{dataPointsCount > 0 && (
|
||||
<Box
|
||||
position="absolute"
|
||||
top={2}
|
||||
left={2}
|
||||
bg="green.500"
|
||||
color="white"
|
||||
px={2}
|
||||
py={1}
|
||||
borderRadius="md"
|
||||
fontSize="xs"
|
||||
zIndex={10}
|
||||
>
|
||||
📈 {dataPointsCount} points
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Zoom/Pan Toggle Switch */}
|
||||
<HStack
|
||||
position="absolute"
|
||||
top={2}
|
||||
left={2}
|
||||
bg="rgba(255, 255, 255, 0.95)"
|
||||
backdropFilter="blur(8px)"
|
||||
borderWidth="1px"
|
||||
borderColor="gray.200"
|
||||
px={3}
|
||||
py={2}
|
||||
borderRadius="lg"
|
||||
fontSize="xs"
|
||||
zIndex={10}
|
||||
spacing={2}
|
||||
shadow="sm"
|
||||
>
|
||||
<FormLabel htmlFor="zoom-switch" mb={0} fontSize="xs" color="gray.700" fontWeight="medium">
|
||||
🔍 Zoom/Pan
|
||||
</FormLabel>
|
||||
<Switch
|
||||
id="zoom-switch"
|
||||
size="sm"
|
||||
isChecked={isZoomEnabled}
|
||||
onChange={(e) => setIsZoomEnabled(e.target.checked)}
|
||||
colorScheme="blue"
|
||||
/>
|
||||
</HStack>
|
||||
|
||||
{/* Reset Zoom Button */}
|
||||
{chartRef.current && (
|
||||
|
@ -1676,16 +1723,19 @@ const ChartjsPlot = ({ session, height = '400px' }) => {
|
|||
{/* Points counter */}
|
||||
<Box
|
||||
position="absolute"
|
||||
top={2}
|
||||
top={isLoadingHistorical ? 12 : 2}
|
||||
right={2}
|
||||
bg="rgba(0,0,0,0.7)"
|
||||
bg="rgba(0,0,0,0.75)"
|
||||
color="white"
|
||||
px={2}
|
||||
py={1}
|
||||
borderRadius="sm"
|
||||
borderRadius="md"
|
||||
fontSize="xs"
|
||||
fontWeight="medium"
|
||||
shadow="sm"
|
||||
zIndex={5}
|
||||
>
|
||||
Points: {dataPointsCount}
|
||||
📊 {dataPointsCount} points
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
|
|
@ -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"
|
||||
}
|
Loading…
Reference in New Issue