eae-basic-fb
npx skills add https://github.com/sapiencezk/eae-skills --skill eae-basic-fb
Agent 安装分布
Skill 文档
EAE Basic Function Block Creation
Create or modify Basic FBs with state machine logic (ECC) and Structured Text algorithms.
CRITICAL RULE: ALWAYS use this skill for ANY operation on Basic FB files.
- Creating new Basic FBs
- Modifying existing Basic FBs (adding events, variables, states, algorithms)
- NEVER directly edit
.fbtfiles outside of this skill
Basic FB = State Machine + Algorithms
- ECC (Execution Control Chart) for state transitions
- Algorithms in ST (Structured Text) for computation
- No internal FBNetwork (unlike Composite)
Quick Start
User: Create a Basic FB called Calculator in MyLibrary that multiplies two REALs
Claude: [Creates .fbt with ECC + REQ algorithm: Result := Value1 * Value2]
Triggers
/eae-basic-fb/eae-basic-fb --register-only– Register existing Basic FB (used by eae-fork orchestration)- “create basic FB”
- “modify basic FB”
- “add event to basic FB”
- “add variable to basic FB”
- “create block with algorithm”
- “create state machine FB”
Register-Only Mode (for eae-fork Orchestration)
When called with --register-only, this skill skips file creation and only performs dfbproj registration. This mode is used by eae-fork to complete the fork workflow after file transformation.
/eae-basic-fb --register-only {BlockName} {Namespace}
What –register-only does:
- Registers in dfbproj – Adds ItemGroup entries for Basic FB visibility
What –register-only does NOT do:
- Create IEC61499 files (.fbt, etc.) – already done by eae-fork
- Update namespaces – already done by eae-fork
Usage
# Register a forked Basic FB
python ../eae-skill-router/scripts/register_dfbproj.py MyBasicFB SE.ScadapackWWW --type basic
# Verify registration
python ../eae-skill-router/scripts/register_dfbproj.py MyBasicFB SE.ScadapackWWW --type basic --verify
Modification Workflow
When modifying an existing Basic FB:
- Read the existing
.fbtfile to understand current structure - Identify what needs to be added/changed
- Generate new hex IDs for any new Events or VarDeclarations
- Update the
.fbtfile with the changes - Update event-variable associations (
<With Var="...">) if needed - Add new ECC states/transitions if adding new events
- Add/update algorithms if needed
Files Generated
| File | Purpose |
|---|---|
{Name}.fbt |
Main block with ECC + algorithms |
{Name}.doc.xml |
Documentation |
{Name}.meta.xml |
Metadata |
Location: IEC61499/
Workflow
- Generate GUID for FBType
- Generate hex IDs for each Event and VarDeclaration
- Create
.fbtwith:<!DOCTYPE FBType SYSTEM "../LibraryElement.dtd"><Identification Standard="61499-2" />- Standard events (INIT/REQ/INITO/CNF)
- ECC with START, INIT, REQ states
- Algorithms in ST
- Create
.doc.xmland.meta.xml - Register in
.dfbproj
Basic FB Template
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE FBType SYSTEM "../LibraryElement.dtd">
<FBType Name="{BlockName}" Namespace="{YourNamespace}"
GUID="{NEW-GUID}" Comment="{Description}">
<Identification Standard="61499-2" />
<VersionInfo Organization="{Org}" Version="0.0" Author="{Author}"
Date="{MM/DD/YYYY}" Remarks="Initial version" />
<CompilerInfo />
<InterfaceList>
<EventInputs>
<Event ID="{HEX-ID}" Name="INIT" Comment="Initialization Request">
<With Var="QI" />
</Event>
<Event ID="{HEX-ID}" Name="REQ" Comment="Normal Execution Request">
<With Var="QI" />
<!-- Add With Var for each input used in REQ -->
</Event>
</EventInputs>
<EventOutputs>
<Event ID="{HEX-ID}" Name="INITO" Comment="Initialization Confirm">
<With Var="QO" />
</Event>
<Event ID="{HEX-ID}" Name="CNF" Comment="Execution Confirmation">
<With Var="QO" />
<!-- Add With Var for each output produced -->
</Event>
</EventOutputs>
<InputVars>
<VarDeclaration ID="{HEX-ID}" Name="QI" Type="BOOL"
Comment="Input event qualifier" />
<!-- Add custom inputs here -->
</InputVars>
<OutputVars>
<VarDeclaration ID="{HEX-ID}" Name="QO" Type="BOOL"
Comment="Output event qualifier" />
<!-- Add custom outputs here -->
</OutputVars>
</InterfaceList>
<BasicFB>
<ECC>
<ECState Name="START" Comment="Initial State" x="552.9412" y="429.4117" />
<ECState Name="INIT" Comment="Initialization" x="923.5294" y="141.1765">
<ECAction Algorithm="INIT" Output="INITO" />
</ECState>
<ECState Name="REQ" Comment="Normal execution" x="217.647" y="752.9412">
<ECAction Algorithm="REQ" Output="CNF" />
</ECState>
<ECTransition Source="START" Destination="INIT" Condition="INIT"
x="923.5294" y="429.4117" />
<ECTransition Source="INIT" Destination="START" Condition="1"
x="552.9412" y="141.1765" />
<ECTransition Source="START" Destination="REQ" Condition="REQ"
x="552.9412" y="600.0" />
<ECTransition Source="REQ" Destination="START" Condition="1"
x="217.647" y="429.4117" />
</ECC>
<Algorithm Name="INIT" Comment="Initialization algorithm">
<ST><![CDATA[QO := QI;]]></ST>
</Algorithm>
<Algorithm Name="REQ" Comment="Normally executed algorithm">
<ST><![CDATA[QO := QI;
(* Add your logic here *)]]></ST>
</Algorithm>
</BasicFB>
</FBType>
Note: Basic FB does NOT have Format="2.0" attribute.
ECC (Execution Control Chart)
The ECC defines the state machine:
Standard States
| State | Purpose | Actions |
|---|---|---|
| START | Initial state | None |
| INIT | Initialization | Run INIT algorithm, fire INITO |
| REQ | Normal execution | Run REQ algorithm, fire CNF |
Standard Transitions
| From | To | Condition |
|---|---|---|
| START | INIT | INIT event received |
| INIT | START | 1 (unconditional) |
| START | REQ | REQ event received |
| REQ | START | 1 (unconditional) |
Adding Custom States
<ECState Name="CUSTOM_STATE" Comment="Custom state" x="800" y="500">
<ECAction Algorithm="CUSTOM_ALG" Output="CUSTOM_EVENT" />
</ECState>
<ECTransition Source="START" Destination="CUSTOM_STATE"
Condition="CUSTOM_INPUT_EVENT" x="700" y="450" />
Algorithms (Structured Text)
Algorithms are written in ST (Structured Text):
<Algorithm Name="REQ" Comment="Calculation algorithm">
<ST><![CDATA[
QO := QI;
Result := Value1 * Value2;
]]></ST>
</Algorithm>
ST Syntax Basics
(* Assignment *)
Result := Value1 + Value2;
(* Conditional *)
IF Condition THEN
Output := TRUE;
ELSE
Output := FALSE;
END_IF;
(* Loop *)
FOR i := 0 TO 10 DO
Array[i] := 0;
END_FOR;
Event-Variable Associations
Use <With Var="..."> to associate variables with events:
<Event Name="REQ" Comment="Request">
<With Var="QI" /> <!-- Always include QI -->
<With Var="Value1" /> <!-- Input used in REQ -->
<With Var="Value2" /> <!-- Input used in REQ -->
</Event>
<Event Name="CNF" Comment="Confirm">
<With Var="QO" /> <!-- Always include QO -->
<With Var="Result" /> <!-- Output produced by REQ -->
</Event>
dfbproj Registration
<ItemGroup>
<None Include="{Name}.doc.xml">
<DependentUpon>{Name}.fbt</DependentUpon>
</None>
<None Include="{Name}.meta.xml">
<DependentUpon>{Name}.fbt</DependentUpon>
</None>
</ItemGroup>
<ItemGroup>
<Compile Include="{Name}.fbt">
<IEC61499Type>Basic</IEC61499Type>
</Compile>
</ItemGroup>
Common Rules
See common-rules.md for:
- ID generation
- DOCTYPE references
- dfbproj registration patterns
Example: Multiplier Block
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE FBType SYSTEM "../LibraryElement.dtd">
<FBType Name="Multiplier" Namespace="MyLibrary"
GUID="a1b2c3d4-e5f6-7890-abcd-ef1234567890" Comment="Multiplies two values">
<Identification Standard="61499-2" />
<VersionInfo Organization="MyOrg" Version="1.0" Author="Claude"
Date="01/16/2026" Remarks="Initial" />
<CompilerInfo />
<InterfaceList>
<EventInputs>
<Event ID="1234567890ABCDEF" Name="INIT" Comment="Initialize">
<With Var="QI" />
</Event>
<Event ID="ABCDEF1234567890" Name="REQ" Comment="Calculate">
<With Var="QI" />
<With Var="Value1" />
<With Var="Value2" />
</Event>
</EventInputs>
<EventOutputs>
<Event ID="FEDCBA0987654321" Name="INITO" Comment="Init done">
<With Var="QO" />
</Event>
<Event ID="0987654321FEDCBA" Name="CNF" Comment="Result ready">
<With Var="QO" />
<With Var="Result" />
</Event>
</EventOutputs>
<InputVars>
<VarDeclaration ID="1111111111111111" Name="QI" Type="BOOL" />
<VarDeclaration ID="2222222222222222" Name="Value1" Type="REAL" />
<VarDeclaration ID="3333333333333333" Name="Value2" Type="REAL" />
</InputVars>
<OutputVars>
<VarDeclaration ID="4444444444444444" Name="QO" Type="BOOL" />
<VarDeclaration ID="5555555555555555" Name="Result" Type="REAL" />
</OutputVars>
</InterfaceList>
<BasicFB>
<ECC>
<ECState Name="START" x="550" y="430" />
<ECState Name="INIT" x="920" y="140">
<ECAction Algorithm="INIT" Output="INITO" />
</ECState>
<ECState Name="REQ" x="220" y="750">
<ECAction Algorithm="REQ" Output="CNF" />
</ECState>
<ECTransition Source="START" Destination="INIT" Condition="INIT" x="920" y="430" />
<ECTransition Source="INIT" Destination="START" Condition="1" x="550" y="140" />
<ECTransition Source="START" Destination="REQ" Condition="REQ" x="550" y="600" />
<ECTransition Source="REQ" Destination="START" Condition="1" x="220" y="430" />
</ECC>
<Algorithm Name="INIT">
<ST><![CDATA[QO := QI;]]></ST>
</Algorithm>
<Algorithm Name="REQ">
<ST><![CDATA[QO := QI;
Result := Value1 * Value2;]]></ST>
</Algorithm>
</BasicFB>
</FBType>
Scripts
This skill includes Python scripts for autonomous validation and operation:
| Script | Purpose | Usage | Exit Codes |
|---|---|---|---|
validate_ecc.py |
Verify ECC state machine correctness | python scripts/validate_ecc.py <file.fbt> |
0=pass, 1=error, 10=validation failed, 11=pass with warnings |
validate_st_algorithm.py |
Check ST algorithm consistency (basic checks) | python scripts/validate_st_algorithm.py <file.fbt> |
0=pass, 1=error, 10=validation failed, 11=pass with warnings |
Validation Workflow
Recommended: Validate automatically after creating or modifying a Basic FB:
# Validate ECC state machine (checks reachability, transitions, algorithms)
python scripts/validate_ecc.py path/to/MyBlock.fbt
# Validate ST algorithms (checks variable references, algorithm consistency)
python scripts/validate_st_algorithm.py path/to/MyBlock.fbt
# Generic validation (basic XML structure)
python ../eae-skill-router/scripts/validate_block.py --type basic path/to/MyBlock.fbt
Example: validate_ecc.py
# Basic validation
python scripts/validate_ecc.py MyBlock.fbt
# Verbose output with detailed information
python scripts/validate_ecc.py MyBlock.fbt --verbose
# JSON output for automation/CI
python scripts/validate_ecc.py MyBlock.fbt --json
# CI mode (JSON only, no human messages)
python scripts/validate_ecc.py MyBlock.fbt --ci
What validate_ecc.py checks:
- â All states are reachable from START
- â All event inputs have at least one transition
- â All transitions reference valid algorithms
- â No circular dependencies in state machine
- â Standard states present (START, INIT, REQ if applicable)
- â ï¸ States without outgoing transitions (warnings)
- â ï¸ Event inputs not used in transitions (warnings)
Example: validate_st_algorithm.py
# Validate algorithms
python scripts/validate_st_algorithm.py MyBlock.fbt --verbose
What validate_st_algorithm.py checks:
- â Algorithm names match ECC references
- â Variables referenced in algorithms are declared
- â ï¸ Empty algorithms (warnings)
- â ï¸ Potentially undefined variables (warnings, may be false positives)
- â ï¸ Unused algorithms (warnings)
Note: Full ST syntax validation is performed by the EAE compiler. These scripts catch common mistakes early to save compilation cycles.
Generate IDs
python ../eae-skill-router/scripts/generate_ids.py --hex 6 --guid 1
Integration with Validation Skills
Naming Validation
Use eae-naming-validator to ensure compliance with SE Application Design Guidelines:
Key Naming Rules for Basic FB:
- FB name: camelCase (e.g.,
scaleLogic,stateDevice,motorControl) - Interface variables: PascalCase (e.g.,
PermitOn,FeedbackOn,Value) - Internal variables: camelCase (e.g.,
error,outMinActiveLast,timerActive) - Events: SNAKE_CASE (e.g.,
INIT,REQ,CUSTOM_EVENT) - Algorithms: Match corresponding events (e.g., INIT algorithm, REQ algorithm)
Validate naming before creation:
# Validate FB and variable names
python ../eae-naming-validator/scripts/validate_names.py \
--app-dir IEC61499 \
--artifact-type BasicFB \
--name scaleLogic
Reference: EAE_ADG EIO0000004686.06, Section 1.5
Performance Analysis
Use eae-performance-analyzer to estimate CPU load:
# Analyze ST algorithm complexity
python ../eae-performance-analyzer/scripts/estimate_cpu_load.py \
--app-dir IEC61499 \
--platform soft-dpac-windows
What to Check:
- ST algorithm complexity (cyclomatic complexity)
- Execution time estimates
- CPU load percentage
Best Practices from EAE ADG
1. Naming Conventions (SE ADG Section 1.5)
Basic FB Naming:
- Use camelCase:
scaleLogic,stateDevice,motorControl - Use descriptive names that indicate purpose
- Avoid generic names:
block1,fb,logic
Variable Naming:
- Interface variables (inputs/outputs): PascalCase â
PermitOn,FeedbackOn,SetPoint - Internal variables (local to FB): camelCase â
error,outMinActiveLast,timerActive - Hungarian notation for complex types:
strConfig,arrBuffer,eState
Event Naming:
- Use SNAKE_CASE:
INIT,REQ,CUSTOM_EVENT,START_OPERATION - Standard events: INIT/INITO for initialization, REQ/CNF for requests
- Avoid generic names:
E1,DO,OUT
Algorithm Naming:
- Match corresponding event names: INIT algorithm, REQ algorithm
- For custom states: Use descriptive names like
calculateAverage,checkLimits
Reference: EAE_ADG EIO0000004686.06, Section 1.5
2. ECC Design Principles
State Machine Guidelines:
- Keep states focused (single responsibility)
- Use START state as the central hub
- Always include INIT/INITO pattern for initialization
- Use conditional transitions sparingly (prefer simple event-driven logic)
- Document complex transitions in comments
Standard Pattern:
START â â INIT (on INIT event, run INIT algorithm, fire INITO)
START â â REQ (on REQ event, run REQ algorithm, fire CNF)
3. ST Algorithm Best Practices
Algorithm Structure:
- Always set QO := QI at the beginning
- Keep algorithms simple (cyclomatic complexity <10 typical)
- Use clear variable names
- Add comments for complex logic
- Avoid deeply nested IF statements (max 3 levels)
Example:
(* INIT Algorithm *)
QO := QI;
error := FALSE;
result := 0.0;
(* REQ Algorithm *)
QO := QI;
IF QI THEN
result := inputValue * scaleFactor;
IF result > maxLimit THEN
result := maxLimit;
error := TRUE;
END_IF;
ELSE
error := TRUE;
END_IF;
4. Event-Variable Associations
With Var Guidelines:
- Always include QI with input events
- Always include QO with output events
- Associate all inputs used in the algorithm with the triggering event
- Associate all outputs produced by the algorithm with the output event
Anti-Patterns
1. Naming Anti-Patterns
â Wrong Casing for Basic FB
<!-- BAD: Using PascalCase for Basic FB -->
<FBType Name="MotorControl" ...>
â Correct camelCase
<FBType Name="motorControl" ...>
â Inconsistent Variable Casing
<!-- Interface variables should be PascalCase -->
<VarDeclaration Name="permitOn" Type="BOOL" /> <!-- BAD: should be "PermitOn" -->
<!-- Internal variables should be camelCase -->
<VarDeclaration Name="Error" Type="BOOL" /> <!-- BAD: should be "error" if internal -->
â Generic Event Names
<Event Name="E1" /> <!-- BAD: non-descriptive -->
<Event Name="DO" /> <!-- BAD: generic -->
â Descriptive Event Names
<Event Name="START_OPERATION" />
<Event Name="CALCULATE_RESULT" />
2. ECC Anti-Patterns
â Missing START State
<ECC>
<!-- BAD: No START state -->
<ECState Name="INIT" x="500" y="350" />
</ECC>
â START State Required
<ECC>
<ECState Name="START" x="550" y="430" />
<ECState Name="INIT" x="920" y="140">
<ECAction Algorithm="INIT" Output="INITO" />
</ECState>
</ECC>
â Unreachable States
<ECC>
<ECState Name="START" x="550" y="430" />
<ECState Name="ORPHAN" x="800" y="500">
<ECAction Algorithm="ORPHAN_ALG" Output="OUT" />
</ECState>
<!-- NO transitions to ORPHAN state - unreachable! -->
</ECC>
â Algorithm/Event Mismatch
<ECState Name="REQ" x="220" y="750">
<ECAction Algorithm="INIT" Output="CNF" /> <!-- BAD: INIT algorithm in REQ state -->
</ECState>
â Matching Algorithm Names
<ECState Name="REQ" x="220" y="750">
<ECAction Algorithm="REQ" Output="CNF" />
</ECState>
3. ST Algorithm Anti-Patterns
â Missing QO Assignment
<Algorithm Name="REQ">
<ST><![CDATA[
(* BAD: Forgot to set QO := QI *)
Result := Value1 * Value2;
]]></ST>
</Algorithm>
â Always Set QO
<Algorithm Name="REQ">
<ST><![CDATA[
QO := QI;
Result := Value1 * Value2;
]]></ST>
</Algorithm>
â Overly Complex Algorithms
(* BAD: Cyclomatic complexity > 15, deeply nested *)
IF condition1 THEN
IF condition2 THEN
IF condition3 THEN
IF condition4 THEN
(* 4+ levels of nesting - hard to read *)
END_IF;
END_IF;
END_IF;
END_IF;
â Refactor Complex Logic
(* Use early returns or break into multiple algorithms *)
IF NOT condition1 THEN
error := TRUE;
RETURN;
END_IF;
IF NOT condition2 THEN
error := TRUE;
RETURN;
END_IF;
(* Main logic here *)
â Undefined Variables
<Algorithm Name="REQ">
<ST><![CDATA[
QO := QI;
Result := UnknownVar * 2; (* UnknownVar not declared! *)
]]></ST>
</Algorithm>
4. Event-Variable Association Anti-Patterns
â Missing With Var
<Event Name="REQ">
<With Var="QI" />
<!-- BAD: Algorithm uses Value1 and Value2 but they're not associated -->
</Event>
<Algorithm Name="REQ">
<ST><![CDATA[
Result := Value1 * Value2; (* Value1, Value2 should be in With Var *)
]]></ST>
</Algorithm>
â Complete With Var Associations
<Event Name="REQ">
<With Var="QI" />
<With Var="Value1" />
<With Var="Value2" />
</Event>
Verification Checklist
Before committing your Basic FB:
Naming (run eae-naming-validator):
- FB name is camelCase
- Interface variables are PascalCase
- Internal variables are camelCase
- Events are SNAKE_CASE
Structure:
- Root element is
<FBType>(NOT<AdapterType>) - Uses
Standard="61499-2"(NOT61499-1) - Has
<BasicFB>element (NOT<FBNetwork>) - Has
<ECC>with START state
ECC Validation (run validate_ecc.py):
- All states reachable from START
- All event inputs have transitions
- All algorithms referenced in ECActions exist
- No orphaned states
ST Algorithm Validation (run validate_st_algorithm.py):
- All algorithms set QO := QI
- All referenced variables are declared
- Cyclomatic complexity <10 (typical)
- No undefined variables
Event-Variable Associations:
- INIT event has
<With Var="QI" /> - INITO event has
<With Var="QO" /> - All inputs used in algorithms are associated with triggering event
- All outputs produced are associated with output event
Performance (run eae-performance-analyzer):
- ST algorithm complexity is reasonable
- Estimated CPU load <70% (soft dPAC)
Scripts Validation:
-
python scripts/validate_ecc.py {Name}.fbtexits with 0 -
python scripts/validate_st_algorithm.py {Name}.fbtexits with 0
Registration:
- Registered in .dfbproj with
IEC61499Type="Basic" - .doc.xml and .meta.xml files created and registered
Related Skills
| Skill | When to Use |
|---|---|
| eae-naming-validator | Validate naming compliance (camelCase for Basic FB) |
| eae-performance-analyzer | Estimate CPU load from ST algorithms |
| eae-composite-fb | Create composite FBs with FBNetwork |
| eae-cat | Create CAT blocks with HMI |
| eae-datatype | Create custom data types for variables |