Enforces Schneider Electric naming conventions across EcoStruxure Automation Expert applications...
Enforces Schneider Electric naming conventions across EcoStruxure Automation Expert applications with automated validation and actionable fix suggestions.
Critical Problem: Non-compliant naming reduces code readability, increases maintenance burden, and violates SE Application Design Guidelines. Manual review of naming across hundreds of artifacts is error-prone and time-consuming.
Solution: Automated validation engine that parses EAE XML files (.fbt, .cat, .dtp, .adp), applies 14+ SE naming rules, and reports violations with specific fix recommendations. Integrates with CI/CD pipelines via JSON output.
python scripts/validate_names.py --app-dir /path/to/eae/app
# With JSON output for CI/CD
python scripts/validate_names.py --app-dir /path/to/eae/app --output violations.json
# Only CATs
python scripts/validate_names.py --app-dir /path/to/eae/app --artifact-type CAT
# Only Basic Function Blocks
python scripts/validate_names.py --app-dir /path/to/eae/app --artifact-type BasicFB
Validating naming conventions in: /path/to/eae/app
Found 45 artifacts across 12 files
VIOLATIONS FOUND: 8
[ERROR] BasicFB "ScaleLogic" (scaleLogic.fbt:1)
Rule: Basic Function Blocks must use camelCase
Expected pattern: ^[a-z][a-zA-Z0-9]*$
Suggestion: Rename to "scaleLogic"
[WARNING] Variable "permit_on" (motorControl.fbt:23)
Rule: Interface variables must use PascalCase
Expected pattern: ^[A-Z][a-zA-Z0-9]*$
Suggestion: Rename to "PermitOn"
Summary: 3 ERRORS, 5 WARNINGS, 0 INFO
Compliance: 82% (37/45 artifacts compliant)
Exit code: 11 (errors found)
Use any of these phrases to invoke the skill:
| Artifact Type | Convention | Pattern | Example | Severity if Violated |
|---|---|---|---|---|
| CAT | PascalCase | ^[A-Z][a-zA-Z0-9]*$ |
AnalogInput | ERROR |
| SubApp | PascalCase | ^[A-Z][a-zA-Z0-9]*$ |
SeqManager | ERROR |
| Basic FB | camelCase | ^[a-z][a-zA-Z0-9]*$ |
scaleLogic | ERROR |
| Composite FB | camelCase | ^[a-z][a-zA-Z0-9]*$ |
stateDevice | ERROR |
| Function | camelCase | ^[a-z][a-zA-Z0-9]*$ |
calculateAverage | ERROR |
| Adapter | IPascalCase | ^I[A-Z][a-zA-Z0-9]*$ |
IAnalogValue | ERROR |
| Event | SNAKE_CASE | ^[A-Z_]+$ |
START_MOTOR | ERROR |
| Structure | strPascalCase | ^str[A-Z][a-zA-Z0-9]*$ |
strMotorData | ERROR |
| Alias | aPascalCase | ^a[A-Z][a-zA-Z0-9]*$ |
aFrame | WARNING |
| Enum | ePascalCase | ^e[A-Z][a-zA-Z0-9]*$ |
eProductType | ERROR |
| Array | arrPascalCase | ^arr[A-Z][a-zA-Z0-9]*$ |
arrRecipeBuffer | WARNING |
| Variable (I/O) | PascalCase | ^[A-Z][a-zA-Z0-9]*$ |
PermitOn | ERROR |
| Variable (Internal) | camelCase | ^[a-z][a-zA-Z0-9]*$ |
outMinActiveLast | WARNING |
| Folder | PascalCase | ^[A-Z][a-zA-Z0-9]*$ |
Motors | WARNING |
Special Cases:
INIT and INITO are always validThe validator scans the application directory for:
.fbt files (Function Block Types - Basic, Composite, Function).cat files (Composite Application Types).dtp files (Data Type definitions - Structure, Enum, Alias, Array).adp files (Adapter declarations)Each file is parsed to extract:
Name attribute)For each extracted name:
Violations include:
Human-Readable (default):
JSON (for CI/CD):
{
"success": false,
"errors": [
{
"artifact_type": "BasicFB",
"name": "ScaleLogic",
"file": "scaleLogic.fbt",
"line": 1,
"rule": "Basic Function Blocks must use camelCase",
"pattern": "^[a-z][a-zA-Z0-9]*$",
"suggestion": "scaleLogic",
"severity": "ERROR"
}
],
"warnings": [ ... ],
"details": {
"total_artifacts": 45,
"compliant": 37,
"compliance_percentage": 82.2
}
}
# Validate entire application
python scripts/validate_names.py --app-dir /path/to/eae/app
# Save violations to JSON file
python scripts/validate_names.py --app-dir /path/to/eae/app --output violations.json
# Only specific artifact types
python scripts/validate_names.py --app-dir /path/to/eae/app --artifact-type CAT
python scripts/validate_names.py --app-dir /path/to/eae/app --artifact-type BasicFB
# Only specific severity levels
python scripts/validate_names.py --app-dir /path/to/eae/app --min-severity ERROR
# Exclude specific files or folders
python scripts/validate_names.py --app-dir /path/to/eae/app --exclude "Legacy/*"
# Exit codes for automation
# 0 = all compliant
# 10 = warnings found (may proceed)
# 11 = errors found (should block)
# 1 = parsing failure
# Jenkins/GitHub Actions example
python scripts/validate_names.py --app-dir $APP_DIR --output report.json
EXIT_CODE=$?
if [ $EXIT_CODE -eq 11 ]; then
echo "Naming violations found - deployment blocked"
exit 1
elif [ $EXIT_CODE -eq 10 ]; then
echo "Naming warnings found - review recommended"
fi
Purpose: Main validation engine for SE naming conventions
Usage:
python scripts/validate_names.py --app-dir <path> [options]
Options:
--app-dir PATH Path to EAE application (required)
--output PATH JSON output file path (default: stdout)
--artifact-type TYPE Filter to specific type (CAT, BasicFB, CompositeFB, etc.)
--min-severity LEVEL Minimum severity to report (ERROR, WARNING, INFO)
--exclude PATTERN Exclude files matching glob pattern
--strict Treat all violations as ERRORS
--help Show full help
Exit Codes:
0: All artifacts compliant (or no violations of requested severity level)10: Warnings found (non-blocking violations)11: Errors found (blocking violations requiring fixes)1: Parsing failure or invalid argumentsOutput: JSON structure with ValidationResult pattern (success, errors, warnings, details)
Example:
# Validate with strict mode (all warnings become errors)
python scripts/validate_names.py --app-dir ./MyApp --strict
# Filter to only CATs and Basic FBs
python scripts/validate_names.py --app-dir ./MyApp --artifact-type CAT,BasicFB
# CI/CD integration with JSON output
python scripts/validate_names.py --app-dir $CI_WORKSPACE --output violations.json --min-severity ERROR
| Skill | Integration Point | Use Case |
|---|---|---|
| eae-cat | Validate names when creating CATs | Ensure new CATs follow PascalCase before generation |
| eae-basic-fb | Validate names when creating Basic FBs | Ensure FB and variables use correct case |
| eae-composite-fb | Validate FB instances | Check instance names match conventions |
| eae-adapter | Validate adapter interfaces | Ensure adapters use IPascalCase prefix |
| eae-datatype | Validate type declarations | Check struct/enum/array/alias prefixes |
| eae-performance-analyzer | Pre-validation step | Fix naming before performance analysis |
Workflow Example:
1. User: "Create a new CAT called analog_input"
2. eae-cat creates CAT scaffolding
3. eae-naming-validator checks name: VIOLATION (should be AnalogInput)
4. User: "Fix the naming violation"
5. eae-naming-validator suggests: "Rename to AnalogInput"
6. eae-cat renames CAT to AnalogInput
7. Validation passes
| Anti-Pattern | Why It Fails | Instead |
|---|---|---|
| Manual name reviews | Error-prone, inconsistent, time-consuming | Automated validation on every commit |
| Vague error messages | "Name is invalid" doesn't help users fix it | Include expected pattern + suggestion |
| Blocking legacy code | Old but functional apps shouldn't break builds | Use --min-severity ERROR for gradual adoption |
| Slow validation | Users won't run if it takes >30s | Optimize XML parsing, cache file reads |
| Ignoring context | Same name has different rules in different scopes | Detect variable scope (interface vs internal) |
| No CI/CD integration | Violations discovered too late | JSON output + exit codes for automation |
After running validation:
See references/naming-rules.md for the complete catalog of 14+ naming rules with:
The validator identifies artifact types from XML structure:
CAT (.cat files):
<CompositeFBType Name="AnalogInput">
<!-- Has attribute CompositeFBType or contains HMI elements -->
</CompositeFBType>
Basic FB (.fbt files):
<FBType Name="scaleLogic">
<ECC> <!-- Execution Control Chart indicates Basic FB -->
...
</ECC>
</FBType>
Composite FB (.fbt files):
<FBType Name="stateDevice">
<FBNetwork> <!-- FBNetwork indicates Composite FB -->
...
</FBNetwork>
</FBType>
Adapter (.adp files):
<AdapterType Name="IAnalogValue">
...
</AdapterType>
DataType (.dtp files):
<!-- Structure -->
<StructuredType Name="strMotorData">
...
</StructuredType>
<!-- Enum -->
<EnumeratedType Name="eProductType">
...
</EnumeratedType>
<!-- Array -->
<ArrayType Name="arrRecipeBuffer">
...
</ArrayType>
<!-- Alias -->
<DataType Name="aFrame" Comment="ALIAS">
...
</DataType>
Interface Variables (PascalCase):
<InterfaceList>
<EventInputs>
<Event Name="START" />
</EventInputs>
<InputVars>
<VarDeclaration Name="PermitOn" Type="BOOL" />
</InputVars>
</InterfaceList>
Internal Variables (camelCase):
<BasicFB>
<InternalVars>
<VarDeclaration Name="outMinActiveLast" Type="BOOL" />
</InternalVars>
</BasicFB>
| Violation | Detection | Suggested Fix |
|---|---|---|
| Wrong case | Matches pattern after case conversion | Convert to correct case |
| Missing prefix | Name would match with prefix added | Add required prefix |
| Extra characters | Name has underscores/hyphens where not allowed | Remove/convert to camelCase |
| Reserved conflict | Uses reserved keyword incorrectly | Append suffix or suggest synonym |
Example Transformations:
# PascalCase → camelCase
"ScaleLogic" → "scaleLogic"
# camelCase → PascalCase
"permitOn" → "PermitOn"
# snake_case → PascalCase
"permit_on" → "PermitOn"
# Missing prefix (Adapter)
"AnalogValue" → "IAnalogValue"
# Missing prefix (Structure)
"MotorData" → "strMotorData"
# Wrong case for Event
"start_motor" → "START_MOTOR"
Limitations:
# Dry-run (show what would be fixed)
python scripts/validate_names.py --app-dir ./MyApp --auto-fix --dry-run
# Apply fixes automatically
python scripts/validate_names.py --app-dir ./MyApp --auto-fix
# Apply only specific fixes
python scripts/validate_names.py --app-dir ./MyApp --auto-fix --only "BasicFB,Variable"
Safety Checks: