frequenz-gridpool 0.3.1__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. {frequenz_gridpool-0.3.1/src/frequenz_gridpool.egg-info → frequenz_gridpool-0.4.0}/PKG-INFO +7 -7
  2. frequenz_gridpool-0.4.0/RELEASE_NOTES.md +20 -0
  3. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/pyproject.toml +6 -6
  4. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/src/frequenz/gridpool/_graph_generator.py +1 -3
  5. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/src/frequenz/gridpool/_microgrid_config.py +137 -9
  6. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0/src/frequenz_gridpool.egg-info}/PKG-INFO +7 -7
  7. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/src/frequenz_gridpool.egg-info/requires.txt +6 -6
  8. frequenz_gridpool-0.3.1/RELEASE_NOTES.md +0 -19
  9. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/LICENSE +0 -0
  10. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/MANIFEST.in +0 -0
  11. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/README.md +0 -0
  12. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/setup.cfg +0 -0
  13. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/src/frequenz/gridpool/__init__.py +0 -0
  14. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/src/frequenz/gridpool/cli/__init__.py +0 -0
  15. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/src/frequenz/gridpool/cli/__main__.py +0 -0
  16. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/src/frequenz/gridpool/cli/_render_graph.py +0 -0
  17. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/src/frequenz/gridpool/conftest.py +0 -0
  18. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/src/frequenz/gridpool/py.typed +0 -0
  19. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/src/frequenz_gridpool.egg-info/SOURCES.txt +0 -0
  20. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/src/frequenz_gridpool.egg-info/dependency_links.txt +0 -0
  21. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/src/frequenz_gridpool.egg-info/entry_points.txt +0 -0
  22. {frequenz_gridpool-0.3.1 → frequenz_gridpool-0.4.0}/src/frequenz_gridpool.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: frequenz-gridpool
3
- Version: 0.3.1
3
+ Version: 0.4.0
4
4
  Summary: High-level interface to grid pools for the Frequenz platform.
5
5
  Author-email: Frequenz Energy-as-a-Service GmbH <floss@frequenz.com>
6
6
  License: MIT
@@ -24,7 +24,7 @@ Requires-Dist: marshmallow-dataclass<9,>=8.7.1
24
24
  Requires-Dist: asyncclick<9,>=8.3.0.4
25
25
  Requires-Dist: typing-extensions<5,>=4.14.1
26
26
  Requires-Dist: frequenz-microgrid-component-graph<0.4,>=0.3.4
27
- Requires-Dist: frequenz-client-assets<0.3,>=0.2.0
27
+ Requires-Dist: frequenz-client-assets<0.4,>=0.3.0
28
28
  Provides-Extra: render-graph
29
29
  Requires-Dist: matplotlib<4,>=3.7.0; extra == "render-graph"
30
30
  Requires-Dist: networkx<4,>=3.0; extra == "render-graph"
@@ -38,20 +38,20 @@ Provides-Extra: dev-formatting
38
38
  Requires-Dist: black==25.11.0; extra == "dev-formatting"
39
39
  Requires-Dist: isort==7.0.0; extra == "dev-formatting"
40
40
  Provides-Extra: dev-mkdocs
41
- Requires-Dist: Markdown==3.10; extra == "dev-mkdocs"
41
+ Requires-Dist: Markdown==3.10.2; extra == "dev-mkdocs"
42
42
  Requires-Dist: black==25.11.0; extra == "dev-mkdocs"
43
43
  Requires-Dist: mike==2.1.3; extra == "dev-mkdocs"
44
44
  Requires-Dist: mkdocs-gen-files==0.5.0; extra == "dev-mkdocs"
45
45
  Requires-Dist: mkdocs-literate-nav==0.6.2; extra == "dev-mkdocs"
46
46
  Requires-Dist: mkdocs-macros-plugin==1.5.0; extra == "dev-mkdocs"
47
- Requires-Dist: mkdocs-material==9.7.1; extra == "dev-mkdocs"
48
- Requires-Dist: mkdocstrings[python]==1.0.1; extra == "dev-mkdocs"
47
+ Requires-Dist: mkdocs-material==9.7.3; extra == "dev-mkdocs"
48
+ Requires-Dist: mkdocstrings[python]==1.0.3; extra == "dev-mkdocs"
49
49
  Requires-Dist: mkdocstrings-python==1.19.0; extra == "dev-mkdocs"
50
50
  Requires-Dist: frequenz-repo-config[lib]==0.13.7; extra == "dev-mkdocs"
51
51
  Provides-Extra: dev-mypy
52
52
  Requires-Dist: mypy==1.19.1; extra == "dev-mypy"
53
53
  Requires-Dist: types-networkx>=3.6.1.20251220; extra == "dev-mypy"
54
- Requires-Dist: types-Markdown==3.10.0.20251106; extra == "dev-mypy"
54
+ Requires-Dist: types-Markdown==3.10.2.20260211; extra == "dev-mypy"
55
55
  Requires-Dist: frequenz-gridpool[dev-mkdocs,dev-noxfile,dev-pytest]; extra == "dev-mypy"
56
56
  Provides-Extra: dev-noxfile
57
57
  Requires-Dist: nox==2025.11.12; extra == "dev-noxfile"
@@ -60,7 +60,7 @@ Provides-Extra: dev-pylint
60
60
  Requires-Dist: frequenz-gridpool[dev-mkdocs,dev-noxfile,dev-pytest]; extra == "dev-pylint"
61
61
  Provides-Extra: dev-pytest
62
62
  Requires-Dist: pytest==9.0.2; extra == "dev-pytest"
63
- Requires-Dist: pylint==4.0.4; extra == "dev-pytest"
63
+ Requires-Dist: pylint==4.0.5; extra == "dev-pytest"
64
64
  Requires-Dist: frequenz-repo-config[extra-lint-examples]==0.13.7; extra == "dev-pytest"
65
65
  Requires-Dist: pytest-mock==3.15.1; extra == "dev-pytest"
66
66
  Requires-Dist: pytest-asyncio==1.3.0; extra == "dev-pytest"
@@ -0,0 +1,20 @@
1
+ # Frequenz Gridpool Library Release Notes
2
+
3
+ ## Summary
4
+
5
+ This release adds default formulas for AC energy metrics when they are not
6
+ explicitly configured.
7
+
8
+ ## Upgrading
9
+
10
+ * Update assets client to v0.3.0.
11
+
12
+ ## New Features
13
+
14
+ * Added default summation formulas for `AC_ENERGY_ACTIVE`,
15
+ `AC_ENERGY_ACTIVE_CONSUMED`, and `AC_ENERGY_ACTIVE_DELIVERED` when formulas are
16
+ not provided. The defaults are built from the component IDs configured for the
17
+ component type.
18
+
19
+ ## Bug Fixes
20
+
@@ -30,7 +30,7 @@ dependencies = [
30
30
  "asyncclick >= 8.3.0.4, < 9",
31
31
  "typing-extensions >= 4.14.1, < 5",
32
32
  "frequenz-microgrid-component-graph >= 0.3.4, < 0.4",
33
- "frequenz-client-assets >= 0.2.0, < 0.3",
33
+ "frequenz-client-assets >= 0.3.0, < 0.4",
34
34
  ]
35
35
  dynamic = ["version"]
36
36
 
@@ -56,21 +56,21 @@ dev-flake8 = [
56
56
  ]
57
57
  dev-formatting = ["black == 25.11.0", "isort == 7.0.0"]
58
58
  dev-mkdocs = [
59
- "Markdown == 3.10",
59
+ "Markdown == 3.10.2",
60
60
  "black == 25.11.0",
61
61
  "mike == 2.1.3",
62
62
  "mkdocs-gen-files == 0.5.0",
63
63
  "mkdocs-literate-nav == 0.6.2",
64
64
  "mkdocs-macros-plugin == 1.5.0",
65
- "mkdocs-material == 9.7.1",
66
- "mkdocstrings[python] == 1.0.1",
65
+ "mkdocs-material == 9.7.3",
66
+ "mkdocstrings[python] == 1.0.3",
67
67
  "mkdocstrings-python == 1.19.0",
68
68
  "frequenz-repo-config[lib] == 0.13.7",
69
69
  ]
70
70
  dev-mypy = [
71
71
  "mypy == 1.19.1",
72
72
  "types-networkx>=3.6.1.20251220",
73
- "types-Markdown == 3.10.0.20251106",
73
+ "types-Markdown == 3.10.2.20260211",
74
74
  # For checking the noxfile, docs/ script, and tests
75
75
  "frequenz-gridpool[dev-mkdocs,dev-noxfile,dev-pytest]",
76
76
  ]
@@ -85,7 +85,7 @@ dev-pylint = [
85
85
  ]
86
86
  dev-pytest = [
87
87
  "pytest == 9.0.2",
88
- "pylint == 4.0.4", # We need this to check for the examples
88
+ "pylint == 4.0.5", # We need this to check for the examples
89
89
  "frequenz-repo-config[extra-lint-examples] == 0.13.7",
90
90
  "pytest-mock == 3.15.1",
91
91
  "pytest-asyncio == 1.3.0",
@@ -3,8 +3,6 @@
3
3
 
4
4
  """Formula generation from assets API component/connection configurations."""
5
5
 
6
- from typing import cast
7
-
8
6
  from frequenz.client.assets import AssetsApiClient
9
7
  from frequenz.client.assets.electrical_component import (
10
8
  ComponentConnection,
@@ -61,6 +59,6 @@ class ComponentGraphGenerator:
61
59
 
62
60
  graph = ComponentGraph[
63
61
  ElectricalComponent, ComponentConnection, ElectricalComponentId
64
- ](components, cast(list[ComponentConnection], connections))
62
+ ](components, connections)
65
63
 
66
64
  return graph
@@ -10,9 +10,13 @@ from dataclasses import field
10
10
  from pathlib import Path
11
11
  from typing import Any, ClassVar, Literal, Self, Type, cast, get_args
12
12
 
13
+ from frequenz.client.assets import AssetsApiClient
14
+ from frequenz.client.common.microgrid import MicrogridId
13
15
  from marshmallow import Schema
14
16
  from marshmallow_dataclass import dataclass
15
17
 
18
+ from ._graph_generator import ComponentGraphGenerator
19
+
16
20
  _logger = logging.getLogger(__name__)
17
21
 
18
22
  ComponentType = Literal["grid", "pv", "battery", "consumption", "chp", "ev"]
@@ -47,15 +51,16 @@ class ComponentTypeConfig:
47
51
  "please use 'AC_POWER_ACTIVE' instead."
48
52
  )
49
53
 
50
- if "AC_POWER_ACTIVE" not in self.formula:
51
- if "AC_ACTIVE_POWER" in self.formula:
52
- self.formula["AC_POWER_ACTIVE"] = self.formula["AC_ACTIVE_POWER"]
53
- else:
54
- _logger.warning(
55
- "ComponentTypeConfig: No formula provided for 'AC_POWER_ACTIVE', "
56
- "using default summation formula."
57
- )
58
- self.formula["AC_POWER_ACTIVE"] = "+".join(
54
+ defaults = {
55
+ "AC_POWER_ACTIVE",
56
+ "AC_ENERGY_ACTIVE",
57
+ "AC_ENERGY_ACTIVE_CONSUMED",
58
+ "AC_ENERGY_ACTIVE_DELIVERED",
59
+ }
60
+
61
+ for metric in defaults:
62
+ if metric not in self.formula:
63
+ self.formula[metric] = "+".join(
59
64
  [f"#{cid}" for cid in self._default_cids()]
60
65
  )
61
66
 
@@ -401,3 +406,126 @@ class MicrogridConfig:
401
406
  microgrid_configs.update({str(key): value for key, value in mcfgs.items()})
402
407
 
403
408
  return microgrid_configs
409
+
410
+ @staticmethod
411
+ async def load_configs_with_formulas(
412
+ assets_url: str,
413
+ assets_auth_key: str,
414
+ assets_sign_secret: str,
415
+ microgrid_config_files: str | Path | list[str | Path] | None = None,
416
+ microgrid_config_dir: str | Path | None = None,
417
+ ) -> dict[str, "MicrogridConfig"]:
418
+ """Load microgrid configurations and ensure formulas are populated.
419
+
420
+ Loads microgrid configuration files and enriches them with automatically
421
+ generated formulas obtained from the Assets API. Missing formulas are filled
422
+ using the component graph generator while preserving any formulas already
423
+ defined in the configuration.
424
+
425
+ Args:
426
+ assets_url:
427
+ Base URL of the Assets API.
428
+ assets_auth_key:
429
+ Authentication key used to access the Assets API.
430
+ assets_sign_secret:
431
+ Signing secret used for authenticated API requests.
432
+ microgrid_config_files:
433
+ Optional path or list of paths to individual microgrid configuration
434
+ files.
435
+ microgrid_config_dir:
436
+ Optional directory containing microgrid configuration files.
437
+
438
+ Returns:
439
+ dict[str, MicrogridConfig]:
440
+ Mapping from microgrid ID (as string) to the corresponding populated
441
+ ``MicrogridConfig`` instance.
442
+
443
+ Notes:
444
+ - Configuration files are first loaded via ``MicrogridConfig.load_configs``.
445
+ - Any missing formulas are populated by querying the Assets API and
446
+ generating formulas from the microgrid component graph.
447
+ """
448
+ microgrid_configs = MicrogridConfig.load_configs(
449
+ microgrid_config_files=microgrid_config_files,
450
+ microgrid_config_dir=microgrid_config_dir,
451
+ )
452
+
453
+ async with AssetsApiClient(
454
+ assets_url, auth_key=assets_auth_key, sign_secret=assets_sign_secret
455
+ ) as assets_client:
456
+ for microgrid_id, config in microgrid_configs.items():
457
+ await populate_missing_formulas(
458
+ microgrid_id=int(microgrid_id),
459
+ config=config,
460
+ assets_client=assets_client,
461
+ )
462
+
463
+ return microgrid_configs
464
+
465
+
466
+ async def populate_missing_formulas(
467
+ microgrid_id: int,
468
+ config: "MicrogridConfig",
469
+ assets_client: AssetsApiClient,
470
+ ) -> None:
471
+ """Populate missing component formulas from the assets API graph.
472
+
473
+ Builds a component graph for the given microgrid and derives default formulas
474
+ for common component types such as consumption, generation, grid, PV, battery,
475
+ CHP, and EV charging. Existing formulas already present in the configuration
476
+ are preserved; only missing component-type entries or missing metric formulas
477
+ are filled in.
478
+
479
+ Args:
480
+ microgrid_id:
481
+ Identifier of the microgrid whose component graph should be used to
482
+ derive formulas.
483
+ config:
484
+ Microgrid configuration object to update in place.
485
+ assets_client:
486
+ Assets API client used to fetch the component graph.
487
+
488
+ Returns:
489
+ None. The configuration is modified in place.
490
+
491
+ Notes:
492
+ - Existing formulas in ``config`` are never overwritten.
493
+ - For missing component types, a new ``ComponentTypeConfig`` is created.
494
+ - The same derived formula is assigned to all supported metric keys for a
495
+ given component type when missing.
496
+ """
497
+ cgg = ComponentGraphGenerator(assets_client)
498
+ graph = await cgg.get_component_graph(MicrogridId(microgrid_id))
499
+
500
+ auto_formulas = {
501
+ "consumption": graph.consumer_formula(),
502
+ "generation": graph.producer_formula(),
503
+ "grid": graph.grid_formula(),
504
+ "pv": graph.pv_formula(None),
505
+ "battery": graph.battery_formula(None),
506
+ "chp": graph.chp_formula(None),
507
+ "ev": graph.ev_charger_formula(None),
508
+ }
509
+
510
+ metrics = (
511
+ "AC_POWER_ACTIVE",
512
+ "AC_ACTIVE_POWER",
513
+ "AC_ENERGY_ACTIVE",
514
+ "AC_ENERGY_ACTIVE_CONSUMED",
515
+ "AC_ENERGY_ACTIVE_DELIVERED",
516
+ )
517
+
518
+ for ctype, formula in auto_formulas.items():
519
+ cfg = config.ctype.get(ctype)
520
+ if cfg is None:
521
+ config.ctype[ctype] = ComponentTypeConfig(
522
+ formula={metric: formula for metric in metrics}
523
+ )
524
+ continue
525
+
526
+ if cfg.formula is None:
527
+ cfg.formula = {}
528
+
529
+ for metric in metrics:
530
+ if metric not in cfg.formula:
531
+ cfg.formula[metric] = formula
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: frequenz-gridpool
3
- Version: 0.3.1
3
+ Version: 0.4.0
4
4
  Summary: High-level interface to grid pools for the Frequenz platform.
5
5
  Author-email: Frequenz Energy-as-a-Service GmbH <floss@frequenz.com>
6
6
  License: MIT
@@ -24,7 +24,7 @@ Requires-Dist: marshmallow-dataclass<9,>=8.7.1
24
24
  Requires-Dist: asyncclick<9,>=8.3.0.4
25
25
  Requires-Dist: typing-extensions<5,>=4.14.1
26
26
  Requires-Dist: frequenz-microgrid-component-graph<0.4,>=0.3.4
27
- Requires-Dist: frequenz-client-assets<0.3,>=0.2.0
27
+ Requires-Dist: frequenz-client-assets<0.4,>=0.3.0
28
28
  Provides-Extra: render-graph
29
29
  Requires-Dist: matplotlib<4,>=3.7.0; extra == "render-graph"
30
30
  Requires-Dist: networkx<4,>=3.0; extra == "render-graph"
@@ -38,20 +38,20 @@ Provides-Extra: dev-formatting
38
38
  Requires-Dist: black==25.11.0; extra == "dev-formatting"
39
39
  Requires-Dist: isort==7.0.0; extra == "dev-formatting"
40
40
  Provides-Extra: dev-mkdocs
41
- Requires-Dist: Markdown==3.10; extra == "dev-mkdocs"
41
+ Requires-Dist: Markdown==3.10.2; extra == "dev-mkdocs"
42
42
  Requires-Dist: black==25.11.0; extra == "dev-mkdocs"
43
43
  Requires-Dist: mike==2.1.3; extra == "dev-mkdocs"
44
44
  Requires-Dist: mkdocs-gen-files==0.5.0; extra == "dev-mkdocs"
45
45
  Requires-Dist: mkdocs-literate-nav==0.6.2; extra == "dev-mkdocs"
46
46
  Requires-Dist: mkdocs-macros-plugin==1.5.0; extra == "dev-mkdocs"
47
- Requires-Dist: mkdocs-material==9.7.1; extra == "dev-mkdocs"
48
- Requires-Dist: mkdocstrings[python]==1.0.1; extra == "dev-mkdocs"
47
+ Requires-Dist: mkdocs-material==9.7.3; extra == "dev-mkdocs"
48
+ Requires-Dist: mkdocstrings[python]==1.0.3; extra == "dev-mkdocs"
49
49
  Requires-Dist: mkdocstrings-python==1.19.0; extra == "dev-mkdocs"
50
50
  Requires-Dist: frequenz-repo-config[lib]==0.13.7; extra == "dev-mkdocs"
51
51
  Provides-Extra: dev-mypy
52
52
  Requires-Dist: mypy==1.19.1; extra == "dev-mypy"
53
53
  Requires-Dist: types-networkx>=3.6.1.20251220; extra == "dev-mypy"
54
- Requires-Dist: types-Markdown==3.10.0.20251106; extra == "dev-mypy"
54
+ Requires-Dist: types-Markdown==3.10.2.20260211; extra == "dev-mypy"
55
55
  Requires-Dist: frequenz-gridpool[dev-mkdocs,dev-noxfile,dev-pytest]; extra == "dev-mypy"
56
56
  Provides-Extra: dev-noxfile
57
57
  Requires-Dist: nox==2025.11.12; extra == "dev-noxfile"
@@ -60,7 +60,7 @@ Provides-Extra: dev-pylint
60
60
  Requires-Dist: frequenz-gridpool[dev-mkdocs,dev-noxfile,dev-pytest]; extra == "dev-pylint"
61
61
  Provides-Extra: dev-pytest
62
62
  Requires-Dist: pytest==9.0.2; extra == "dev-pytest"
63
- Requires-Dist: pylint==4.0.4; extra == "dev-pytest"
63
+ Requires-Dist: pylint==4.0.5; extra == "dev-pytest"
64
64
  Requires-Dist: frequenz-repo-config[extra-lint-examples]==0.13.7; extra == "dev-pytest"
65
65
  Requires-Dist: pytest-mock==3.15.1; extra == "dev-pytest"
66
66
  Requires-Dist: pytest-asyncio==1.3.0; extra == "dev-pytest"
@@ -2,7 +2,7 @@ marshmallow-dataclass<9,>=8.7.1
2
2
  asyncclick<9,>=8.3.0.4
3
3
  typing-extensions<5,>=4.14.1
4
4
  frequenz-microgrid-component-graph<0.4,>=0.3.4
5
- frequenz-client-assets<0.3,>=0.2.0
5
+ frequenz-client-assets<0.4,>=0.3.0
6
6
 
7
7
  [dev]
8
8
  frequenz-gridpool[dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest,render-graph]
@@ -19,21 +19,21 @@ black==25.11.0
19
19
  isort==7.0.0
20
20
 
21
21
  [dev-mkdocs]
22
- Markdown==3.10
22
+ Markdown==3.10.2
23
23
  black==25.11.0
24
24
  mike==2.1.3
25
25
  mkdocs-gen-files==0.5.0
26
26
  mkdocs-literate-nav==0.6.2
27
27
  mkdocs-macros-plugin==1.5.0
28
- mkdocs-material==9.7.1
29
- mkdocstrings[python]==1.0.1
28
+ mkdocs-material==9.7.3
29
+ mkdocstrings[python]==1.0.3
30
30
  mkdocstrings-python==1.19.0
31
31
  frequenz-repo-config[lib]==0.13.7
32
32
 
33
33
  [dev-mypy]
34
34
  mypy==1.19.1
35
35
  types-networkx>=3.6.1.20251220
36
- types-Markdown==3.10.0.20251106
36
+ types-Markdown==3.10.2.20260211
37
37
  frequenz-gridpool[dev-mkdocs,dev-noxfile,dev-pytest]
38
38
 
39
39
  [dev-noxfile]
@@ -45,7 +45,7 @@ frequenz-gridpool[dev-mkdocs,dev-noxfile,dev-pytest]
45
45
 
46
46
  [dev-pytest]
47
47
  pytest==9.0.2
48
- pylint==4.0.4
48
+ pylint==4.0.5
49
49
  frequenz-repo-config[extra-lint-examples]==0.13.7
50
50
  pytest-mock==3.15.1
51
51
  pytest-asyncio==1.3.0
@@ -1,19 +0,0 @@
1
- # Frequenz Gridpool Library Release Notes
2
-
3
- ## Summary
4
-
5
- <!-- Here goes a general summary of what this release is about -->
6
-
7
- ## Upgrading
8
-
9
- * The minimum required version of `frequenz-microgrid-component-graph` is now `v0.3.4`.
10
-
11
- ## New Features
12
-
13
- * Added `gridpool-cli render-graph` to visualize microgrid component graphs using the
14
- Assets API credentials (`ASSETS_API_URL`, `ASSETS_API_AUTH_KEY`, and
15
- `ASSETS_API_SIGN_SECRET`).
16
-
17
- ## Bug Fixes
18
-
19
- - Fixed component graph rendering so children follow the vertical order of their parents, keeping upper-level branches above lower ones in the layered layout.