helpers
frequenz.lib.notebooks.reporting.utils.helpers ¤
Energy flow and configuration utilities for microgrid analysis and reporting.
This module provides helper functions for
- Safe numeric extraction and aggregation from pandas DataFrames.
- Loading and validating YAML-based configuration files.
- Labeling microgrid component columns using configuration metadata.
- Computing derived energy flow metrics such as:
- Production excess
- Battery charge utilization
- Grid feed-in
- Self-consumption and self-share
- Formatting and timezone conversion utilities for reporting.
These utilities are primarily used in energy analytics pipelines and microgrid reporting notebooks to ensure consistent data preprocessing, metric calculation, and standardized output structures.
| FUNCTION | DESCRIPTION |
|---|---|
_get_numeric_series |
Safely extract a numeric Series or return zeros if missing. |
_sum_cols |
Safely sum multiple numeric columns. |
load_config |
Load and validate a YAML configuration file. |
_fmt_to_de_system |
Format numbers using German-style decimal conventions. |
_convert_timezone |
Convert a DataFrame timestamp column to a target timezone. |
label_component_columns |
Rename numeric component columns using MicrogridConfig. |
get_energy_report_columns |
Determine relevant columns for energy reporting. |
add_energy_flows |
Compute derived production, battery, and grid metrics. |
Notes
- These helpers are designed for internal use and assume well-structured DataFrames with datetime indices or timestamp columns.
- All numeric outputs are returned as float64 Series to ensure consistency.
Classes¤
Functions:¤
frequenz.lib.notebooks.reporting.utils.helpers.add_energy_flows ¤
add_energy_flows(
df: DataFrame,
production_cols: list[str] | None = None,
consumption_cols: list[str] | None = None,
grid_cols: list[str] | None = None,
battery_cols: list[str] | None = None,
) -> DataFrame
Compute and add derived energy flow metrics to the DataFrame.
This function aggregates production and consumption data, derives energy flow relationships such as grid feed-in, battery charging, and self-consumption, and appends these computed columns to the given DataFrame. Columns that are specified but missing or contain only null/zero values are ignored.
| PARAMETER | DESCRIPTION |
|---|---|
df
|
Input DataFrame containing production, consumption, and optionally battery power data.
TYPE:
|
production_cols
|
list of column names representing production sources. |
consumption_cols
|
list of column names representing consumption sources. |
grid_cols
|
list of column names representing grid import/export. |
battery_cols
|
optional list of column names for battery charging power. If None, battery-related flows are set to zero. |
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
A DataFrame including additional columns: - "production_excess": Production exceeding consumption. - "grid_feed_in": Portion of excess fed into the grid. - "production_self_use": Self-consumed portion of production. - "production_to_battery": Production energy sent to the battery. - "grid_to_battery": Grid energy sent to the battery. - "battery_to_grid": Battery discharge exported to the grid. - "battery_to_consumption": Battery discharge used by consumption. - "production_self_share": Share of production that is self-consumed (self-consumed / total production). - "production_self_usage": Share of consumption covered by self-production (self-consumed / total consumption). |
Source code in src/frequenz/lib/notebooks/reporting/utils/helpers.py
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 | |
frequenz.lib.notebooks.reporting.utils.helpers.build_color_map ¤
build_color_map(
cols: list[str],
color_dict: dict[str, str] | None = None,
palette: list[str] | None = None,
) -> dict[str, str]
Generate a color mapping for columns or categories.
Creates a mapping from column names (or categorical labels) to color
values. Default colors are sourced from the in-code color dictionary
and can be overridden via color_dict. Remaining columns are assigned
distinct colors from a chosen palette, ensuring no duplicates.
| PARAMETER | DESCRIPTION |
|---|---|
cols
|
List of column names or category labels to assign colors to. |
color_dict
|
Optional dictionary of color mappings to override defaults. Columns found here are assigned these colors directly. |
palette
|
Optional list of color codes to use as defaults. If None, a combined Plotly qualitative palette is used. |
| RETURNS | DESCRIPTION |
|---|---|
dict[str, str]
|
A dictionary mapping each column or category name to a unique color. |
Source code in src/frequenz/lib/notebooks/reporting/utils/helpers.py
frequenz.lib.notebooks.reporting.utils.helpers.convert_timezone ¤
Convert a datetime Series to a target timezone.
If the Series contains timezone-naive datetimes, they are first localized to
assume_tz before converting to target_tz.
| PARAMETER | DESCRIPTION |
|---|---|
ts
|
Input Series containing the datetime values.
TYPE:
|
target_tz
|
Timezone name to convert the Series to.
Defaults to
TYPE:
|
assume_tz
|
Timezone to assume for naive datetimes.
Defaults to
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Series
|
pd.Series: The timestamp Series converted to the requested timezone. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If |
Source code in src/frequenz/lib/notebooks/reporting/utils/helpers.py
frequenz.lib.notebooks.reporting.utils.helpers.fill_aggregated_component_columns ¤
fill_aggregated_component_columns(
df: DataFrame,
component_types: list[str],
config: AggregatedComponentConfig | None = None,
) -> DataFrame
Populate missing aggregate columns by summing labeled component columns.
| PARAMETER | DESCRIPTION |
|---|---|
df
|
Input DataFrame potentially containing aggregated component columns (e.g., "battery_power_flow") and labeled individual component columns (e.g., "Battery #1", "Battery #2").
TYPE:
|
component_types
|
List of component types to consider for aggregation (e.g., ["battery", "pv", "chp", "wind"]). |
config
|
Mapping of component types to tuples containing the aggregated column name and the prefix used to identify individual component columns.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
DataFrame with missing aggregated component columns filled in by summing |
DataFrame
|
the corresponding individual component columns. |
Source code in src/frequenz/lib/notebooks/reporting/utils/helpers.py
frequenz.lib.notebooks.reporting.utils.helpers.fmt_to_de_system ¤
Format a number using German-style decimal and thousands separators.
The function formats the number with two decimal places, using a comma as the decimal separator and a dot as the thousands separator.
| PARAMETER | DESCRIPTION |
|---|---|
x
|
The number to format.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The formatted string with German number formatting applied. |
Example
_fmt_to_de_system(12345.6789) '12.345,68'
Source code in src/frequenz/lib/notebooks/reporting/utils/helpers.py
frequenz.lib.notebooks.reporting.utils.helpers.get_energy_report_columns ¤
Build the list of dataframe columns for the energy report.
The selected columns depend on the available component types.
| PARAMETER | DESCRIPTION |
|---|---|
component_types
|
List of component types (e.g. ["pv", "wind", "chp", "battery"]) |
single_components
|
Extra component columns to always include. |
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
The full list of dataframe columns. |
Source code in src/frequenz/lib/notebooks/reporting/utils/helpers.py
frequenz.lib.notebooks.reporting.utils.helpers.get_meter_display_names
async
¤
get_meter_display_names(
microgrid_id: int,
*,
server_url: str | None = None,
auth_key: str | None = None,
sign_secret: str | None = None
) -> dict[str, str]
Fetch component display names asynchronously from the Assets API.
Source code in src/frequenz/lib/notebooks/reporting/utils/helpers.py
frequenz.lib.notebooks.reporting.utils.helpers.label_component_columns ¤
label_component_columns(
df: DataFrame,
mcfg: MicrogridConfig,
column_battery: str = "battery",
column_pv: str = "pv",
column_chp: str = "chp",
column_ev: str = "ev",
column_wind: str = "wind",
component_display_names: (
Mapping[str, str] | None
) = None,
) -> tuple[DataFrame, list[str]]
Rename numeric single-component columns to labeled names.
Numeric string column names like "14" are converted to
"Battery #14", "PV #14", "CHP #14" or "EV #14" based on
the component IDs provided by mcfg.component_type_ids(...)
| PARAMETER | DESCRIPTION |
|---|---|
df
|
Input DataFrame with numeric string column names.
TYPE:
|
mcfg
|
Configuration with
TYPE:
|
column_battery
|
Key name for battery component type.
TYPE:
|
column_pv
|
Key name for PV component type.
TYPE:
|
column_chp
|
Key name for CHP component type.
TYPE:
|
column_ev
|
Key name for EV component type.
TYPE:
|
column_wind
|
Key name for wind component type.
TYPE:
|
component_display_names
|
Optional mapping from numeric component IDs to human-readable display names fetched from the Assets API. |
| RETURNS | DESCRIPTION |
|---|---|
tuple[DataFrame, list[str]]
|
Tuple containing the renamed DataFrame and the list of applied labels |
Source code in src/frequenz/lib/notebooks/reporting/utils/helpers.py
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 | |
frequenz.lib.notebooks.reporting.utils.helpers.load_config ¤
Load a YAML config file and return it as a dictionary.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
Path to the YAML file.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict[str, Any]
|
Configuration values as a dictionary. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the YAML root element is not a mapping (dict). |
Source code in src/frequenz/lib/notebooks/reporting/utils/helpers.py
frequenz.lib.notebooks.reporting.utils.helpers.long_to_wide ¤
long_to_wide(
df: DataFrame,
*,
time_col: str | Index = "Timestamp",
category_col: str | None = "Battery",
value_col: str | None = "Battery Throughput",
sum_col_name: str | None = None,
aggfunc: AggFuncLiteral = "sum"
) -> DataFrame
Convert a long-format DataFrame into wide format with optional aggregation.
Transforms a long-format dataset (one row per timestamp-category pair) into a wide-format table, where each category becomes a separate column. Optionally adds a total (sum) column across all categories.
| PARAMETER | DESCRIPTION |
|---|---|
df
|
Input DataFrame in long format.
TYPE:
|
time_col
|
Column name representing timestamps used as the index in
the resulting wide table. Defaults to
TYPE:
|
category_col
|
Column name representing category labels that become
column headers in the wide table. Defaults to
TYPE:
|
value_col
|
Column name representing numeric values to aggregate and
pivot into columns. Defaults to
TYPE:
|
sum_col_name
|
Optional name for a new column containing the row-wise sum
of all category columns. If None, defaults to
TYPE:
|
aggfunc
|
Aggregation function applied when multiple entries exist per
timestamp-category pair (e.g.,
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
A wide-format DataFrame with one row per timestamp, one column per category, |
DataFrame
|
and an optional total column representing the aggregated sum across all categories. |
Source code in src/frequenz/lib/notebooks/reporting/utils/helpers.py
frequenz.lib.notebooks.reporting.utils.helpers.normalize_date_for_reporting ¤
Return midnight for past dates or current time for today.
If the input date is today (in the target timezone), this returns the
current time in that timezone. If the date is in the future, a ValueError
is raised to prevent selecting future dates. For past dates, midnight is
returned via set_date_to_midnight.
| PARAMETER | DESCRIPTION |
|---|---|
input_date
|
Date or datetime object to evaluate. |
timezone_name
|
Name of the target timezone (e.g., "Europe/Berlin"). Defaults to "UTC". Falls back to UTC if the timezone name is invalid.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
datetime
|
A timezone-aware datetime object representing the current time |
datetime
|
when the input date is today, or midnight for past dates. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If the input date is in the future. |
Source code in src/frequenz/lib/notebooks/reporting/utils/helpers.py
frequenz.lib.notebooks.reporting.utils.helpers.set_date_to_midnight ¤
Return a timezone-aware datetime set to midnight of the given date.
Converts a date or datetime into a midnight timestamp localized to the specified timezone. If the input is already a datetime, only the date portion is used.
| PARAMETER | DESCRIPTION |
|---|---|
input_date
|
Date or datetime object to normalize to midnight. |
timezone_name
|
Name of the target timezone (e.g., "Europe/Berlin"). Defaults to "UTC". Falls back to UTC if the timezone name is invalid.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
datetime
|
A timezone-aware datetime object representing midnight of the |
datetime
|
given date in the specified timezone. |