-
Notifications
You must be signed in to change notification settings - Fork 2
Implement a ComponentGraphGenerator from the assets API
#16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v0.x.x
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,7 +15,6 @@ description = "High-level interface to grid pools for the Frequenz platform." | |
| readme = "README.md" | ||
| license = { text = "MIT" } | ||
| keywords = ["frequenz", "python", "lib", "library", "gridpool"] | ||
| # TODO(cookiecutter): Remove and add more classifiers if appropriate | ||
| classifiers = [ | ||
| "Development Status :: 3 - Alpha", | ||
| "Intended Audience :: Developers", | ||
|
|
@@ -26,17 +25,17 @@ classifiers = [ | |
| "Typing :: Typed", | ||
| ] | ||
| requires-python = ">= 3.11, < 4" | ||
| # TODO(cookiecutter): Remove and add more dependencies if appropriate | ||
| dependencies = [ | ||
| "typing-extensions >= 4.14.1, < 5", | ||
| "frequenz-microgrid-component-graph @ git+https://github.com/shsms/frequenz-microgrid-component-graph-python.git@c4a458e06e541846de0a25142d5b821dd7934f47", | ||
| "frequenz-client-assets @ git+https://github.com/shsms/frequenz-client-assets-python@bbf09104df24ddfac497e2a3dd66fe68cfdacd25" | ||
| ] | ||
| dynamic = ["version"] | ||
|
|
||
| [[project.authors]] | ||
| name = "Frequenz Energy-as-a-Service GmbH" | ||
| email = "[email protected]" | ||
|
|
||
| # TODO(cookiecutter): Remove and add more optional dependencies if appropriate | ||
| [project.optional-dependencies] | ||
| dev-flake8 = [ | ||
| "flake8 == 7.3.0", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,25 +1,8 @@ | ||
| # License: MIT | ||
| # Copyright © 2025 Frequenz Energy-as-a-Service GmbH | ||
|
|
||
| """High-level interface to grid pools for the Frequenz platform.. | ||
| """High-level interface to grid pools for the Frequenz platform.""" | ||
|
|
||
| TODO(cookiecutter): Add a more descriptive module description. | ||
| """ | ||
| from ._graph_generator import ComponentGraphGenerator | ||
|
|
||
|
|
||
| # TODO(cookiecutter): Remove this function | ||
| def delete_me(*, blow_up: bool = False) -> bool: | ||
| """Do stuff for demonstration purposes. | ||
|
|
||
| Args: | ||
| blow_up: If True, raise an exception. | ||
|
|
||
| Returns: | ||
| True if no exception was raised. | ||
|
|
||
| Raises: | ||
| RuntimeError: if blow_up is True. | ||
| """ | ||
| if blow_up: | ||
| raise RuntimeError("This function should be removed!") | ||
| return True | ||
| __all__ = ["ComponentGraphGenerator"] |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,90 @@ | ||||||
| # License: MIT | ||||||
| # Copyright © 2025 Frequenz Energy-as-a-Service GmbH | ||||||
|
|
||||||
| """Formula generation from assets API component/connection configurations.""" | ||||||
|
|
||||||
| from typing import cast | ||||||
|
|
||||||
| from frequenz.client.assets import AssetsApiClient | ||||||
| from frequenz.client.assets.electrical_component import ( | ||||||
| ComponentConnection, | ||||||
| ElectricalComponent, | ||||||
| ) | ||||||
| from frequenz.client.base import channel | ||||||
| from frequenz.client.common.microgrid import MicrogridId | ||||||
| from frequenz.client.common.microgrid.electrical_components import ElectricalComponentId | ||||||
| from frequenz.microgrid_component_graph import ComponentGraph | ||||||
|
|
||||||
|
|
||||||
| class ComponentGraphGenerator: | ||||||
| """Generates component graphs for microgrids using the Assets API.""" | ||||||
|
|
||||||
| def __init__( # pylint: disable=too-many-arguments | ||||||
| self, | ||||||
| server_url: str, | ||||||
| *, | ||||||
| auth_key: str | None = None, | ||||||
| sign_secret: str | None = None, | ||||||
| channel_defaults: channel.ChannelOptions = channel.ChannelOptions(), | ||||||
| connect: bool = True, | ||||||
| ) -> None: | ||||||
| """Initialize this instance. | ||||||
| Args: | ||||||
| server_url: The location of the microgrid API server in the form of a URL. | ||||||
| The following format is expected: | ||||||
| "grpc://hostname{:`port`}{?ssl=`ssl`}", | ||||||
| where the `port` should be an int between 0 and 65535 (defaulting to | ||||||
| 9090) and `ssl` should be a boolean (defaulting to `true`). | ||||||
| For example: `grpc://localhost:1090?ssl=true`. | ||||||
| auth_key: The authentication key to use for the connection. | ||||||
| sign_secret: The secret to use for signing requests. | ||||||
| channel_defaults: The default options use to create the channel when not | ||||||
|
||||||
| channel_defaults: The default options use to create the channel when not | |
| channel_defaults: The default options used to create the channel when not |
Copilot
AI
Nov 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The None check at line 83 is unnecessary since the type hint indicates list_microgrid_electrical_component_connections returns a list of connections, not optional connections. If None values are genuinely possible, the type hints should reflect this. Consider removing this check or updating the type hints for clarity.
| if any(c is None for c in connections): | |
| raise ValueError("Failed to load all electrical component connections.") |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -2,17 +2,66 @@ | |||||
| # Copyright © 2025 Frequenz Energy-as-a-Service GmbH | ||||||
|
|
||||||
| """Tests for the frequenz.gridpool package.""" | ||||||
| import pytest | ||||||
|
|
||||||
| from frequenz.gridpool import delete_me | ||||||
| from unittest.mock import AsyncMock, MagicMock, patch | ||||||
|
|
||||||
| from frequenz.client.assets import AssetsApiClient | ||||||
| from frequenz.client.assets.electrical_component import ( | ||||||
| ComponentConnection, | ||||||
| GridConnectionPoint, | ||||||
| Meter, | ||||||
| SolarInverter, | ||||||
| ) | ||||||
| from frequenz.client.common.microgrid import MicrogridId | ||||||
| from frequenz.client.common.microgrid.electrical_components import ElectricalComponentId | ||||||
|
|
||||||
| def test_gridpool_succeeds() -> None: # TODO(cookiecutter): Remove | ||||||
| """Test that the delete_me function succeeds.""" | ||||||
| assert delete_me() is True | ||||||
| from frequenz.gridpool._graph_generator import ComponentGraphGenerator | ||||||
|
|
||||||
|
|
||||||
| def test_gridpool_fails() -> None: # TODO(cookiecutter): Remove | ||||||
| """Test that the delete_me function fails.""" | ||||||
| with pytest.raises(RuntimeError, match="This function should be removed!"): | ||||||
| delete_me(blow_up=True) | ||||||
| async def test_formula_generation() -> None: | ||||||
| """Test that the frequenz.gridpool package loads correctly.""" | ||||||
|
||||||
| """Test that the frequenz.gridpool package loads correctly.""" | |
| """Test formula generation from component graph.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Missing trailing comma after the last dependency. For consistency and easier future modifications, add a trailing comma.