plceye
A static analyzer and code smell detector for PLC files.
Supported Formats
- L5X - Rockwell Automation Studio 5000 Logix Designer
- PLCopen XML - IEC 61131-3 standard exchange format
- All 5 IEC 61131-3 languages supported:
- ST (Structured Text)
- IL (Instruction List)
- FBD (Function Block Diagram)
- LD (Ladder Diagram)
- SFC (Sequential Function Chart)
- All 5 IEC 61131-3 languages supported:
Features
- Unused Tags/Variables (S0001) - Detect tags that are defined but never referenced
- Undefined Tags (S0002) - Find tags referenced in code but not declared
- Empty Routines/POUs (S0003) - Identify routines with no logic
- Unused AOIs (S0004) - Detect AOIs that are never called
- Unused DataTypes (S0005) - Find user-defined types that are never used
- Cyclomatic Complexity (M0001) - Detect overly complex ST routines (>10)
- Deep Nesting (M0003) - Find deeply nested control structures (>5 levels)
- Statistics - View file metrics including complexity analysis
- Configurable - Customize detection via
plceye.toml
Installation
Usage
# Analyze a single file
# Analyze PLCopen XML file
# Analyze multiple files
# Use custom configuration
# Set minimum severity level
# Show file statistics (no rule detection)
# Generate default configuration
Configuration
Create a plceye.toml file to customize detection:
[]
# Minimum severity to report: "info", "warning", "error"
= "info"
[]
= true
# Ignore tags matching these patterns (glob-style)
= ["_*", "HMI_*"]
# Ignore tags in these scopes
= []
[]
= true
# Ignore undefined tags matching these patterns
= ["Local:*"]
[]
= true
= []
[]
= true
[]
= true
[]
= true
= 10
[]
= true
= 5
Output
=== project.L5X ===
[info] S0001: Controller - Tag 'Spare_01' is defined but never used (Spare_01)
[warning] S0002: Program:Main - Tag 'Unknown' is referenced but not defined (Unknown)
[info] M0001: Program:Main - Routine 'ComplexLogic' has cyclomatic complexity of 15 (max: 10) (ComplexLogic)
Found 3 issue(s) in 1 file(s).
Rule Codes
| Code | Name | Description | Default Severity |
|---|---|---|---|
| S0001 | unused-tag | Tag/variable defined but never referenced | info |
| S0002 | undefined-tag | Tag referenced but not defined | warning |
| S0003 | empty-block | Routine/POU with no executable logic | info |
| S0004 | unused-aoi | AOI defined but never called | info |
| S0005 | unused-datatype | User-defined type never used | info |
| M0001 | cyclomatic-complexity | ST routine complexity exceeds threshold | info |
| M0003 | deep-nesting | Control structure nesting too deep | info |
Library Usage
use ;
let project = from_file?;
let detector = new;
let report = detector.analyze?;
for rule in report.rules
// Get statistics
let stats = detector.get_stats?;
println!;
println!;
Disclaimer
This is an independent open-source project and is not affiliated with, endorsed by, or associated with Rockwell Automation, Inc.
"Rockwell Automation", "Allen-Bradley", "Studio 5000", and "Logix Designer" are trademarks of Rockwell Automation, Inc.
License
MIT License - see LICENSE for details.