diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f80f12e..e49f72e 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -6,10 +6,15 @@ ## Upgrading +* The CLI tool is moved to dedicated folder. + ## New Features +* Support data requests for multiple component IDs from command line. +* Support for passing formula strings as a `cid` argument from the command line. + ## Bug Fixes diff --git a/pyproject.toml b/pyproject.toml index 6a0a0f5..b1af7df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ dependencies = [ dynamic = ["version"] [project.scripts] -reporting-cli = "frequenz.client.reporting.__main__:main" +reporting-cli = "frequenz.client.reporting.cli.__main__:main" [[project.authors]] name = "Frequenz Energy-as-a-Service GmbH" diff --git a/src/frequenz/client/reporting/__main__.py b/src/frequenz/client/reporting/cli/__main__.py similarity index 81% rename from src/frequenz/client/reporting/__main__.py rename to src/frequenz/client/reporting/cli/__main__.py index b550341..22f9e65 100644 --- a/src/frequenz/client/reporting/__main__.py +++ b/src/frequenz/client/reporting/cli/__main__.py @@ -24,8 +24,18 @@ def main() -> None: help="URL of the Reporting service", default="localhost:50051", ) - parser.add_argument("--mid", type=int, help="Microgrid ID", required=True) - parser.add_argument("--cid", type=int, help="Component ID", required=True) + parser.add_argument( + "--mid", + type=int, + help="Microgrid ID", + required=True, + ) + parser.add_argument( + "--cid", + nargs="+", + type=str, + help="Component IDs or formulae", + ) parser.add_argument( "--metrics", type=str, @@ -97,7 +107,7 @@ def main() -> None: async def run( *, microgrid_id: int, - component_id: int, + component_id: list[str], metric_names: list[str], start_dt: datetime | None, end_dt: datetime | None, @@ -130,13 +140,17 @@ async def run( metrics = [Metric[mn] for mn in metric_names] - def data_iter() -> AsyncIterator[MetricSample]: + cids = [int(cid.strip()) for cid in component_id if cid.strip().isdigit()] + formulas = [cid.strip() for cid in component_id if not cid.strip().isdigit()] + microgrid_components = [(microgrid_id, cids)] + + async def data_iter() -> AsyncIterator[MetricSample]: """Iterate over single metric. Just a wrapper around the client method for readability. - Returns: - Iterator over single metric samples + Yields: + Single metric samples """ resampling_period = ( timedelta(seconds=resampling_period_s) @@ -144,16 +158,29 @@ def data_iter() -> AsyncIterator[MetricSample]: else None ) - return client.list_single_component_data( - microgrid_id=microgrid_id, - component_id=component_id, + async for sample in client.list_microgrid_components_data( + microgrid_components=microgrid_components, metrics=metrics, start_dt=start_dt, end_dt=end_dt, resampling_period=resampling_period, include_states=states, include_bounds=bounds, - ) + ): + yield sample + + for formula in formulas: + assert resampling_period is not None + for metric in metrics: + async for sample in client.receive_aggregated_data( + microgrid_id=microgrid_id, + metric=metric, + aggregation_formula=formula, + start=start_dt, + end=end_dt, + resampling_period=resampling_period, + ): + yield sample if fmt == "iter": # Iterate over single metric generator