eae-cat
npx skills add https://github.com/sapiencezk/eae-skills --skill eae-cat
Agent 安装分布
Skill 文档
EAE CAT Block Creation
Create and register CAT (Composite Application Type) blocks – the most common block type in EAE.
CAT = Enhanced Composite FB with:
- HMI visualization (symbols)
- OPC-UA server interface
- Persistence (offline parameters)
This skill handles:
- Creating new CAT blocks from scratch
- Registering CAT blocks in dfbproj (including forked blocks from eae-fork)
- Generating HMI symbol files
- Validating CAT registration
Tip: Need standard blocks like E_CYCLE, E_DELAY, or MQTT inside your CAT? Use
/eae-runtime-baseto find the right Runtime.Base block.
Quick Start
User: Create a CAT block called MotorController in MyLibrary namespace
Claude: [Creates IEC61499/MotorController/ folder with all files]
Triggers
/eae-cat/eae-cat --register-only– Register existing CAT block (used by eae-fork orchestration)- “create CAT block”
- “create block with HMI”
- “create CAT with visualization”
Register-Only Mode (for eae-fork Orchestration)
When called with --register-only, this skill skips file creation and only performs project registration. This mode is used by eae-fork to complete the fork workflow after file transformation.
/eae-cat --register-only {BlockName} {Namespace}
What –register-only does:
- Registers in dfbproj – Adds ItemGroup entries for CAT block visibility
- Registers in csproj – Adds HMI file entries to HMI project
- Updates Folders.xml – Adds folder entries for library browser
- Validates – Confirms block is properly registered
What –register-only does NOT do:
- Create IEC61499 files (.fbt, .cfg, etc.) – already done by eae-fork
- Create HMI files (.def.cs, .cnv.cs, etc.) – already done by eae-fork
- Update namespaces – already done by eae-fork
Usage by eae-fork
eae-fork detects CAT type â calls /eae-cat --register-only
â
âââ python ../eae-skill-router/scripts/register_dfbproj.py {Block} {Lib} --type cat
â
âââ Validates registration complete
Manual Usage
If you need to manually register a CAT block (e.g., after manual file copy):
# Register a forked CAT block
python ../eae-skill-router/scripts/register_dfbproj.py AnalogInput SE.ScadapackWWW --type cat
# Verify registration
python ../eae-skill-router/scripts/register_dfbproj.py AnalogInput SE.ScadapackWWW --type cat --verify
# Dry run (see what would be added)
python ../eae-skill-router/scripts/register_dfbproj.py AnalogInput SE.ScadapackWWW --type cat --dry-run
Files Generated
A CAT block creates 15+ files in two locations:
IEC61499/{CATName}/
| File | Purpose |
|---|---|
{Name}.cfg |
CAT configuration (links all files) |
{Name}.fbt |
Main composite FB |
{Name}.doc.xml |
Documentation |
{Name}.meta.xml |
Metadata |
{Name}_CAT.offline.xml |
Offline parameter config |
{Name}_CAT.opcua.xml |
OPC-UA server config |
{Name}_HMI.fbt |
Service interface FB |
{Name}_HMI.doc.xml |
HMI documentation |
{Name}_HMI.meta.xml |
HMI metadata |
{Name}_HMI.offline.xml |
HMI offline config |
{Name}_HMI.opcua.xml |
HMI OPC-UA config |
HMI/{CATName}/
| File | Purpose |
|---|---|
{Name}.def.cs |
Symbol definitions |
{Name}.event.cs |
Event definitions |
{Name}.Design.resx |
Design resources |
{Name}_sDefault.cnv.cs |
Default symbol |
{Name}_sDefault.cnv.Designer.cs |
Symbol designer |
{Name}_sDefault.cnv.resx |
Symbol resources |
{Name}_sDefault.cnv.xml |
Symbol mapping |
{Name}_sDefault.doc.xml |
Symbol documentation |
Workflow
- Create folder
IEC61499/{CATName}/ - Generate GUIDs for CAT FB and HMI FB
- Create .cfg file (links everything)
- Create .fbt file (Composite FB with
Format="2.0") - Create _HMI.fbt (Service interface)
- Create supporting files (.doc.xml, .meta.xml, .offline.xml, .opcua.xml)
- Create HMI folder
HMI/{CATName}/ - Create symbol files (.def.cs, .event.cs, .cnv.* files)
- Register in .dfbproj
CAT Configuration File (.cfg)
The .cfg file links all CAT components:
<?xml version="1.0" encoding="utf-8"?>
<CAT xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Name="{CATName}"
CATFile="{CATName}\{CATName}.fbt"
SymbolDefFile="..\HMI\{CATName}\{CATName}.def.cs"
SymbolEventFile="..\HMI\{CATName}\{CATName}.event.cs"
DesignFile="..\HMI\{CATName}\{CATName}.Design.resx"
xmlns="http://www.nxtcontrol.com/IEC61499.xsd">
<HMIInterface Name="IThis" FileName="{CATName}\{CATName}_HMI.fbt">
<Symbol Name="sDefault" FileName="..\HMI\{CATName}\{CATName}_sDefault.cnv.cs">
<DependentFiles>..\HMI\{CATName}\{CATName}_sDefault.cnv.Designer.cs</DependentFiles>
<DependentFiles>..\HMI\{CATName}\{CATName}_sDefault.cnv.resx</DependentFiles>
<DependentFiles>..\HMI\{CATName}\{CATName}_sDefault.cnv.xml</DependentFiles>
</Symbol>
<MetaFile>{CATName}\{CATName}_HMI.meta.xml</MetaFile>
</HMIInterface>
<Plugin Name="Plugin=OfflineParametrizationEditor;IEC61499Type=CAT_OFFLINE;$ItemType$=Content"
Project="{Project}" Value="{CATName}\{CATName}_CAT.offline.xml" />
<Plugin Name="Plugin=OPCUAConfigurator;IEC61499Type=CAT_OPCUA;$ItemType$=Content"
Project="{Project}" Value="{CATName}\{CATName}_CAT.opcua.xml" />
<HWConfiguration xsi:nil="true" />
</CAT>
Note: CAT .cfg files DO use xmlns – this is correct (unlike .fbt files).
CAT FB Template (.fbt)
Same as Composite FB but with HMI.Alias attribute:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE FBType SYSTEM "../LibraryElement.dtd">
<FBType Name="{CATName}" Namespace="{YourNamespace}" Format="2.0"
GUID="{NEW-GUID}" Comment="CAT Function Block">
<Attribute Name="HMI.Alias" Value="" />
<Identification Standard="61499-2" />
<VersionInfo Organization="{Org}" Version="0.0" Author="{Author}"
Date="{MM/DD/YYYY}" Remarks="Initial version" />
<CompilerInfo />
<InterfaceList>
<!-- Events and Variables -->
</InterfaceList>
<FBNetwork>
<!-- FB instances and connections -->
</FBNetwork>
</FBType>
HMI Service FB Template (_HMI.fbt)
The HMI service interface defines what data is exposed to visualization:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE FBType SYSTEM "../LibraryElement.dtd">
<FBType GUID="{NEW-GUID}" Name="{CATName}_HMI" Namespace="{YourNamespace}">
<InterfaceList>
<EventInputs>
<Event ID="{HEX-ID}" Name="INIT">
<With Var="QI" />
</Event>
<Event ID="{HEX-ID}" Name="UPD">
<With Var="Value" />
<With Var="Status" />
</Event>
</EventInputs>
<EventOutputs>
<Event ID="{HEX-ID}" Name="INITO">
<With Var="QO" />
<With Var="STATUS" />
</Event>
</EventOutputs>
<InputVars>
<VarDeclaration ID="{HEX-ID}" Name="QI" Type="BOOL" />
<VarDeclaration ID="{HEX-ID}" Name="Value" Type="REAL" />
<VarDeclaration ID="{HEX-ID}" Name="Status" Type="Status" Namespace="SE.App2Base" />
</InputVars>
<OutputVars>
<VarDeclaration ID="{HEX-ID}" Name="QO" Type="BOOL" />
<VarDeclaration ID="{HEX-ID}" Name="STATUS" Type="STRING" />
</OutputVars>
</InterfaceList>
<Service RightInterface="" LeftInterface="">
<ServiceSequence Name="" />
</Service>
</FBType>
SubCAT References
If your CAT contains other CAT blocks internally, add SubCAT references:
<SubCAT Name="{instanceName}" Type="{SubCATType}" Namespace="{Namespace}" UsedInCAT="true" />
dfbproj Registration
CAT blocks have complex registration:
<!-- CAT configuration and supporting files -->
<ItemGroup>
<None Include="{Name}\{Name}.cfg">
<DependentUpon>{Name}.fbt</DependentUpon>
<IEC61499Type>CAT</IEC61499Type>
</None>
<None Include="{Name}\{Name}_CAT.offline.xml">
<DependentUpon>{Name}.fbt</DependentUpon>
<Plugin>OfflineParametrizationEditor</Plugin>
<IEC61499Type>CAT_OFFLINE</IEC61499Type>
</None>
<None Include="{Name}\{Name}_CAT.opcua.xml">
<DependentUpon>{Name}.fbt</DependentUpon>
<Plugin>OPCUAConfigurator</Plugin>
<IEC61499Type>CAT_OPCUA</IEC61499Type>
</None>
<None Include="{Name}\{Name}_HMI.offline.xml">
<DependentUpon>{Name}_HMI.fbt</DependentUpon>
<Plugin>OfflineParametrizationEditor</Plugin>
<IEC61499Type>CAT_OFFLINE</IEC61499Type>
</None>
<None Include="{Name}\{Name}_HMI.opcua.xml">
<DependentUpon>{Name}_HMI.fbt</DependentUpon>
<Plugin>OPCUAConfigurator</Plugin>
<IEC61499Type>CAT_OPCUA</IEC61499Type>
</None>
<!-- .doc.xml and .meta.xml files... -->
</ItemGroup>
<!-- Main CAT FB -->
<ItemGroup>
<Compile Include="{Name}\{Name}.fbt">
<IEC61499Type>CAT</IEC61499Type>
</Compile>
<Compile Include="{Name}\{Name}_HMI.fbt">
<IEC61499Type>CAT</IEC61499Type>
<Usage>Private</Usage>
<DependentUpon>{Name}.fbt</DependentUpon>
<HMI>..\HMI\{Name}\{Name}_sDefault.cnv.cs</HMI>
</Compile>
</ItemGroup>
FBNetwork Layout
Follow the same layout guidelines as Composite FB. See eae-composite-fb.
Common Runtime.Base Blocks for CATs
CAT blocks often use standard Runtime.Base blocks internally. Use /eae-runtime-base for full documentation.
Frequently Used in CATs
| Block | Purpose | Typical Use in CAT |
|---|---|---|
E_CYCLE |
Periodic update | Update HMI values periodically |
E_DELAY |
Timed actions | Debounce, timeout handling |
E_REND |
Synchronize | Wait for multiple init completions |
E_SWITCH |
Conditional routing | Route based on mode/state |
PERSISTENCE |
Save values | Store parameters offline |
LOGGER |
Diagnostics | Log CAT events |
Example: CAT with Periodic HMI Update
<FBNetwork>
<!-- Timer for periodic HMI updates -->
<FB ID="1" Name="updateTimer" Type="E_CYCLE" Namespace="Runtime.Base" x="500" y="350" />
<!-- Your logic blocks -->
<FB ID="2" Name="logic" Type="MyLogicFB" Namespace="MyLib" x="1100" y="350" />
<EventConnections>
<Connection Source="$INIT" Destination="$1.START" />
<Connection Source="$1.EO" Destination="$2.REQ" />
</EventConnections>
<DataConnections>
<Connection Source="T#500ms" Destination="$1.DT" />
</DataConnections>
</FBNetwork>
For the complete catalog of ~100 Runtime.Base blocks, see
/eae-runtime-base.
Common Rules
See common-rules.md for:
- ID generation
- DOCTYPE references
- dfbproj registration patterns
Troubleshooting
| Issue | Solution |
|---|---|
| CAT won’t load | Ensure all files in {Name}/ subfolder |
| HMI not visible | Check .cfg HMIInterface paths |
| SubCAT missing | Add SubCAT reference in .cfg |
| Symbols not working | Verify HMI/ folder structure |
Scripts
This skill includes Python scripts for autonomous validation and operation:
| Script | Purpose | Usage | Exit Codes |
|---|---|---|---|
validate_cat.py |
Verify all 15+ CAT files are consistent | python scripts/validate_cat.py <IEC61499/CATName> |
0=pass, 1=error, 10=validation failed, 11=pass with warnings |
validate_hmi.py |
Check HMI file structure | python scripts/validate_hmi.py <HMI/CATName> |
0=pass, 1=error, 10=validation failed, 11=pass with warnings |
Validation Workflow
Recommended: Validate automatically after creating or modifying a CAT block:
# Validate CAT block (all 15+ files, namespaces, .cfg file)
python scripts/validate_cat.py path/to/IEC61499/MyCATBlock
# Validate HMI files (C# structure, conventions)
python scripts/validate_hmi.py path/to/HMI/MyCATBlock
# Generic validation (basic XML structure)
python ../eae-skill-router/scripts/validate_block.py --type cat path/to/IEC61499/MyCATBlock/
Example: validate_cat.py
# Basic validation
python scripts/validate_cat.py IEC61499/MyCATBlock
# Validate with expected namespace
python scripts/validate_cat.py IEC61499/MyCATBlock --namespace MyLibrary
# Verbose output with file details
python scripts/validate_cat.py IEC61499/MyCATBlock --verbose
# JSON output for automation/CI
python scripts/validate_cat.py IEC61499/MyCATBlock --json
# CI mode (JSON only, no human messages)
python scripts/validate_cat.py IEC61499/MyCATBlock --ci
What validate_cat.py checks:
- â All required IEC61499 files exist (11 files: .cfg, .fbt, _HMI.fbt, .offline.xml, .opcua.xml, etc.)
- â All required HMI files exist (8+ files: .def.cs, .event.cs, .cnv.*, etc.)
- â .cfg file references correct paths (CATFile, HMIFile, SymbolDefFile)
- â .cfg Name attribute matches directory name
- â Namespaces are consistent across .fbt files
- â ï¸ Missing recommended HMI files (warnings)
CAT Block File Checklist:
IEC61499/{CATName}/ (11 files):
- â
{Name}.cfg– CAT configuration - â
{Name}.fbt– Main composite FB - â
{Name}.doc.xml,{Name}.meta.xml - â
{Name}_CAT.offline.xml,{Name}_CAT.opcua.xml - â
{Name}_HMI.fbt– Service interface FB - â
{Name}_HMI.doc.xml,{Name}_HMI.meta.xml - â
{Name}_HMI.offline.xml,{Name}_HMI.opcua.xml
HMI/{CATName}/ (8+ files):
- â
{Name}.def.cs– Symbol definitions - â
{Name}.event.cs– Event definitions - â
{Name}.Design.resx– Design resources - â
{Name}_sDefault.cnv.cs– Default symbol - â
{Name}_sDefault.cnv.Designer.cs– Symbol designer - â
{Name}_sDefault.cnv.resx– Symbol resources - â
{Name}_sDefault.cnv.xml– Symbol mapping - â
{Name}_sDefault.doc.xml– Symbol documentation
Example: validate_hmi.py
# Validate HMI files
python scripts/validate_hmi.py HMI/MyCATBlock --verbose
What validate_hmi.py checks:
- â .def.cs contains symbol definition class
- â .def.cs inherits from SymbolDefinition
- â .event.cs contains event definitions
- â .event.cs uses partial class pattern
- â Converter files (.cnv.*) are present
- â Converter inherits from UserControl
- â ï¸ File structure warnings (missing namespaces, empty files)
Note: Full C# compilation is performed by the EAE IDE. These scripts catch common structural issues early to save compilation cycles.
Generate IDs
CAT blocks need 2 GUIDs (CAT FB + HMI FB) plus hex IDs for events/vars:
python ../eae-skill-router/scripts/generate_ids.py --guid 2 --hex 10
Templates
Integration with Validation Skills
Naming Validation
Use eae-naming-validator to ensure compliance with SE Application Design Guidelines:
Key Naming Rules for CAT:
- CAT name: PascalCase (e.g.,
AnalogInput,MotorController) - Interface variables (inputs/outputs): PascalCase (e.g.,
PermitOn,FeedbackOn) - Internal variables: camelCase (e.g.,
error,outMinActiveLast) - Events: SNAKE_CASE (e.g.,
START_MOTOR,STOP_PROCESS) - Adapters (if used): IPascalCase (e.g.,
IMotorControl)
Validate naming before creation:
# Validate CAT and variable names
python ../eae-naming-validator/scripts/validate_names.py \
--app-dir IEC61499/MyLibrary \
--json
Performance Analysis
Use eae-performance-analyzer to prevent event storms in CAT FBNetworks:
# Analyze event flow in CAT block
python ../eae-performance-analyzer/scripts/analyze_event_flow.py \
--app-dir IEC61499/MyLibrary
# Check for anti-patterns
python ../eae-performance-analyzer/scripts/detect_storm_patterns.py \
--app-dir IEC61499/MyLibrary
What to Check:
- Event multiplication factor <10x
- No tight event loops (cycles â¤2 hops)
- HMI update frequency (E_CYCLE DT â¥100ms)
- I/O event connections <30 downstream
Best Practices from EAE ADG
1. Naming Conventions (SE ADG Section 1.5)
CAT Naming:
- Use PascalCase:
MotorController,SpMon,OosMode - Single word preferred for folders:
Motors,Valves - Avoid abbreviations unless industry-standard (PID, HMI, OPC)
Variable Naming:
- Interface variables: PascalCase â
PermitOn,FeedbackOn - Internal variables: camelCase â
error,timerActive - Data types: Hungarian notation â
strMotorData,arrRecipeBuffer
Event Naming:
- Use SNAKE_CASE:
START_MOTOR,STOP_PROCESS - Use INIT/INITO for initialization
Reference: EAE_ADG EIO0000004686.06, Section 1.5
2. FBNetwork Layout
Grid Guidelines:
- X-axis: 500, 1100, 1700, 2300, 2900 (600px spacing)
- Y-axis: 350, 800, 1250, 1700, 2150 (450px spacing)
- Top-to-bottom data flow
- Left-to-right event flow
3. HMI Interface Design
Service FB (_HMI.fbt) Guidelines:
- Keep interface minimal (expose only necessary data)
- Use periodic updates (E_CYCLE 500ms typical, 100ms minimum)
- Use SE.App2Base.Status for standardized status reporting
- Include QI/QO pattern for init handshake
HMI Update Pattern:
<FBNetwork>
<FB ID="1" Name="hmiUpdate" Type="E_CYCLE" Namespace="Runtime.Base" x="500" y="350" />
<EventConnections>
<Connection Source="$INIT" Destination="$1.START" />
<Connection Source="$1.EO" Destination="$HMI.UPD" />
</EventConnections>
<DataConnections>
<Connection Source="T#500ms" Destination="$1.DT" />
</DataConnections>
</FBNetwork>
Anti-Patterns
1. Event Storm Anti-Patterns
â TIGHT_EVENT_LOOP
<!-- BAD: FB1 -> FB2 -> FB1 creates 2-hop loop -->
<EventConnections>
<Connection Source="$1.CNF" Destination="$2.REQ" />
<Connection Source="$2.CNF" Destination="$1.REQ" />
</EventConnections>
â FIX: Add state guard with RS flip-flop
â HIGH_FREQUENCY_TIMER
<!-- BAD: 10ms E_CYCLE causes 100 events/sec -->
<DataConnections>
<Connection Source="T#10ms" Destination="$1.DT" />
</DataConnections>
â FIX: Use appropriate interval (500ms for HMI, 100ms minimum)
2. Naming Anti-Patterns
â Inconsistent Casing
<VarDeclaration Name="PermitOn" Type="BOOL" />
<VarDeclaration Name="Error" Type="BOOL" /> <!-- BAD: should be "error" if internal -->
â Generic Event Names
<Event Name="DO1" /> <!-- BAD: non-descriptive -->
â Descriptive Event Names
<Event Name="START_MOTOR" />
<Event Name="UPDATE_HMI" />
3. Structure Anti-Patterns
â Missing .cfg File
IEC61499/MyCATBlock/
MyCATBlock.fbt â
MyCATBlock_HMI.fbt â
MyCATBlock.cfg â MISSING - CAT won't load!
â Wrong .cfg Paths
<!-- BAD: Absolute paths -->
<CAT CATFile="C:\Projects\IEC61499\MyCAT\MyCAT.fbt" ... />
â Relative Paths
<CAT CATFile="MyCAT\MyCAT.fbt"
SymbolDefFile="..\HMI\MyCAT\MyCAT.def.cs" ... />
4. HMI Anti-Patterns
â Too Many HMI Variables (50+ variables exposed)
â Minimal HMI Interface (5-15 variables, use structured types)
â Direct I/O in HMI Service (_HMI.fbt should contain only <Service>, no <FBNetwork>)
Verification Checklist
Before committing your CAT block:
Structure:
- All 11 IEC61499 files present in
{Name}/subfolder - All 8+ HMI files present in
HMI/{Name}/subfolder - .cfg file exists with correct relative paths
- Registered in .dfbproj with correct IEC61499Type tags
Naming (run eae-naming-validator):
- CAT name is PascalCase
- Interface variables are PascalCase
- Internal variables are camelCase
- Events are SNAKE_CASE
Performance (run eae-performance-analyzer):
- Event multiplication factor <10x
- No tight event loops (â¤2 hops)
- E_CYCLE timers â¥100ms (unless justified)
- I/O event connections <30 downstream
Scripts Validation:
-
python scripts/validate_cat.py IEC61499/{Name}exits with 0 -
python scripts/validate_hmi.py HMI/{Name}exits with 0
Manual Checks:
- HMI interface has 5-15 variables (not 50+)
- _HMI.fbt contains
<Service>only - .cfg paths are relative
- SubCAT references added (if using nested CATs)
Registering Forked Blocks
When eae-fork copies a block from a source library, it handles file transformation (copy, namespace update, reference update). This skill (eae-cat) completes the process by:
- Registering in dfbproj – Makes block visible in EAE library browser
- Creating HMI files – Symbol implementations (.cnv.cs, .cnv.Designer.cs, .cnv.resx, .cnv.xml)
- Validating registration – Ensures block loads correctly
Workflow: After eae-fork
eae-fork completes â eae-cat registers
â â
â Steps 1-4: â Steps 5-7:
â ⢠Copy files â ⢠Generate HMI files
â ⢠Update namespace â ⢠Register in dfbproj
â ⢠Update refs â ⢠Validate registration
â ⢠Update .cfg â
â¼ â¼
Files in IEC61499/ Block visible in EAE
Registration Command
# After forking AnalogInput to SE.ScadapackWWW:
python ../eae-skill-router/scripts/register_dfbproj.py AnalogInput SE.ScadapackWWW --type cat
# Output:
# [OK] Successfully registered CAT block 'AnalogInput' in dfbproj
# Entries:
# + AnalogInput\AnalogInput.fbt (Compile/CAT)
# + AnalogInput\AnalogInput_HMI.fbt (Compile/CAT)
# + AnalogInput\AnalogInput.cfg (None/CAT)
# + AnalogInput\AnalogInput_CAT.offline.xml (None/CAT_OFFLINE)
# + AnalogInput\AnalogInput_CAT.opcua.xml (None/CAT_OPCUA)
# + AnalogInput\AnalogInput_CAT.aspmap.xml (None/CAT_ASPMAP)
Related Skills
| Skill | When to Use |
|---|---|
| eae-fork | Fork blocks from SE libraries (calls eae-cat after for CAT blocks) |
| eae-naming-validator | Validate naming compliance with SE ADG |
| eae-performance-analyzer | Prevent event storms in FBNetwork |
| eae-runtime-base | Find standard blocks (E_CYCLE, E_DELAY, MQTT, etc.) |
| eae-se-process | Find SE process blocks (motors, valves, PID, signals) |
| eae-composite-fb | Simple composite without HMI |
| eae-basic-fb | Create custom logic blocks |
| eae-datatype | Create custom data types |