Getting Started¶
What Is echo-energycalc?¶
echo-energycalc is the Python calculation engine for the Performance Server at Echoenergia. It is responsible for computing all server-side features (tags, variables) in the performance database, running batch jobs that interact with Bazefield, and calculating alarm thresholds.
Originally focused on energy calculations (power curves, energy estimation, electrical losses), the package has since evolved into a general calculation framework used for wind turbines, solar inverters, SPEs (Sub-Plant Equipment groupings), met masts, and other asset types.
Package Structure¶
The package is organized around three main subsystems:
echo_energycalc/
│
├── Feature Calculators # Compute features (tags) for individual objects
│ ├── feature_calc_core.py ← FeatureCalculator base class
│ ├── feature_calc_*.py ← concrete calculator implementations
│ ├── solar_energy_loss_*.py ← solar-specific loss calculators
│ └── calculation_handler.py ← orchestrates feature calculations
│
├── Calculation Requirements # Fetch data needed by calculators
│ ├── calculation_requirements_core.py ← CalculationRequirement base class
│ └── calculation_requirement_*.py ← concrete requirement implementations
│
├── Job System # Batch jobs that run in the Performance Server
│ ├── job_instance.py ← JobInstance base class
│ ├── job_instance_*.py ← concrete job implementations
│ └── job_handler.py ← discovers and runs jobs from the DB
│
├── Alarm Calculations # Alarm threshold computation
│ ├── alarm_calc_core.py
│ └── alarm_calc_threshold.py
│
└── Utilities & Constants
├── constants.py ← auto-discovery of all calculators/jobs
├── feature_calc_utils.py ← shared aggregation helpers
├── _polars_utils.py ← pandas ↔ polars conversion
└── ... ← power curve, filters, yaw, solar regression
Note
All new calculator modules follow auto-registration: simply defining a class with a _name attribute is enough — no manual registration in constants.py is required.
Key Concepts for Developers¶
server_calc_type — The link between the DB and code¶
Every calculated feature in performance_db has a server_calc_type attribute. This string is the key that maps a feature to its Python calculator class. For example, server_calc_type = "theoretical_active_power" maps to FeatureCalcPowerTheoretical.
CalculationRequirement — Declarative data fetching¶
Instead of writing DB queries inline inside calculators, each calculator declares its requirements at construction time. Requirements are checked for validity and then fetched in a single _fetch_requirements() call. This pattern:
- Makes it easy to understand what data a calculator needs by reading its
__init__. - Enables thread-safe caching across parallel calculations.
- Allows optional requirements (e.g.,
neighbor_active_power_regressions).
CalculationHandler — The orchestrator¶
CalculationHandler is the entry point used by Airflow DAGs. It discovers which features need to be calculated for which objects, instantiates the correct FeatureCalculator subclass for each, runs them (optionally in parallel), and saves the results.
JobInstance — Server-side batch jobs¶
Jobs are one-off or periodic tasks stored in performance_db. Unlike feature calculators (which always compute a specific feature/object pair), jobs can target arbitrary object lists and perform actions like inserting Bazefield allocations or deleting tags.
Documentation Sections¶
| Section | Description |
|---|---|
| Feature Calculation | How features are calculated, how to add new calculators, and all available calculator classes |
| Alarm Calculation | Threshold-based alarm calculation |
| Jobs | Batch job framework and available job types |
| Changelog | Full version history |
Development Quick Reference¶
# Install for local development
uv pip install . --no-deps --reinstall --no-cache
# Run all tests (requires Echo VPN)
pytest
# Run a specific test
pytest -k <test_name>
# Lint and format
ruff check .
ruff format .
# Serve docs locally
mkdocs serve -a localhost:8111