feat: Enhance application event logging; add tooltips for UI fields and improve PLC configuration descriptions

This commit is contained in:
Miguel 2025-08-27 12:45:19 +02:00
parent cda40ce0ab
commit dec3a49836
7 changed files with 374 additions and 9 deletions

View File

@ -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
}

View File

@ -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,

View File

@ -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}

View File

@ -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 <div style={{ display: 'none' }}>{children}</div>
}
// 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 ? (
<ChakraTooltip
label={tooltipContent}
hasArrow
>
<Box w="full">
{children}
</Box>
</ChakraTooltip>
) : children
return (
<FormControl isInvalid={!!errors} isRequired={required}>
{wrappedChildren}
{errors && (
<FormErrorMessage>
{errors}
</FormErrorMessage>
)}
{/* Intentionally removed description display since it will be shown in tooltip */}
</FormControl>
)
}

View File

@ -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 (
<ChakraTooltip
label={label}
{...rest}
>
{children}
</ChakraTooltip>
)
})

View File

@ -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)}
>

View File

@ -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"
}