block-brickSpxComponent

Overview

An SpxComponent represents a node in a tree of components. Each node can:

  • Hold configuration data (definition)

  • Track a parent and any number of named children

  • Propagate lifecycle calls (e.g. prepare(), run(),

    destroy()) through its subtree

  • Behave like a Python dict for child lookup

Because of its generic design, you can subclass SpxComponent to define

specific simulation models—e.g. electrical devices or control‐system

blocks—that plug into MiL workflows.


Core Attributes

Attribute
Type
Description

name

str

Unique identifier for this component instance.

parent

Optional[SpxComponent]

Reference to the parent component; None if this is the root.

children

Dict[str, SpxComponent]

Mapping of child names to child component instances.

definition

Any

Configuration data used to populate and initialize this component.

state

SpxComponentState

Current lifecycle state (e.g. INITIALIZED, RUNNING, DESTROYED).

logger

logging.Logger

Preconfigured logger under name spx_sdk.SpxComponent.<name>.


Child Management

  • Validation

    • Adding a child to itself raises ValueError.

    • Adding non-SpxComponent raises ValueError.


Dictionary-Like Interface

SpxComponent implements getitem, setitem, contains, and len, letting you treat it like a dict of its children:

This makes dynamic tree construction and traversal concise and Pythonic.


Lifecycle Methods

Each lifecycle call:

  1. Logs the action

  2. Updates self.state

  3. Propagates the call to all children

prepare()

Sets state → PREPARING; children → prepare(); → PREPARED

run()

→ RUNNING; children → run(); → STOPPED

start()

Alias for run().

pause()

→ PAUSING; children → pause(); → PAUSED

stop()

→ STOPPING; children → stop(); → STOPPED

reset()

→ STOPPING; children → reset(); → STOPPED

destroy()

→ DESTROYING; children → destroy(); clears children; → DESTROYED


Extending for Simulation Models

To create a custom component—e.g. a device block in an MiL setup—subclass

SpxComponent (or Item if you’re using the SPX container pattern):

  • _populate: Override to extract domain-specific properties from

    definition. Always call super() first.

  • Lifecycle hooks: Add logging or custom behavior before/after

    calling super().prepare() / super().run(), etc.


Usage Examples

Simple Hierarchy

Integrating in MiL System


Best Practices

  • Unique Names: Use descriptive, unique name values to avoid collisions.

  • Docstrings: Document any overrides of _populate or lifecycle methods.

  • Composition: If your model contains distinct sub-elements, nest them as children.

  • Logging: Leverage self.logger.debug for traceability in MiL runs.

  • Dictionary Interface: Prefer component.get("child") or 'child' in component over manual children[...] access.

Last updated