diff --git a/application_events.json b/application_events.json index 8a32d5f..5a7aaf4 100644 --- a/application_events.json +++ b/application_events.json @@ -1916,8 +1916,278 @@ "event_type": "application_started", "message": "Application initialization completed successfully", "details": {} + }, + { + "timestamp": "2025-08-27T12:13:17.964520", + "level": "info", + "event_type": "udp_streaming_stopped", + "message": "UDP streaming to PlotJuggler stopped (CSV recording continues)", + "details": {} + }, + { + "timestamp": "2025-08-27T12:13:17.968522", + "level": "info", + "event_type": "csv_recording_stopped", + "message": "🔥 CRITICAL: CSV recording stopped (dataset threads continue for UDP streaming)", + "details": { + "recording_protection": false, + "performance_monitoring": false + } + }, + { + "timestamp": "2025-08-27T12:13:17.970522", + "level": "info", + "event_type": "udp_streaming_stopped", + "message": "UDP streaming to PlotJuggler stopped (CSV recording continues)", + "details": {} + }, + { + "timestamp": "2025-08-27T12:13:17.973523", + "level": "info", + "event_type": "dataset_deactivated", + "message": "Dataset deactivated: DAR", + "details": { + "dataset_id": "DAR" + } + }, + { + "timestamp": "2025-08-27T12:13:17.976522", + "level": "info", + "event_type": "plc_disconnection", + "message": "Disconnected from PLC 10.1.33.11 (application shutdown (will auto-reconnect on restart))", + "details": {} + }, + { + "timestamp": "2025-08-27T12:13:36.526402", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-27T12:13:37.537542", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-27T12:22:27.597570", + "level": "info", + "event_type": "udp_streaming_stopped", + "message": "UDP streaming to PlotJuggler stopped (CSV recording continues)", + "details": {} + }, + { + "timestamp": "2025-08-27T12:22:27.603988", + "level": "info", + "event_type": "csv_recording_stopped", + "message": "🔥 CRITICAL: CSV recording stopped (dataset threads continue for UDP streaming)", + "details": { + "recording_protection": false, + "performance_monitoring": false + } + }, + { + "timestamp": "2025-08-27T12:22:27.606986", + "level": "info", + "event_type": "udp_streaming_stopped", + "message": "UDP streaming to PlotJuggler stopped (CSV recording continues)", + "details": {} + }, + { + "timestamp": "2025-08-27T12:22:27.609986", + "level": "info", + "event_type": "dataset_deactivated", + "message": "Dataset deactivated: DAR", + "details": { + "dataset_id": "DAR" + } + }, + { + "timestamp": "2025-08-27T12:22:27.612494", + "level": "info", + "event_type": "plc_disconnection", + "message": "Disconnected from PLC 10.1.33.11 (application shutdown (will auto-reconnect on restart))", + "details": {} + }, + { + "timestamp": "2025-08-27T12:22:41.364802", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-27T12:22:42.376711", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-27T12:28:07.306476", + "level": "info", + "event_type": "udp_streaming_stopped", + "message": "UDP streaming to PlotJuggler stopped (CSV recording continues)", + "details": {} + }, + { + "timestamp": "2025-08-27T12:28:07.310114", + "level": "info", + "event_type": "csv_recording_stopped", + "message": "🔥 CRITICAL: CSV recording stopped (dataset threads continue for UDP streaming)", + "details": { + "recording_protection": false, + "performance_monitoring": false + } + }, + { + "timestamp": "2025-08-27T12:28:07.313213", + "level": "info", + "event_type": "udp_streaming_stopped", + "message": "UDP streaming to PlotJuggler stopped (CSV recording continues)", + "details": {} + }, + { + "timestamp": "2025-08-27T12:28:07.317658", + "level": "info", + "event_type": "dataset_deactivated", + "message": "Dataset deactivated: DAR", + "details": { + "dataset_id": "DAR" + } + }, + { + "timestamp": "2025-08-27T12:28:07.321497", + "level": "info", + "event_type": "plc_disconnection", + "message": "Disconnected from PLC 10.1.33.11 (application shutdown (will auto-reconnect on restart))", + "details": {} + }, + { + "timestamp": "2025-08-27T12:28:21.068942", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-27T12:28:22.085957", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-27T12:37:50.695486", + "level": "info", + "event_type": "udp_streaming_stopped", + "message": "UDP streaming to PlotJuggler stopped (CSV recording continues)", + "details": {} + }, + { + "timestamp": "2025-08-27T12:37:50.700489", + "level": "info", + "event_type": "csv_recording_stopped", + "message": "🔥 CRITICAL: CSV recording stopped (dataset threads continue for UDP streaming)", + "details": { + "recording_protection": false, + "performance_monitoring": false + } + }, + { + "timestamp": "2025-08-27T12:37:50.705227", + "level": "info", + "event_type": "udp_streaming_stopped", + "message": "UDP streaming to PlotJuggler stopped (CSV recording continues)", + "details": {} + }, + { + "timestamp": "2025-08-27T12:37:50.709226", + "level": "info", + "event_type": "dataset_deactivated", + "message": "Dataset deactivated: DAR", + "details": { + "dataset_id": "DAR" + } + }, + { + "timestamp": "2025-08-27T12:37:50.712236", + "level": "info", + "event_type": "plc_disconnection", + "message": "Disconnected from PLC 10.1.33.11 (application shutdown (will auto-reconnect on restart))", + "details": {} + }, + { + "timestamp": "2025-08-27T12:38:05.475657", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-27T12:38:06.488937", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-27T12:43:42.407901", + "level": "info", + "event_type": "udp_streaming_stopped", + "message": "UDP streaming to PlotJuggler stopped (CSV recording continues)", + "details": {} + }, + { + "timestamp": "2025-08-27T12:43:42.412929", + "level": "info", + "event_type": "csv_recording_stopped", + "message": "🔥 CRITICAL: CSV recording stopped (dataset threads continue for UDP streaming)", + "details": { + "recording_protection": false, + "performance_monitoring": false + } + }, + { + "timestamp": "2025-08-27T12:43:42.418915", + "level": "info", + "event_type": "udp_streaming_stopped", + "message": "UDP streaming to PlotJuggler stopped (CSV recording continues)", + "details": {} + }, + { + "timestamp": "2025-08-27T12:43:42.422287", + "level": "info", + "event_type": "dataset_deactivated", + "message": "Dataset deactivated: DAR", + "details": { + "dataset_id": "DAR" + } + }, + { + "timestamp": "2025-08-27T12:43:42.427798", + "level": "info", + "event_type": "plc_disconnection", + "message": "Disconnected from PLC 10.1.33.11 (application shutdown (will auto-reconnect on restart))", + "details": {} + }, + { + "timestamp": "2025-08-27T12:43:56.185470", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-27T12:43:57.197628", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} } ], - "last_updated": "2025-08-27T11:20:49.372928", - "total_entries": 95 + "last_updated": "2025-08-27T12:43:57.197628", + "total_entries": 130 } \ No newline at end of file diff --git a/config/schema/ui/plc.uischema.json b/config/schema/ui/plc.uischema.json index 5f7b5b3..a6589c7 100644 --- a/config/schema/ui/plc.uischema.json +++ b/config/schema/ui/plc.uischema.json @@ -63,15 +63,18 @@ "plc_config": { "ip": { "ui:column": 6, - "ui:placeholder": "192.168.1.100" + "ui:placeholder": "192.168.1.100", + "ui:description": "🌐 IP address of the Siemens S7-300/400 PLC (e.g., 192.168.1.100)" }, "rack": { "ui:column": 3, - "ui:widget": "updown" + "ui:widget": "updown", + "ui:description": "🏗️ PLC rack number (usually 0 for S7-300/400)" }, "slot": { "ui:column": 3, - "ui:widget": "updown" + "ui:widget": "updown", + "ui:description": "🔌 PLC slot number (typically 2 for CPU)" }, "symbols_path": { "ui:column": 12, diff --git a/frontend/src/components/PLCConfigManager.jsx b/frontend/src/components/PLCConfigManager.jsx index a5048da..0c5ab37 100644 --- a/frontend/src/components/PLCConfigManager.jsx +++ b/frontend/src/components/PLCConfigManager.jsx @@ -21,6 +21,7 @@ import { FiUpload } from 'react-icons/fi' import Form from '@rjsf/chakra-ui' import validator from '@rjsf/validator-ajv8' import LayoutObjectFieldTemplate from './rjsf/LayoutObjectFieldTemplate.jsx' +import TooltipFieldTemplate from './rjsf/TooltipFieldTemplate.jsx' import { widgets } from './rjsf/widgets.jsx' import { getSchema, readConfig, writeConfig } from '../services/api.js' @@ -241,7 +242,10 @@ export default function PLCConfigManager() { validator={validator} onChange={editing ? handleChange : () => { }} onSubmit={editing ? () => handleSave() : undefined} - templates={{ ObjectFieldTemplate: LayoutObjectFieldTemplate }} + templates={{ + ObjectFieldTemplate: LayoutObjectFieldTemplate, + FieldTemplate: TooltipFieldTemplate + }} widgets={widgets} readonly={!editing} showErrorList={false} diff --git a/frontend/src/components/rjsf/TooltipFieldTemplate.jsx b/frontend/src/components/rjsf/TooltipFieldTemplate.jsx new file mode 100644 index 0000000..130f382 --- /dev/null +++ b/frontend/src/components/rjsf/TooltipFieldTemplate.jsx @@ -0,0 +1,57 @@ +import React from 'react' +import { Box, FormControl, FormErrorMessage, Tooltip as ChakraTooltip } from '@chakra-ui/react' + +/** + * Custom RJSF Field Template with integrated tooltips + * Shows ui:description as tooltip on hover over the field + * Removes the description text that normally appears below the field + */ +export default function TooltipFieldTemplate(props) { + const { + id, + label, + children, + errors, + help, + description, + hidden, + required, + displayLabel, + schema, + uiSchema + } = props + + if (hidden) { + return
{children}
+ } + + // Get description from uiSchema if available + const tooltipContent = uiSchema?.['ui:description'] || description + + // Only show tooltip if there's actual content (not empty string or whitespace) + const hasTooltipContent = tooltipContent && typeof tooltipContent === 'string' && tooltipContent.trim().length > 0 + + // If there's tooltip content, wrap just the children (input/widget) in tooltip + const wrappedChildren = hasTooltipContent ? ( + + + {children} + + + ) : children + + return ( + + {wrappedChildren} + {errors && ( + + {errors} + + )} + {/* Intentionally removed description display since it will be shown in tooltip */} + + ) +} diff --git a/frontend/src/components/ui/tooltip.jsx b/frontend/src/components/ui/tooltip.jsx new file mode 100644 index 0000000..d7a56ae --- /dev/null +++ b/frontend/src/components/ui/tooltip.jsx @@ -0,0 +1,25 @@ +import { Tooltip as ChakraTooltip } from "@chakra-ui/react" +import * as React from "react" + +export const Tooltip = React.forwardRef(function Tooltip(props, ref) { + const { + children, + disabled, + label, + ...rest + } = props + + // Debug logging + console.log('Tooltip render:', { label, disabled, hasChildren: !!children }) + + if (disabled || !label) return children + + return ( + + {children} + + ) +}) diff --git a/frontend/src/pages/Dashboard.jsx b/frontend/src/pages/Dashboard.jsx index e9d479b..35fd6ce 100644 --- a/frontend/src/pages/Dashboard.jsx +++ b/frontend/src/pages/Dashboard.jsx @@ -61,6 +61,7 @@ import PlotManager from '../components/PlotManager' import PlotHistoricalManager from '../components/PlotHistoricalManager' import allWidgets from '../components/widgets/AllWidgets' import LayoutObjectFieldTemplate from '../components/rjsf/LayoutObjectFieldTemplate' +import TooltipFieldTemplate from '../components/rjsf/TooltipFieldTemplate' import CsvFileBrowser from '../components/CsvFileBrowser' import { VariableProvider, useVariableContext } from '../contexts/VariableContext' import * as api from '../services/api' @@ -1186,7 +1187,10 @@ function ConfigurationPanel({ schemaData, formData, onFormChange, onSave, saving formData={formData} validator={validator} widgets={allWidgets} - templates={{ ObjectFieldTemplate: LayoutObjectFieldTemplate }} + templates={{ + ObjectFieldTemplate: LayoutObjectFieldTemplate, + FieldTemplate: TooltipFieldTemplate + }} onChange={({ formData }) => onFormChange(formData)} onSubmit={({ formData }) => onSave(formData)} > diff --git a/system_state.json b/system_state.json index e6f26c1..e1120d6 100644 --- a/system_state.json +++ b/system_state.json @@ -2,9 +2,11 @@ "last_state": { "should_connect": false, "should_stream": false, - "active_datasets": [] + "active_datasets": [ + "DAR" + ] }, "auto_recovery_enabled": true, - "last_update": "2025-08-27T11:21:07.224296", + "last_update": "2025-08-27T12:43:58.812150", "plotjuggler_path": "C:\\Program Files\\PlotJuggler\\plotjuggler.exe" } \ No newline at end of file