"""Enum types and constants for SimAuto wrapper.
This module defines standardized types for string literals used throughout
the SAW module, replacing hardcoded strings with type-safe enumerations.
"""
from enum import Enum, IntFlag, auto
from typing import Union
class _StrEnum(str, Enum):
"""Base class for string-valued enums with correct ``str()`` behavior.
Python 3.11+ changed ``str()`` on ``str, Enum`` to return
``'ClassName.MEMBER'`` instead of the value. This base class
restores the expected behavior so enums can be passed directly
to ``_run_script`` and pandas comparisons.
"""
def __str__(self):
return self.value
[docs]
class YesNo(_StrEnum):
"""Boolean flag values for PowerWorld commands.
PowerWorld uses "YES" and "NO" strings for boolean parameters in
script commands rather than true/false.
"""
YES = "YES"
"""Affirmative / enable option."""
NO = "NO"
"""Negative / disable option."""
[docs]
@classmethod
def from_bool(cls, value: bool) -> "YesNo":
"""Convert a Python boolean to YesNo enum.
Parameters
----------
value : bool
The boolean value to convert.
Returns
-------
YesNo
YesNo.YES if value is True, YesNo.NO otherwise.
"""
return cls.YES if value else cls.NO
[docs]
class FilterKeyword(_StrEnum):
"""Special filter keywords for PowerWorld commands.
These keywords are passed unquoted to PowerWorld, unlike custom
filter names which must be quoted.
"""
SELECTED = "SELECTED"
"""Only objects currently selected in PowerWorld."""
AREAZONE = "AREAZONE"
"""Objects in the active area/zone filter."""
ALL = "ALL"
"""Select all objects of the type."""
[docs]
class SolverMethod(_StrEnum):
"""Power flow solution methods.
These are the available solver algorithms for the SolvePowerFlow command.
"""
RECTNEWT = "RECTNEWT"
"""Rectangular Newton-Raphson (default)."""
POLARNEWT = "POLARNEWT"
"""Polar Newton-Raphson."""
GAUSSSEIDEL = "GAUSSSEIDEL"
"""Gauss-Seidel iterative method."""
FASTDEC = "FASTDEC"
"""Fast Decoupled method."""
ROBUST = "ROBUST"
"""Robust solver for difficult cases."""
DC = "DC"
"""DC power flow (linear approximation)."""
[docs]
class LinearMethod(_StrEnum):
"""Linear calculation methods for sensitivity analysis.
Used in PTDF, LODF, shift factor, and related calculations.
"""
DC = "DC"
"""DC linear method (most common default)."""
AC = "AC"
"""AC linear method."""
DCPS = "DCPS"
"""DC linear with post-solution adjustment."""
[docs]
class InterfaceLimitSetting(_StrEnum):
"""Interface limit configuration values."""
AUTO = "AUTO"
"""Automatic limit calculation."""
NONE = "NONE"
"""No limit applied."""
[docs]
class ObjectType(_StrEnum):
"""PowerWorld object type identifiers.
These are used for filtering and operations on specific element types.
"""
BUS = "BUS"
"""Bus/node."""
BRANCH = "BRANCH"
"""Branch (line or transformer)."""
GEN = "GEN"
"""Generator."""
LOAD = "LOAD"
"""Load."""
SHUNT = "SHUNT"
"""Shunt device."""
AREA = "AREA"
"""Control area."""
ZONE = "ZONE"
"""Zone."""
OWNER = "OWNER"
"""Owner."""
INTERFACE = "INTERFACE"
"""Interface (flowgate)."""
INJECTIONGROUP = "INJECTIONGROUP"
"""Injection group."""
BUSSHUNT = "BUSSHUNT"
"""Bus shunt."""
SUPERBUS = "SUPERBUS"
"""Super bus (aggregated)."""
TRANSFORMER = "TRANSFORMER"
"""Transformer specifically."""
LINE = "LINE"
"""Transmission line specifically."""
SUPERAREA = "SUPERAREA"
"""Super area (aggregated)."""
[docs]
class KeyFieldType(_StrEnum):
"""Key field types for result output."""
PRIMARY = "PRIMARY"
"""Primary key fields (e.g., BusNum)."""
SECONDARY = "SECONDARY"
"""Secondary key fields (e.g., BusName)."""
LABEL = "LABEL"
"""Label-based identification."""
[docs]
class StarBusHandling(_StrEnum):
"""Star bus handling options for case append operations."""
NEAR = "NEAR"
"""Map to nearest bus (default)."""
MAX = "MAX"
"""Map to maximum impedance bus."""
[docs]
class MultiSectionLineHandling(_StrEnum):
"""Multi-section line handling options for case append operations."""
MAINTAIN = "MAINTAIN"
"""Maintain multisection line structure (default)."""
EQUIVALENCE = "EQUIVALENCE"
"""Convert to equivalent circuits."""
[docs]
class IslandReference(_StrEnum):
"""Island reference options for sensitivity analysis."""
EXISTING = "EXISTING"
"""Use existing island configuration."""
NO = "NO"
"""No area reference."""
[docs]
class OnelineLinkMode(_StrEnum):
"""Oneline diagram linking modes."""
LABELS = "LABELS"
"""Link objects by labels (default)."""
NUMBERS = "NUMBERS"
"""Link objects by numbers."""
[docs]
class ShuntModel(_StrEnum):
"""Shunt model types for line tapping operations."""
CAPACITANCE = "CAPACITANCE"
"""Capacitive shunt model."""
INDUCTANCE = "INDUCTANCE"
"""Inductive shunt model."""
[docs]
class BranchDeviceType(_StrEnum):
"""Branch device types for bus splitting operations."""
LINE = "Line"
"""Transmission line."""
TRANSFORMER = "Transformer"
"""Transformer."""
BREAKER = "Breaker"
"""Circuit breaker."""
[docs]
class TSGetResultsMode(_StrEnum):
"""Mode for saving transient stability results."""
SINGLE = "SINGLE"
"""Single combined output file."""
SEPARATE = "SEPARATE"
"""Separate files per object."""
JSIS = "JSIS"
"""JSIS format output."""
[docs]
class BranchDistanceMeasure(_StrEnum):
"""Branch distance measurement types for topology analysis."""
REACTANCE = "X"
"""Use reactance (X) as distance measure."""
IMPEDANCE = "Z"
"""Use impedance magnitude (Z) as distance measure."""
[docs]
class BranchFilterMode(_StrEnum):
"""Branch filter modes for topology traversal."""
ALL = "ALL"
"""All branches."""
SELECTED = "SELECTED"
"""Only selected branches."""
CLOSED = "CLOSED"
"""Only closed branches."""
[docs]
class ScalingBasis(_StrEnum):
"""Scaling basis for load/generation scaling operations."""
MW = "MW"
"""Absolute MW/MVAR values."""
FACTOR = "FACTOR"
"""Multiplier factor."""
[docs]
class ObjectIDHandling(_StrEnum):
"""Object ID handling modes for contingency export."""
NO = "NO"
"""Standard object references."""
YES_MS_3W = "YES_MS_3W"
"""Include multi-section and 3-winding IDs."""
[docs]
class RatingSetPrecedence(_StrEnum):
"""Rating set precedence for weather-based ratings."""
NORMAL = "NORMAL"
"""Use normal rating set."""
CTG = "CTG"
"""Use contingency rating set."""
[docs]
class RatingSet(_StrEnum):
"""Rating set identifiers for branch limits."""
DEFAULT = "DEFAULT"
"""Use default rating."""
NO = "NO"
"""Don't update rating."""
A = "A"
B = "B"
C = "C"
D = "D"
E = "E"
F = "F"
G = "G"
H = "H"
I = "I"
J = "J"
K = "K"
L = "L"
M = "M"
N = "N"
O = "O"
[docs]
class FieldListColumn(_StrEnum):
"""Column names for GetFieldList results.
PowerWorld returns field metadata with these column headers. Different
Simulator versions may return different subsets of these columns.
"""
KEY_FIELD = "key_field"
"""Whether the field is a key field."""
INTERNAL_FIELD_NAME = "internal_field_name"
"""PowerWorld internal field name."""
FIELD_DATA_TYPE = "field_data_type"
"""Data type of the field."""
DESCRIPTION = "description"
"""Human-readable description."""
DISPLAY_NAME = "display_name"
"""Display name in PowerWorld UI."""
ENTERABLE = "enterable"
"""Whether the field can be edited."""
[docs]
@classmethod
def base_columns(cls) -> list:
"""Returns the standard 5-column format (most common)."""
return [
cls.KEY_FIELD.value,
cls.INTERNAL_FIELD_NAME.value,
cls.FIELD_DATA_TYPE.value,
cls.DESCRIPTION.value,
cls.DISPLAY_NAME.value,
]
[docs]
@classmethod
def old_columns(cls) -> list:
"""Returns the legacy 4-column format (older Simulator versions)."""
return [
cls.KEY_FIELD.value,
cls.INTERNAL_FIELD_NAME.value,
cls.FIELD_DATA_TYPE.value,
cls.DESCRIPTION.value,
]
[docs]
@classmethod
def new_columns(cls) -> list:
"""Returns the extended 6-column format (newer Simulator versions)."""
return [
cls.KEY_FIELD.value,
cls.INTERNAL_FIELD_NAME.value,
cls.FIELD_DATA_TYPE.value,
cls.DESCRIPTION.value,
cls.DISPLAY_NAME.value,
cls.ENTERABLE.value,
]
[docs]
class SpecificFieldListColumn(_StrEnum):
"""Column names for GetSpecificFieldList results.
PowerWorld returns specific field metadata with these column headers.
"""
VARIABLENAME_LOCATION = "variablename:location"
"""Variable name with location."""
FIELD = "field"
"""Field identifier."""
COLUMN_HEADER = "column header"
"""Column header label."""
FIELD_DESCRIPTION = "field description"
"""Human-readable description."""
ENTERABLE = "enterable"
"""Whether the field can be edited."""
[docs]
@classmethod
def base_columns(cls) -> list:
"""Returns the standard 4-column format."""
return [
cls.VARIABLENAME_LOCATION.value,
cls.FIELD.value,
cls.COLUMN_HEADER.value,
cls.FIELD_DESCRIPTION.value,
]
[docs]
@classmethod
def new_columns(cls) -> list:
"""Returns the extended 5-column format (newer Simulator versions)."""
return [
cls.VARIABLENAME_LOCATION.value,
cls.FIELD.value,
cls.COLUMN_HEADER.value,
cls.FIELD_DESCRIPTION.value,
cls.ENTERABLE.value,
]
# Type aliases for flexibility - allows either enum or raw string
FilterType = Union[FilterKeyword, str]
class PowerWorldMode(_StrEnum):
"""PowerWorld Simulator operating modes."""
RUN = "RUN"
"""Run mode for executing simulations."""
EDIT = "EDIT"
"""Edit mode for modifying case data."""
class FaultType(_StrEnum):
"""Fault types for fault analysis calculations."""
SLG = "SLG"
"""Single Line to Ground fault."""
LL = "LL"
"""Line to Line fault."""
THREE_PHASE = "3PB"
"""Three Phase Balanced fault."""
DLG = "DLG"
"""Double Line to Ground fault."""
class GICCalcMode(_StrEnum):
"""GIC calculation mode options."""
SNAPSHOT = "SnapShot"
"""Single time point calculation."""
TIME_VARYING = "TimeVarying"
"""Time series from uniform field."""
NON_UNIFORM_TIME_VARYING = "NonUniformTimeVarying"
"""Time series with spatial variation."""
SPATIALLY_UNIFORM_TIME_VARYING = "SpatiallyUniformTimeVarying"
"""Spatially uniform time series."""
# ---------------------------------------------------------------------------
# Bus Category Classification
# ---------------------------------------------------------------------------
[docs]
class BusType(_StrEnum):
"""Power flow bus type from the BusCat field.
The three fundamental bus types that determine which equations
a bus contributes to the power flow Jacobian.
Attributes
----------
SLACK : str
Reference bus — fixes voltage magnitude and angle.
PV : str
Generator bus — specifies P injection and V magnitude.
PQ : str
Load bus — specifies P and Q injection.
"""
SLACK = "Slack"
PV = "PV"
PQ = "PQ"
[docs]
class BusCtrl(IntFlag):
"""Voltage control modifier flags from BusCat qualifiers.
Bitwise-combinable flags describing how a bus participates in
voltage regulation. A remotely regulated bus with droop control
would have ``BusCtrl.REMOTE | BusCtrl.DROOP``.
Attributes
----------
NONE : int
No special control.
REMOTE : int
Remote voltage regulation (controls voltage at another bus).
DROOP : int
Voltage droop control with deadband.
LDC : int
Line drop compensation.
TOL : int
Voltage setpoint tolerance band (PVTol mode).
"""
NONE = 0
REMOTE = auto()
DROOP = auto()
LDC = auto()
TOL = auto()
[docs]
class Role(_StrEnum):
"""Bus role in a voltage regulation group.
When multiple generators coordinate to regulate voltage at a
remote bus, each participating bus takes on a distinct role.
Attributes
----------
NONE : str
Not part of a regulation group (local control only).
PRIMARY : str
Enforces the voltage equation at the regulated bus.
SECONDARY : str
Shares reactive power proportionally with the primary.
TARGET : str
The bus whose voltage is being regulated remotely.
"""
NONE = "None"
PRIMARY = "Primary"
SECONDARY = "Secondary"
TARGET = "Target"