S7_snap7_Stremer_n_Recorder/.github/copilot-instructions.md

10 KiB

PLC S7-315 Streamer & Logger - AI Coding Guide

Workingflow

I m usign npm run dev so there is no need to build react Also restart flask every time there is any modification to reset the application So for testing the app now is running on http://localhost:5173/app with vite doing proxy

Architecture Overview

This is a dual-stack industrial automation system for Siemens S7-315 PLCs combining Python backend orchestration with React frontend controls:

  • Backend: Flask app (main.py) orchestrating core modules via PLCDataStreamer
  • Frontend: Vite + React + Chakra UI + RJSF for dynamic configuration forms
  • Data Flow: PLC → snap7 → CSV recording + UDP streaming → PlotJuggler visualization
  • Configuration: JSON Schema-driven with validation for PLC variables and plot definitions

Core Architecture Principles

1. Orchestrator Pattern

core/plc_data_streamer.py is the main coordinator that initializes and manages:

  • ConfigManager: JSON configuration persistence with schema validation
  • PLCClient: Siemens snap7 communication
  • DataStreamer: Independent CSV recording + UDP streaming threads
  • EventLogger: Persistent application event logging
  • InstanceManager: Single-instance control with auto-recovery

2. Independent Data Streams

Critical: CSV recording and UDP streaming are separate concerns:

  • CSV recording: Always active when PLC connected (automatic)
  • UDP streaming: Manual control for PlotJuggler visualization
  • Each dataset thread handles both, but UDP transmission is independently controlled

3. Schema-Driven Configuration with RJSF

All configuration uses JSON Schema validation with React JSON Schema Forms (RJSF):

  • Frontend-First Validation: RJSF handles all form generation and validation
  • Backend API Simplification: Flask provides simple CRUD operations for JSON files
  • Array-Based Data Structure: All configurations use array format for RJSF compatibility
  • Three Form Types:
    • Type 1: Single object forms (PLC config)
    • Type 2: Array management forms (dataset definitions, plot definitions)
    • Type 3: Filtered array forms with combo selectors (variables linked to datasets/plots)

4. JSON Configuration Structure

CRITICAL: All JSON files use array-based structures for RJSF compatibility:

  • plc_config.json: Single object with udp_config containing sampling_interval
  • dataset_definitions.json: {"datasets": [{"id": "DAR", "name": "...", ...}]}
  • dataset_variables.json: {"variables": [{"dataset_id": "DAR", "variables": [...]}]}
  • plot_definitions.json: {"plots": [{"id": "plot1", "name": "...", ...}]}
  • plot_variables.json: {"plot_variables": [{"plot_id": "plot1", "variables": [...]}]}

Development Workflows

Backend Development

# Setup Python environment (REQUIRED before any Python work)
conda create -n plc_streamer python=3.10
conda activate plc_streamer
pip install -r requirements.txt

# Run backend server
python main.py
# Access at http://localhost:5000

Frontend Development

cd frontend
npm install
npm run dev  # Development server at http://localhost:5173
npm run build  # Production build to dist/

Key External Dependencies

  • snap7.dll: Must be in system PATH or project root for PLC communication
  • PlotJuggler: Configured to receive UDP JSON at 127.0.0.1:9870

Critical File Patterns

Configuration Management

  • config/data/*.json: Runtime configuration files
  • config/schema/*.json: JSON Schema definitions
  • ConfigSchemaManager in core/schema_manager.py: Centralized schema loading and validation

Frontend Components

  • pages/DashboardNew.jsx: Main control interface with tabbed layout
  • components/EditableTable.jsx: Reusable schema-to-table converter
  • components/PlotManager.jsx: Real-time Chart.js plotting with streaming
  • Pattern: RJSF forms for configuration, custom tables for data management

API Endpoints Structure

Flask routes in main.py follow simplified REST patterns with unified JSON handling:

  • /api/config/*: Unified configuration CRUD operations for all JSON files
  • /api/plc/*: PLC connection and status
  • /api/streaming/*: Data streaming controls
  • /api/plots/*: Plot session management
  • API Philosophy: Backend provides simple file I/O, frontend handles all validation via RJSF

Important Conventions

1. Error Handling & Logging

  • All core classes require logger injection: __init__(self, logger)
  • Use self.event_logger.log_event() for persistent events
  • PyInstaller compatibility: Use resource_path() for file access

2. React Component Patterns

  • FormTable.jsx: Single-row forms per item using RJSF schemas
  • DatasetFormManager/PlotFormManager: Master-detail table management
  • Chakra UI components with consistent styling via theme.js
  • RJSF Integration: All forms auto-generated from JSON Schema, no hardcoded form fields

3. Thread Safety

  • Data streaming uses thread-safe collections and proper cleanup
  • Instance management prevents multiple app instances
  • Background threads properly handle graceful shutdown

4. Schema Evolution

Follow existing patterns in config/schema/ - all forms are auto-generated from JSON Schema + UI Schema combinations. Never hardcode form fields.

  • Array-First Design: All multi-item configurations use array structures for RJSF type 2 forms
  • Unified Validation: JSON Schema validation both client-side (RJSF) and server-side (jsonschema library)
  • Schema-UI Separation: Data schemas in /config/schema/, UI schemas in /config/schema/ui/

5. Development Context

  • Use .doc/MemoriaDeEvolucion.md for understanding recent changes and decisions
  • Comments and variables must be in English per project conventions
  • No standalone markdown files unless specifically requested

Integration Points

PLC Communication

  • Data blocks accessed via DB{number}.{offset} addressing
  • Supported types: REAL, INT, DINT, BOOL
  • Connection state managed through PLCClient with automatic reconnection

Real-time Visualization

  • Chart.js with chartjs-plugin-streaming for real-time plots
  • Automatic data ingestion from /api/plots/{session_id}/data
  • Plot session lifecycle managed through backend API

CSV Data Export

  • Automatic file rotation by size/time in records/ directory
  • Thread-safe CSV writing with proper cleanup
  • Configurable retention policies for long-term storage

Notes

Always write software variables and comments in English The development is focused on Windows and after testing must work without CDN completely offline.

RJSF Configuration Management

Form Type Architecture

The system implements three distinct RJSF form patterns:

Type 1: Single Object Forms

  • Used for: PLC configuration (plc_config.json)
  • Structure: Single JSON object with nested properties
  • RJSF Pattern: Direct object form rendering
  • Example: Connection settings, UDP configuration with sampling_interval

Type 2: Array Management Forms

  • Used for: Dataset definitions (dataset_definitions.json), Plot definitions (plot_definitions.json)
  • Structure: {"datasets": [...]} or {"plots": [...]}
  • RJSF Pattern: Array form with add/remove/edit capabilities
  • Critical: Root must be array wrapper for RJSF compatibility

Type 3: Filtered Array Forms with Combo Selectors

  • Used for: Variables linked to datasets/plots (dataset_variables.json, plot_variables.json)
  • Structure: Array with foreign key references (dataset_id, plot_id)
  • RJSF Pattern: Filtered forms based on selected dataset/plot
  • Workflow: Select parent → Edit associated variables
  • Implementation: Combo selector + dynamic schema generation for selected item
  • Key Functions: getSelectedDatasetVariables(), updateSelectedDatasetVariables()

RJSF Best Practices and Common Pitfalls

Critical Widget Guidelines:

  • Arrays: Never specify "ui:widget": "array" - arrays use built-in ArrayField component
  • Valid Widgets: text, textarea, select, checkbox, updown, variableSelector
  • Widget Registry: All widgets must be registered in AllWidgets.jsx
  • Custom Widgets: Use specific widget names, avoid generic type names

Schema Structure Rules:

  • Array Items: Always include title property for array item schemas
  • UI Layout: Use "ui:layout" for grid-based field arrangement
  • Field Templates: Leverage LayoutObjectFieldTemplate for responsive layouts
  • Error Handling: RJSF errors often indicate missing widgets or malformed schemas

Type 3 Form Implementation Pattern

// Step 1: Parent Selector (Combo)
const [selectedItemId, setSelectedItemId] = useState('')

// Step 2: Filtered Data Helper
const getSelectedItemData = () => {
    return allData.find(item => item.parent_id === selectedItemId) || defaultData
}

// Step 3: Update Helper  
const updateSelectedItemData = (newData) => {
    const updated = allData.map(item => 
        item.parent_id === selectedItemId ? { ...item, ...newData } : item
    )
    setAllData({ ...allData, items: updated })
}

// Step 4: Dynamic Schema Generation
const dynamicSchema = {
    type: "object",
    properties: { /* fields specific to selected item */ }
}

JSON Schema Migration Notes

  • Legacy to Array: All object-based configs converted to array format
  • ID Fields: Added explicit id fields to all array items for referencing
  • Validation: Unified validation using jsonschema library server-side + RJSF client-side
  • Backward Compatibility: Migration handled in backend for existing configurations

Development Debugging Guide

RJSF Error Resolution:

  • No widget 'X' for type 'Y': Check widget registration in AllWidgets.jsx
  • Array rendering errors: Remove "ui:widget" specification from array fields
  • Schema validation failures: Use validate_schema.py to test JSON structure
  • Form not displaying: Verify schema structure matches expected Type 1/2/3 pattern

Type 3 Form Debugging:

  • Combo not showing options: Check parent data loading and availableItems array
  • Form not updating: Verify selectedItemId state and helper functions
  • Data not persisting: Check updateSelectedItemData() logic and save operations
  • Schema errors: Ensure dynamic schema generation matches data structure

Frontend-Backend Integration:

  • API endpoint naming: Use consistent /api/config/{config-name} pattern
  • JSON structure validation: Backend uses jsonschema, frontend uses RJSF validation
  • Error handling: Both client and server should handle array format gracefully
  • Configuration loading: Always verify API response structure before setting form data