From 5c840368292645eb55c756ad74cf86ba006c273f Mon Sep 17 00:00:00 2001 From: Mohammad Tayyab Date: Mon, 19 Oct 2026 20:51:22 +0200 Subject: [PATCH 1/3] feat: add energy metric formulas Signed-off-by: Mohammad Tayyab --- src/frequenz/gridpool/config/_load.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/frequenz/gridpool/config/_load.py b/src/frequenz/gridpool/config/_load.py index 0dc5a01..db6f5ee 100644 --- a/src/frequenz/gridpool/config/_load.py +++ b/src/frequenz/gridpool/config/_load.py @@ -33,6 +33,13 @@ _logger = logging.getLogger(__name__) +_AUTO_FORMULA_METRICS = ( + "AC_POWER_ACTIVE", + "AC_ENERGY_ACTIVE", + "AC_ENERGY_ACTIVE_CONSUMED", + "AC_ENERGY_ACTIVE_DELIVERED", +) + async def load_configs( default_files: str | Path | list[str | Path] | None = None, @@ -232,7 +239,7 @@ def _derive_component_configs( ) -> dict[str, ComponentTypeConfig]: """Build the component-type configs for a microgrid from its graph. - Derives, per component type, the `AC_POWER_ACTIVE` formula and the + Derives, per component type, formulas for active power and energy, and the meter/inverter/component ID lists straight from the component graph. A component type only appears in the result if the graph yields a non-zero formula or at least one ID for it. @@ -257,7 +264,7 @@ def as_formula(derived: str) -> dict[str, str] | None: return None except ValueError: pass - return {"AC_POWER_ACTIVE": derived} + return {metric: derived for metric in _AUTO_FORMULA_METRICS} configs: dict[str, ComponentTypeConfig] = { "consumption": ComponentTypeConfig( From 063bead447df8e42297f64defc4d6b7de146a0e3 Mon Sep 17 00:00:00 2001 From: Mohammad Tayyab Date: Mon, 19 Oct 2026 20:51:38 +0200 Subject: [PATCH 2/3] test: update test cases Signed-off-by: Mohammad Tayyab --- tests/test_load.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tests/test_load.py b/tests/test_load.py index 5548acb..9bc7643 100644 --- a/tests/test_load.py +++ b/tests/test_load.py @@ -28,6 +28,18 @@ _load_microgrids_from_api, ) +_FORMULA_METRICS = ( + "AC_POWER_ACTIVE", + "AC_ENERGY_ACTIVE", + "AC_ENERGY_ACTIVE_CONSUMED", + "AC_ENERGY_ACTIVE_DELIVERED", +) + + +def _formulas(expression: str) -> dict[str, str]: + """Build the expected auto-generated formulas for an expression.""" + return {metric: expression for metric in _FORMULA_METRICS} + def _mock_client() -> MagicMock: """Mock an Assets API client for one microgrid: grid -> meter -> PV, + a meter.""" @@ -73,7 +85,7 @@ async def test_load_microgrids_from_api_derives_formulas_and_ids() -> None: cfg = configs[10] assert cfg.enterprise_id == 7 - assert cfg.ctype["pv"].formula == {"AC_POWER_ACTIVE": "COALESCE(#4, #2, 0.0)"} + assert cfg.ctype["pv"].formula == _formulas("COALESCE(#4, #2, 0.0)") assert cfg.ctype["pv"].inverter == [4] assert cfg.ctype["pv"].meter == [2] assert cfg.ctype["grid"].meter == [2, 3] @@ -105,7 +117,7 @@ async def test_load_microgrids_from_api_honours_the_component_graph_config() -> # Meter first, the opposite of the default order asserted above. ctype = configs[10].ctype - assert ctype["pv"].formula == {"AC_POWER_ACTIVE": "COALESCE(#2, #4, 0.0)"} + assert ctype["pv"].formula == _formulas("COALESCE(#2, #4, 0.0)") async def test_load_configs_forwards_the_component_graph_config() -> None: @@ -120,9 +132,7 @@ async def test_load_configs_forwards_the_component_graph_config() -> None: ) ).microgrids - assert configs[10].ctype["pv"].formula == { - "AC_POWER_ACTIVE": "COALESCE(#2, #4, 0.0)" - } + assert configs[10].ctype["pv"].formula == _formulas("COALESCE(#2, #4, 0.0)") async def test_load_configs_rejects_a_component_graph_config_without_a_client() -> None: @@ -197,7 +207,7 @@ async def test_derive_component_configs_builds_formulas_and_ids() -> None: configs = _derive_component_configs(graph) - assert configs["pv"].formula == {"AC_POWER_ACTIVE": "COALESCE(#4, #2, 0.0)"} + assert configs["pv"].formula == _formulas("COALESCE(#4, #2, 0.0)") assert configs["pv"].inverter == [4] assert configs["pv"].meter == [2] assert configs["grid"].meter == [2, 3] From d419e1eda4afdb1bf00bc5623580f6671a90d7b9 Mon Sep 17 00:00:00 2001 From: Mohammad Tayyab Date: Mon, 19 Oct 2026 20:54:49 +0200 Subject: [PATCH 3/3] docs: update release notes Signed-off-by: Mohammad Tayyab --- RELEASE_NOTES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index ffeaa94..0e807df 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -13,7 +13,7 @@ ## New Features - +- Automatically generate component formulas for the `AC_ENERGY_ACTIVE`, `AC_ENERGY_ACTIVE_CONSUMED`, and `AC_ENERGY_ACTIVE_DELIVERED` metrics when deriving microgrid configuration from the Assets API, in addition to the existing `AC_POWER_ACTIVE` formulas. ## Bug Fixes