Update application events and system state. Removed obsolete events, added new application start and dataset activation events, and updated last update timestamp in system state.

This commit is contained in:
Miguel 2025-08-14 11:27:50 +02:00
parent 2845d71efe
commit 9618984a2b
3 changed files with 255 additions and 81 deletions

View File

@ -1,46 +1,5 @@
{
"events": [
{
"timestamp": "2025-07-17T17:42:25.463541",
"level": "error",
"event_type": "dataset_streaming_error",
"message": "Error in dataset 'DAR' streaming loop: dictionary changed size during iteration",
"details": {
"dataset_id": "dar",
"error": "dictionary changed size during iteration",
"consecutive_errors": 1
}
},
{
"timestamp": "2025-07-17T17:43:27.747295",
"level": "info",
"event_type": "dataset_created",
"message": "Dataset created: mixer (prefix: mixer)",
"details": {
"dataset_id": "mixer",
"name": "mixer",
"prefix": "mixer",
"sampling_interval": 1.0
}
},
{
"timestamp": "2025-07-17T17:57:48.090115",
"level": "info",
"event_type": "Application started",
"message": "Application initialization completed successfully",
"details": {}
},
{
"timestamp": "2025-07-17T17:57:48.111503",
"level": "info",
"event_type": "plc_connection",
"message": "Successfully connected to PLC 10.1.33.11",
"details": {
"ip": "10.1.33.11",
"rack": 0,
"slot": 2
}
},
{
"timestamp": "2025-07-17T17:57:48.115971",
"level": "info",
@ -10421,8 +10380,44 @@
"trigger_variable": null,
"auto_started": true
}
},
{
"timestamp": "2025-08-14T11:26:02.147101",
"level": "info",
"event_type": "application_started",
"message": "Application initialization completed successfully",
"details": {}
},
{
"timestamp": "2025-08-14T11:26:02.211520",
"level": "info",
"event_type": "dataset_activated",
"message": "Dataset activated: DAR",
"details": {
"dataset_id": "DAR",
"variables_count": 3,
"streaming_count": 3,
"prefix": "gateway_phoenix"
}
},
{
"timestamp": "2025-08-14T11:26:02.225519",
"level": "info",
"event_type": "csv_recording_started",
"message": "CSV recording started: 1 datasets activated",
"details": {
"activated_datasets": 1,
"total_datasets": 3
}
},
{
"timestamp": "2025-08-14T11:26:02.293765",
"level": "error",
"event_type": "csv_cleanup_failed",
"message": "CSV cleanup failed: 'max_hours'",
"details": {}
}
],
"last_updated": "2025-08-14T11:15:09.838725",
"last_updated": "2025-08-14T11:26:02.293765",
"total_entries": 1000
}

View File

@ -28,7 +28,8 @@ import {
TabPanels,
Tab,
TabPanel,
Divider
Divider,
Select
} from '@chakra-ui/react'
import Form from '@rjsf/chakra-ui'
import validator from '@rjsf/validator-ajv8'
@ -44,6 +45,7 @@ export default function PlotManager() {
const [plotsVariablesSchemaData, setPlotsVariablesSchemaData] = useState(null)
const [plotsConfig, setPlotsConfig] = useState(null)
const [plotsVariablesConfig, setPlotsVariablesConfig] = useState(null)
const [selectedPlotId, setSelectedPlotId] = useState('')
const [loading, setLoading] = useState(true)
const [actionLoading, setActionLoading] = useState({})
@ -77,6 +79,11 @@ export default function PlotManager() {
setPlotsVariablesSchemaData(plotsVariablesSchemaResponse)
setPlotsConfig(plotsConfigData)
setPlotsVariablesConfig(plotsVariablesConfigData)
// Auto-select first plot if none selected
if (!selectedPlotId && plotsConfigData?.plots?.length > 0) {
setSelectedPlotId(plotsConfigData.plots[0].id)
}
} catch (error) {
toast({
title: '❌ Failed to load plot data',
@ -101,6 +108,42 @@ export default function PlotManager() {
return plotVarEntry?.variables || []
}
// Type 3 Pattern Helper Functions
// Get filtered variables for selected plot
const getSelectedPlotVariables = () => {
if (!plotsVariablesConfig?.variables || !selectedPlotId) {
return { variables: [] }
}
const plotVars = plotsVariablesConfig.variables.find(v => v.plot_id === selectedPlotId)
return plotVars || { variables: [] }
}
// Update variables for selected plot
const updateSelectedPlotVariables = (newVariableData) => {
if (!plotsVariablesConfig?.variables || !selectedPlotId) return
const updatedVariables = plotsVariablesConfig.variables.map(v =>
v.plot_id === selectedPlotId
? { ...v, ...newVariableData }
: v
)
// If plot not found, add new entry
if (!plotsVariablesConfig.variables.find(v => v.plot_id === selectedPlotId)) {
updatedVariables.push({
plot_id: selectedPlotId,
...newVariableData
})
}
const updatedConfig = { ...plotsVariablesConfig, variables: updatedVariables }
setPlotsVariablesConfig(updatedConfig)
}
// Available plots for combo selector
const availablePlots = plotsConfig?.plots || []
// Handle plot configuration updates
const handlePlotConfigUpdate = async (plotId, newConfig) => {
try {
@ -310,42 +353,178 @@ export default function PlotManager() {
</TabPanel>
<TabPanel p={0} pt={4}>
{plotsVariablesSchemaData?.schema && plotsVariablesConfig && (
<Card bg={cardBg} borderColor={borderColor}>
<CardHeader>
<Heading size="md">Plot Variables Configuration</Heading>
<Text fontSize="sm" color="gray.500" mt={1}>
Configure which variables are displayed in each plot session
</Text>
</CardHeader>
<CardBody>
<Form
schema={plotsVariablesSchemaData.schema}
uiSchema={plotsVariablesSchemaData.uiSchema}
formData={plotsVariablesConfig}
validator={validator}
widgets={allWidgets}
templates={{ ObjectFieldTemplate: LayoutObjectFieldTemplate }}
onSubmit={({ formData }) => savePlotsVariablesConfig(formData)}
onChange={({ formData }) => setPlotsVariablesConfig(formData)}
>
<HStack spacing={2} mt={4}>
<Button
type="submit"
colorScheme="blue"
isLoading={actionLoading.savePlotsVariables}
loadingText="Saving..."
>
💾 Save Variables
</Button>
<Button variant="outline" onClick={loadPlotData}>
🔄 Reset
</Button>
</HStack>
</Form>
</CardBody>
</Card>
)}
{/* Plot Variables Configuration with Combo Selector - Type 3 Pattern */}
<Card bg={cardBg} borderColor={borderColor}>
<CardHeader>
<Heading size="md">Plot Variables Configuration</Heading>
<Text fontSize="sm" color="gray.500" mt={1}>
Select a plot session, then configure which variables are displayed in that plot
</Text>
</CardHeader>
<CardBody>
{/* Step 1: Plot Selector (Combo) */}
<VStack spacing={4} align="stretch">
<Box>
<Text fontSize="sm" fontWeight="bold" mb={2}>
🎯 Select Plot Session
</Text>
<Select
value={selectedPlotId}
onChange={(e) => setSelectedPlotId(e.target.value)}
placeholder="Choose a plot session to configure..."
size="md"
>
{availablePlots.map(plot => (
<option key={plot.id} value={plot.id}>
📈 {plot.name} ({plot.id})
</option>
))}
</Select>
{availablePlots.length === 0 && (
<Text fontSize="sm" color="orange.500" mt={2}>
No plot sessions available. Configure plot definitions first in the "Plot Definitions" tab.
</Text>
)}
</Box>
{/* Variables Configuration Form */}
{selectedPlotId && (
<Box>
<Divider mb={4} />
<Text fontSize="sm" fontWeight="bold" mb={2}>
Configure Variables for Plot "{selectedPlotId}"
</Text>
{/* Simplified schema for selected plot variables */}
{(() => {
const selectedPlotVars = getSelectedPlotVariables()
// Schema for this plot's variables
const singlePlotSchema = {
type: "object",
properties: {
variables: {
type: "array",
title: "Variables",
description: `Variables to display in plot ${selectedPlotId}`,
items: {
type: "object",
title: "Plot Variable",
properties: {
dataset_id: {
type: "string",
title: "Dataset Source",
description: "Which dataset contains this variable"
},
variable_name: {
type: "string",
title: "Variable Name",
description: "Name of the variable to plot"
},
label: {
type: "string",
title: "Display Label",
description: "Label shown in the plot legend"
},
color: {
type: "string",
title: "Line Color",
default: "#3182CE"
},
line_width: {
type: "number",
title: "Line Width",
default: 2,
minimum: 1,
maximum: 10
},
y_axis: {
type: "string",
title: "Y-Axis",
enum: ["left", "right"],
default: "left"
}
},
required: ["dataset_id", "variable_name", "label"]
}
}
}
}
const singlePlotUiSchema = {
variables: {
items: {
"ui:layout": [[
{ "name": "dataset_id", "width": 2 },
{ "name": "variable_name", "width": 3 },
{ "name": "label", "width": 2 },
{ "name": "color", "width": 2 },
{ "name": "line_width", "width": 1 },
{ "name": "y_axis", "width": 2 }
]]
}
}
}
return (
<Form
schema={singlePlotSchema}
uiSchema={singlePlotUiSchema}
formData={selectedPlotVars}
validator={validator}
widgets={allWidgets}
templates={{ ObjectFieldTemplate: LayoutObjectFieldTemplate }}
onSubmit={({ formData }) => {
updateSelectedPlotVariables(formData)
// Create updated config and save it
const updatedVariables = plotsVariablesConfig.variables?.map(v =>
v.plot_id === selectedPlotId
? { ...v, ...formData }
: v
) || []
// If plot not found, add new entry
if (!plotsVariablesConfig.variables?.find(v => v.plot_id === selectedPlotId)) {
updatedVariables.push({
plot_id: selectedPlotId,
...formData
})
}
const updatedConfig = { ...plotsVariablesConfig, variables: updatedVariables }
savePlotsVariablesConfig(updatedConfig)
}}
onChange={({ formData }) => updateSelectedPlotVariables(formData)}
>
<HStack spacing={2} mt={4}>
<Button
type="submit"
colorScheme="blue"
isLoading={actionLoading.savePlotsVariables}
loadingText="Saving..."
>
💾 Save Variables for {selectedPlotId}
</Button>
<Button variant="outline" onClick={loadPlotData}>
🔄 Reset
</Button>
</HStack>
</Form>
)
})()}
</Box>
)}
{!selectedPlotId && availablePlots.length > 0 && (
<Box textAlign="center" py={8}>
<Text color="gray.500">
👆 Select a plot session above to configure its variables
</Text>
</Box>
)}
</VStack>
</CardBody>
</Card>
</TabPanel>
</TabPanels>
</Tabs>

View File

@ -3,11 +3,11 @@
"should_connect": true,
"should_stream": false,
"active_datasets": [
"Test",
"DAR",
"Test",
"Fast"
]
},
"auto_recovery_enabled": true,
"last_update": "2025-08-14T11:14:46.738038"
"last_update": "2025-08-14T11:26:02.237589"
}