Create Power System Components with Units¶
Learn how to define power system components with proper unit handling, including per-unit normalization, multiple base values, and automatic unit conversions.
Prerequisites¶
Install R2X Core:
pip install r2x-core
Step 1: Create a Component with Per-Unit Fields¶
Define a generator with per-unit fields using the HasPerUnit mixin and Unit
annotations. R2X Core stores all per-unit quantities internally in device-base
per-unit, so display modes only affect how values appear, not how they’re
calculated.
>>> from typing import Annotated
>>> from infrasys import Component
>>> from r2x_core import HasPerUnit, Unit
>>>
>>> class Generator(HasPerUnit, Component):
... """Generator with per-unit power tracking."""
... base_power: Annotated[float, Unit("MVA")]
... rated_voltage: Annotated[float, Unit("kV")]
... output: Annotated[float, Unit("pu", base="base_power")]
>>>
>>> gen = Generator(
... name="Coal Plant 1",
... base_power=500.0,
... rated_voltage=22.0,
... output=0.85
... )
>>> print(gen.name)
Coal Plant 1
The output field stores the value in per-unit normalized to base_power.
Step 2: Handle Multiple Base Values¶
Equipment with multiple ratings, like transformers, can reference different bases. Each field independently specifies which base it normalizes to, and R2X Core tracks and converts accordingly.
>>> from typing import Annotated
>>> from infrasys import Component
>>> from r2x_core import HasPerUnit, Unit
>>>
>>> class Transformer(HasPerUnit, Component):
... """Transformer with multiple voltage references."""
... base_power: Annotated[float, Unit("MVA")]
... high_voltage: Annotated[float, Unit("kV")]
... low_voltage: Annotated[float, Unit("kV")]
... impedance: Annotated[float, Unit("pu", base="base_power")]
... tap_position: Annotated[float, Unit("pu", base="high_voltage")]
>>>
>>> tx = Transformer(
... name="Main TX",
... base_power=100.0,
... high_voltage=138.0,
... low_voltage=13.8,
... impedance=0.10,
... tap_position=1.05
... )
>>> print(tx.name)
Main TX
Step 3: Change Display Modes¶
View unit values in different display modes without affecting internal
calculations. The UnitSystem controls how values are presented to users.
>>> from r2x_core import UnitSystem, set_unit_system, get_unit_system
>>>
>>> current = get_unit_system()
>>> print(type(current).__name__)
UnitSystem
>>>
>>> set_unit_system(UnitSystem.DEVICE_BASE)
Step 4: Work with the HasUnits Mixin¶
Use the HasUnits mixin to get unit-aware access to all component fields. This
provides a convenient interface for components that need explicit unit
management.
>>> from typing import Annotated
>>> from infrasys import Component
>>> from r2x_core import HasUnits, Unit
>>>
>>> class Load(HasUnits, Component):
... """Load with unit-aware power tracking."""
... base_power: Annotated[float, Unit("MVA")]
... active_power: Annotated[float, Unit("pu", base="base_power")]
... reactive_power: Annotated[float, Unit("pu", base="base_power")]
>>>
>>> load = Load(
... name="Load 1",
... base_power=50.0,
... active_power=0.8,
... reactive_power=0.3
... )
>>> print(load.name)
Load 1
Summary¶
You’ve learned how to:
Create components with unit-aware fields using
HasPerUnitandUnitannotationsHandle equipment with multiple base values by specifying base references per field
Change display modes to view values in different units
Use the
HasUnitsmixin for explicit unit management in components
Next Steps¶
Work with Units - Learn advanced unit operations
Processing File Data - Import measurement data with automatic conversions
See Also¶
Unit- Unit annotation APIHasPerUnit- Per-unit mixin classUnit System Design and Architecture - Design philosophy behind the unit system