Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 61 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,61 @@

## Introduction

High-level interface to grid pools for the Frequenz platform.
High-level interface to gridpools for the Frequenz platform.

TODO(cookiecutter): Improve the README file
## Market topology configuration

Market topology is stored under the `assets` namespace. A relation names at
least two of a gridpool, microgrid and market location:

```toml
assets.microgrids.241.meta.microgrid_id = 241

assets.market_locations.10208446344.id = "10208446344"

assets.relations.G80M241L10208446344.gridpool_id = 80
assets.relations.G80M241L10208446344.microgrid_id = 241
assets.relations.G80M241L10208446344.market_location_id = "10208446344"
assets.relations.G80M241L10208446344.delivery_area = "10YDE-RWENET---I"
assets.relations.G80M241L10208446344.validity.trading.participation = "ENERGY_TRADING"
assets.relations.G80M241L10208446344.validity.trading.start = 2026-01-01T00:00:00Z
```

A relation naming a gridpool requires a delivery area. A gridpool-free relation
must link a microgrid and market location, and may carry a delivery area for a
direct market-location-to-area mapping. Omitted market-location types default
to `MALO_ID`; omitted market areas default to `101` (`EU_DE`).

**Current limitation:** Delivery areas support only 16-character EIC codes;
other identifier types are rejected. Validation checks the format and check
character, not registration with an EIC issuing office.

Validity periods are half-open: the start is inclusive, the end exclusive, and
an omitted bound is open. Bounds and query instants must include a UTC offset.

Load one or more files and query the merged document with:

```python
from datetime import datetime, timezone
from pathlib import Path

from frequenz.gridpool.config import load_assets_from_files

config = load_assets_from_files(
[Path("topology.toml"), Path("topology-overrides.toml")]
)
relations = config.find_relations(
microgrid_id=241,
at=datetime(2026, 1, 15, tzinfo=timezone.utc),
)
```

Later files override individual fields from earlier files. The projections
`find_delivery_areas`, `find_market_locations` and `find_microgrids` accept
filters for the other relation sides and an instant.

Market locations are keyed by raw ID, so the same raw ID cannot be used in
several market areas within one document.

## Supported Platforms

Expand Down Expand Up @@ -86,7 +138,11 @@ Redirect stdout to save the result:
gridpool-cli generate-config <microgrid_id> > microgrid.toml
```

You can layer existing config files with the Assets API by precedence
This command emits only microgrid entries. Topology relations, including their
delivery-area codes, and market-location entries from input files are not
included in its stdout output.

You can layer existing microgrid config files with the Assets API by precedence
(`--default` < Assets API < `--override`). Values from a `--default` file are
overridden by the API, while a `--override` file keeps its own values and the
API only fills the gaps:
Expand All @@ -97,7 +153,8 @@ gridpool-cli generate-config <microgrid_id> \
--override overrides.toml > microgrid.toml
```

If no microgrid IDs are given, they are taken from the supplied files:
If no microgrid IDs are given, they are taken from the microgrid entries in the
supplied files:

```bash
gridpool-cli generate-config --override existing.toml > microgrid.toml
Expand Down
56 changes: 50 additions & 6 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,62 @@
configs = AssetsConfig.load_from_file(path).microgrids
```

`load_configs_from_files` and `load_configs` are unchanged.
`load_configs` keeps its existing interface. `load_configs_from_files` now
layers files field by field instead of replacing a complete microgrid entry;
fields omitted by a later file retain the value from the earlier layer and
cannot be removed by omission.

- `Metadata.delivery_area` is removed. Delivery areas are read from topology
relations instead. When relations are present, the legacy `Metadata.gid`
must be their sole gridpool ID; remove it for a microgrid that participates
in several gridpools.

- Relation validity bounds and `at` query instants must include a UTC offset.

- The implementation modules `config.assets`, `config.load` and
`config.microgrid` are now private. Import their public names from
`frequenz.gridpool.config` instead.

## New Features

- `AssetsConfig` gives the `assets` namespace a type, so the entities still to
come are added as fields rather than as more dict lookups. Entries are checked
against the ID they are filed under wherever the class is loaded, not only via
`load_from_file`.
come are added as fields rather than as more dict lookups. Microgrid IDs are
checked during construction. `AssetsConfig.check()` performs the topology-wide
checks after all layers have been merged; the file loaders call it unless
`AssetsConfig.load_from_file` is passed `check=False`.

File loaders ignore unknown entity tables with a warning, so a reader keeps
working against files that already carry newer entities.

Entity tables a version does not know are ignored with a warning, so a reader
keeps working against files that already carry newer entities.
- Market topology is described under `assets.relations`, based on the Assets
API `MarketTopologyRelation`: each record links at least two of a gridpool, a
microgrid and a market location, filed under a `G<>M<>L<>` key derived from its
own sides. A relation naming a gridpool sits in a `delivery_area` that rides on
the relation, so a gridpool-to-microgrid relation with no market location still
carries one. A relation's validity lives in `validity`, each entry a half-open
`[start, end)` datetime period it applies over. Use-case-specific periods
qualify a relation; separate relations let one microgrid participate in
several gridpools. The config extends the API with plain periods for relations
that do not distinguish use cases. A gridpool-free microgrid-to-market-location
relation may also carry a delivery area for a direct mapping. Market locations
live under `assets.market_locations` as self-describing entries carrying their
own identifier, how to read it (MALO by default), and the Assets API market
area (`EU_DE` by default). Delivery areas currently support only
check-character-validated EIC code strings on relations. Raw market-location
IDs must be unique within a document, including across market areas.

`load_assets_from_files` layers several files into one document. Later files
override individual fields from earlier ones. `AssetsConfig` answers the common
lookups with `find_relations` and the projections `find_delivery_areas`,
`find_market_locations` and `find_microgrids`, each filtered by the other
sides and an instant.

Time-varying enterprise ownership is outside this change;
`Metadata.enterprise_id` remains as a scalar field.

## Bug Fixes

- Layering config files no longer resets a field a later file leaves unset back
to its default. The raw tables are merged before they are loaded.

<!-- Here goes notable bug fixes that are worth a special mention or explanation -->
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ min-similarity-lines = 40
disable = [
"too-few-public-methods",
"too-many-return-statements",
"too-many-arguments",
# disabled because it conflicts with isort
"wrong-import-order",
"ungrouped-imports",
Expand Down
2 changes: 1 addition & 1 deletion src/frequenz/gridpool/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
merge_config_maps,
merge_microgrid_configs,
)
from .config.assets import AssetsConfig
from .config._assets import AssetsConfig

__all__ = [
"ComponentGraphConfig",
Expand Down
20 changes: 15 additions & 5 deletions src/frequenz/gridpool/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
# License: MIT
# Copyright © 2025 Frequenz Energy-as-a-Service GmbH

"""Microgrid configuration data model and loading."""
"""Asset configuration data models and loading."""

from frequenz.microgrid_component_graph import ComponentGraphConfig, FormulaOverrides

from .assets import AssetsConfig
from .load import (
from ._assets import AssetsConfig
from ._load import (
load_assets_from_files,
load_configs,
load_configs_from_api,
load_configs_from_files,
)
from .microgrid import (
from ._microgrid import (
BatteryConfig,
ComponentCategory,
ComponentType,
Expand All @@ -23,19 +24,28 @@
merge_config_maps,
merge_microgrid_configs,
)
from ._topology import (
MarketLocationConfig,
RelationConfig,
ValidityConfig,
)

__all__ = [
"AssetsConfig",
"BatteryConfig",
"ComponentCategory",
"ComponentGraphConfig",
"ComponentType",
"ComponentTypeConfig",
"FormulaOverrides",
"MarketLocationConfig",
"Metadata",
"AssetsConfig",
"MicrogridConfig",
"PVConfig",
"RelationConfig",
"ValidityConfig",
"WindConfig",
"load_assets_from_files",
"load_configs",
"load_configs_from_api",
"load_configs_from_files",
Expand Down
Loading