Skip to content

Commit 7f04fd9

Browse files
Change BatteryPool to send metrics only when they change (#254)
We compared the metric result but with timestamp. Because timestamps were different comparison was always True. Exclude timestamp to not it in the comparison methods. Remove Sample from the metric result types, because we don't return any Sample metric now and it is not consistent with the rest the result types, now.
2 parents cddf2e3 + 6c6f9ee commit 7f04fd9

File tree

3 files changed

+22
-20
lines changed

3 files changed

+22
-20
lines changed

src/frequenz/sdk/timeseries/battery_pool/_metric_calculator.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
from ... import microgrid
1414
from ...microgrid.component import ComponentCategory, ComponentMetricId, InverterType
15-
from ...timeseries import Sample
1615
from ._component_metrics import ComponentMetricsData
1716
from ._result_types import Bound, CapacityMetrics, PowerMetrics, SoCMetrics
1817

@@ -59,7 +58,7 @@ def battery_inverter_mapping(batteries: Iterable[int]) -> dict[int, int]:
5958

6059
# Formula output types class have no common interface
6160
# Print all possible types here.
62-
T = TypeVar("T", Sample, SoCMetrics, CapacityMetrics, PowerMetrics)
61+
T = TypeVar("T", SoCMetrics, CapacityMetrics, PowerMetrics)
6362

6463

6564
class MetricCalculator(ABC, Generic[T]):

src/frequenz/sdk/timeseries/battery_pool/_result_types.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
"""Methods for processing battery-inverter data."""
55

6-
from dataclasses import dataclass
6+
from dataclasses import dataclass, field
77
from datetime import datetime
88

99

@@ -22,7 +22,8 @@ class Bound:
2222
class CapacityMetrics:
2323
"""Capacity metrics."""
2424

25-
timestamp: datetime
25+
# compare = False tells the dataclass to not use name for comparison methods
26+
timestamp: datetime = field(compare=False)
2627
"""Timestamp of the metrics,"""
2728

2829
total_capacity: float
@@ -53,7 +54,8 @@ class CapacityMetrics:
5354
class SoCMetrics:
5455
"""Soc metrics."""
5556

56-
timestamp: datetime
57+
# compare = False tells the dataclass to not use name for comparison methods
58+
timestamp: datetime = field(compare=False)
5759
"""Timestamp of the metrics."""
5860

5961
average_soc: float
@@ -91,7 +93,8 @@ class SoCMetrics:
9193
class PowerMetrics:
9294
"""Power bounds metrics."""
9395

94-
timestamp: datetime
96+
# compare = False tells the dataclass to not use name for comparison methods
97+
timestamp: datetime = field(compare=False)
9598
"""Timestamp of the metrics."""
9699

97100
supply_bound: Bound

tests/timeseries/_battery_pool/test_battery_pool.py

+14-14
Original file line numberDiff line numberDiff line change
@@ -509,12 +509,7 @@ async def run_capacity_test(setup_args: SetupArgs) -> None:
509509
),
510510
Scenario(
511511
batteries_in_pool[1],
512-
{"capacity": 200, "soc_lower_bound": float("NaN")},
513-
CapacityMetrics(now, 30, Bound(600, 2700)),
514-
),
515-
Scenario(
516-
batteries_in_pool[1],
517-
{"soc_lower_bound": 20},
512+
{"capacity": 200},
518513
CapacityMetrics(now, 230, Bound(4600, 20700)),
519514
),
520515
]
@@ -601,12 +596,7 @@ async def run_soc_test(setup_args: SetupArgs) -> None:
601596
scenarios: list[Scenario[SoCMetrics]] = [
602597
Scenario(
603598
batteries_in_pool[0],
604-
{"capacity": 150},
605-
SoCMetrics(now, 30, Bound(20, 80)),
606-
),
607-
Scenario(
608-
batteries_in_pool[0],
609-
{"soc": 10},
599+
{"capacity": 150, "soc": 10},
610600
SoCMetrics(now, 15, Bound(20, 80)),
611601
),
612602
Scenario(
@@ -631,10 +621,12 @@ async def run_soc_test(setup_args: SetupArgs) -> None:
631621
{"soc": 30},
632622
SoCMetrics(now, 30, Bound(20, 80)),
633623
),
624+
# Final metric didn't change, so nothing should be received.
634625
Scenario(
635626
batteries_in_pool[0],
636627
{"capacity": 0, "soc_lower_bound": 10, "soc_upper_bound": 100},
637-
SoCMetrics(now, 30, Bound(20, 80)),
628+
None,
629+
wait_for_result=False,
638630
),
639631
# Test zero division error
640632
Scenario(
@@ -788,13 +780,21 @@ async def run_power_bounds_test( # pylint: disable=too-many-locals
788780
{"power_lower_bound": float("NaN")},
789781
PowerMetrics(now, Bound(-10, 0), Bound(0, 200)),
790782
),
783+
Scenario(
784+
batteries_in_pool[1],
785+
{
786+
"power_lower_bound": -100,
787+
"power_upper_bound": float("NaN"),
788+
},
789+
PowerMetrics(now, Bound(-100, 0), Bound(0, 6000)),
790+
),
791791
Scenario(
792792
bat_inv_map[batteries_in_pool[1]],
793793
{
794794
"active_power_lower_bound": float("NaN"),
795795
"active_power_upper_bound": float("NaN"),
796796
},
797-
PowerMetrics(now, Bound(-10, 0), Bound(0, 200)),
797+
PowerMetrics(now, Bound(-100, 0), Bound(0, 0)),
798798
),
799799
# All components are sending NaN, can't calculate bounds
800800
Scenario(

0 commit comments

Comments
 (0)