Skip to content

Commit f80505d

Browse files
feat: refactor config file arguments of mg data and mg config classes
The `load_configs` static method has been refactored to offer a more flexible and explicit way of providing configuration files. Previously, the method accepted a *paths argument. The signature has been changed to now accept two distinct optional parameters: * The first argument accepts a single configuration file or a list of files. * The second argument accepts a directory. For both parameters, inputs can be provided as either String or Path objects. It is mandatory to provide at least one of these arguments. The `MicrogridConfig` class will attempt to load all specified configuration files although the content of the loaded configuration files is not yet validated. The `MicrogridData` class now accepts a dict of `MicrogridConfigs` as returned by `MicrogridData.load_configs` instead of a path. Signed-off-by: Matthias Wende <[email protected]>
1 parent 8706709 commit f80505d

File tree

2 files changed

+63
-18
lines changed

2 files changed

+63
-18
lines changed

src/frequenz/data/microgrid/component_data.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,20 @@ def __init__(
2424
server_url: str,
2525
auth_key: str,
2626
sign_secret: str,
27-
microgrid_config_path: str | list[str],
27+
microgrid_configs: dict[str, MicrogridConfig] | None = None,
2828
) -> None:
2929
"""Initialize microgrid data.
3030
3131
Args:
3232
server_url: URL of the reporting service.
3333
auth_key: Authentication key to the service.
3434
sign_secret: Secret for signing requests.
35-
microgrid_config_path: Path(s) to the config file with microgrid components.
36-
37-
Raises:
38-
ValueError: If no microgrid config path is provided.
35+
microgrid_configs: MicrogridConfig dict mapping microgrid IDs to MicrogridConfigs.
3936
"""
37+
self._microgrid_configs = microgrid_configs
4038
self._client = ReportingApiClient(
4139
server_url=server_url, auth_key=auth_key, sign_secret=sign_secret
4240
)
43-
paths = (
44-
[microgrid_config_path]
45-
if isinstance(microgrid_config_path, str)
46-
else microgrid_config_path
47-
)
48-
if len(paths) < 1:
49-
raise ValueError("At least one microgrid config path must be provided")
50-
self._microgrid_configs = MicrogridConfig.load_configs(*paths)
5141

5242
@property
5343
def microgrid_ids(self) -> list[str]:
@@ -98,6 +88,8 @@ async def metric_data( # pylint: disable=too-many-arguments
9888
ctype: mcfg.formula(ctype, metric.upper()) for ctype in component_types
9989
}
10090

91+
logging.debug("Formulas: %s", formulas)
92+
10193
metric_enum = Metric[metric.upper()]
10294
data = [
10395
sample

src/frequenz/data/microgrid/config.py

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33

44
"""Configuration for microgrids."""
55

6+
import logging
67
import re
78
import tomllib
89
from dataclasses import dataclass
10+
from pathlib import Path
911
from typing import Any, Literal, cast, get_args
1012

13+
_logger = logging.getLogger(__name__)
14+
1115
ComponentType = Literal["grid", "pv", "battery", "consumption", "chp", "ev"]
1216
"""Valid component types."""
1317

@@ -286,22 +290,71 @@ def formula(self, component_type: str, metric: str) -> str:
286290
return formula
287291

288292
@staticmethod
289-
def load_configs(*paths: str) -> dict[str, "MicrogridConfig"]:
293+
def load_configs(
294+
microgrid_config_files: str | Path | list[str | Path] | None = None,
295+
microgrid_config_dir: str | Path | None = None,
296+
) -> dict[str, "MicrogridConfig"]:
290297
"""Load multiple microgrid configurations from a file.
291298
292299
Configs for a single microgrid are expected to be in a single file.
293300
Later files with the same microgrid ID will overwrite the previous configs.
294301
295302
Args:
296-
*paths: Path(es) to the config file(s).
303+
microgrid_config_files: Path to a single microgrid config file or list of paths.
304+
microgrid_config_dir: Directory containing multiple microgrid config files.
297305
298306
Returns:
299307
Dictionary of single microgrid formula configs with microgrid IDs as keys.
308+
309+
Raises:
310+
ValueError: If no config files or dir is provided, or if no config files are found.
300311
"""
301-
microgrid_configs = {}
302-
for config_path in paths:
303-
with open(config_path, "rb") as f:
312+
if microgrid_config_files is None and microgrid_config_dir is None:
313+
raise ValueError(
314+
"No microgrid config path or directory provided. "
315+
"Please provide at least one."
316+
)
317+
318+
config_files: list[Path] = []
319+
320+
if microgrid_config_files:
321+
if isinstance(microgrid_config_files, str):
322+
config_files = [Path(microgrid_config_files)]
323+
elif isinstance(microgrid_config_files, Path):
324+
config_files = [microgrid_config_files]
325+
elif isinstance(microgrid_config_files, list):
326+
config_files = [Path(f) for f in microgrid_config_files]
327+
328+
if microgrid_config_dir:
329+
if Path(microgrid_config_dir).is_dir():
330+
config_files += list(Path(microgrid_config_dir).glob("*.toml"))
331+
else:
332+
raise ValueError(
333+
f"Microgrid config directory {microgrid_config_dir} "
334+
"is not a directory"
335+
)
336+
337+
if len(config_files) == 0:
338+
raise ValueError(
339+
"No microgrid config files found. "
340+
"Please provide at least one valid config file."
341+
)
342+
343+
microgrid_configs: dict[str, "MicrogridConfig"] = {}
344+
345+
for config_path in config_files:
346+
if not config_path.is_file():
347+
_logger.warning("Config path %s is not a file, skipping.", config_path)
348+
continue
349+
350+
with config_path.open("rb") as f:
304351
cfg_dict = tomllib.load(f)
305352
for microgrid_id, mcfg in cfg_dict.items():
353+
_logger.debug(
354+
"Loading microgrid config for ID %s from %s",
355+
microgrid_id,
356+
config_path,
357+
)
306358
microgrid_configs[microgrid_id] = MicrogridConfig(mcfg)
359+
307360
return microgrid_configs

0 commit comments

Comments
 (0)