Skip to content

Commit

Permalink
Add client example
Browse files Browse the repository at this point in the history
  • Loading branch information
cwasicki committed Mar 15, 2024
1 parent 66bf66a commit a4a0d71
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 0 deletions.
139 changes: 139 additions & 0 deletions examples/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# License: MIT
# Copyright © 2024 Frequenz Energy-as-a-Service GmbH

"""Examples usage of reporting API."""

import argparse
import asyncio
from datetime import datetime
from pprint import pprint
from typing import AsyncGenerator

import pandas as pd
from frequenz.client.common.metric import Metric

from frequenz.client.reporting import ReportingClient

# Experimental import
from frequenz.client.reporting._client import MetricSample


# pylint: disable=too-many-locals
async def main(microgrid_id: int, component_id: int) -> None:
"""Test the ReportingClient.
Args:
microgrid_id: int
component_id: int
"""
service_address = "localhost:50051"
client = ReportingClient(service_address)

microgrid_components = [(microgrid_id, [component_id])]
metrics = [
Metric.DC_POWER,
Metric.DC_CURRENT,
]

start_dt = datetime.fromisoformat("2023-11-21T12:00:00.00+00:00")
end_dt = datetime.fromisoformat("2023-11-21T12:01:00.00+00:00")

page_size = 10

print("########################################################")
print("Iterate over single metric generator")

async for sample in client.single_metric_iter(
microgrid_id=microgrid_id,
component_id=component_id,
metric=metrics[0],
start_dt=start_dt,
end_dt=end_dt,
page_size=page_size,
):
print("Received:", sample)

###########################################################################
#
# The following code is experimental and demonstrates potential future
# usage of the ReportingClient.
#
###########################################################################

async def components_data_iter() -> AsyncGenerator[MetricSample, None]:
"""Iterate over components data.
Yields:
Single metric sample
"""
# pylint: disable=protected-access
async for page in client._iterate_components_data_pages(
microgrid_components=microgrid_components,
metrics=metrics,
start_dt=start_dt,
end_dt=end_dt,
page_size=page_size,
):
for entry in page.iterate_metric_samples():
yield entry

async def components_data_dict(
components_data_iter: AsyncGenerator[MetricSample, None]
) -> dict[int, dict[int, dict[datetime, dict[Metric, float]]]]:
"""Convert components data iterator into a single dict.
The nesting structure is:
{
microgrid_id: {
component_id: {
timestamp: {
metric: value
}
}
}
}
Args:
components_data_iter: async generator
Returns:
Single dict with with all components data
"""
ret: dict[int, dict[int, dict[datetime, dict[Metric, float]]]] = {}

async for ts, mid, cid, met, value in components_data_iter:
if mid not in ret:
ret[mid] = {}
if cid not in ret[mid]:
ret[mid][cid] = {}
if ts not in ret[mid][cid]:
ret[mid][cid][ts] = {}

ret[mid][cid][ts][met] = value

return ret

print("########################################################")
print("Iterate over generator")
async for msample in components_data_iter():
print("Received:", msample)

print("########################################################")
print("Dumping all data as a single dict")
dct = await components_data_dict(components_data_iter())
pprint(dct)

print("########################################################")
print("Turn data into a pandas DataFrame")
data = [cd async for cd in components_data_iter()]
df = pd.DataFrame(data).set_index("timestamp")
pprint(df)


if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("microgrid_id", type=int, help="Microgrid ID")
parser.add_argument("component_id", type=int, help="Component ID")

args = parser.parse_args()
asyncio.run(main(args.microgrid_id, args.component_id))
6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ dev-mypy = [
"types-Markdown == 3.4.2.10",
# For checking the noxfile, docs/ script, and tests
"frequenz-client-reporting[dev-mkdocs,dev-noxfile,dev-pytest]",
"pandas-stubs >= 2, < 3", # Only required for example
]
dev-noxfile = [
"nox == 2023.4.22",
Expand All @@ -73,6 +74,7 @@ dev-pylint = [
"pylint == 3.0.2",
# For checking the noxfile, docs/ script, and tests
"frequenz-client-reporting[dev-mkdocs,dev-noxfile,dev-pytest]",
"pandas >= 2, < 3", # Only required for example
]
dev-pytest = [
"pytest == 8.0.0",
Expand All @@ -84,6 +86,10 @@ dev-pytest = [
dev = [
"frequenz-client-reporting[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]",
]
examples = [
"grpcio >= 1.51.1, < 2",
"pandas >= 2, < 3",
]

[project.urls]
Documentation = "https://frequenz-floss.github.io/frequenz-client-reporting-python/"
Expand Down

0 comments on commit a4a0d71

Please sign in to comment.