Skip to content

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:

Text Only
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

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

Bash
# 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