Skip to content

Commit be64e00

Browse files
committed
Use inclusion bounds to replace older bounds fields
Support for exclusion bounds will be added separately. Signed-off-by: Sahas Subramanian <[email protected]>
1 parent 74a9b92 commit be64e00

File tree

8 files changed

+76
-59
lines changed

8 files changed

+76
-59
lines changed

src/frequenz/sdk/actor/_data_sourcing/microgrid_api_source.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,23 @@ def get_channel_name(self) -> str:
8282
ComponentMetricId.SOC_LOWER_BOUND: lambda msg: msg.soc_lower_bound,
8383
ComponentMetricId.SOC_UPPER_BOUND: lambda msg: msg.soc_upper_bound,
8484
ComponentMetricId.CAPACITY: lambda msg: msg.capacity,
85-
ComponentMetricId.POWER_LOWER_BOUND: lambda msg: msg.power_lower_bound,
86-
ComponentMetricId.POWER_UPPER_BOUND: lambda msg: msg.power_upper_bound,
85+
ComponentMetricId.POWER_INCLUSION_LOWER_BOUND: lambda msg: (
86+
msg.power_inclusion_lower_bound
87+
),
88+
ComponentMetricId.POWER_INCLUSION_UPPER_BOUND: lambda msg: (
89+
msg.power_inclusion_upper_bound
90+
),
8791
ComponentMetricId.TEMPERATURE: lambda msg: msg.temperature,
8892
}
8993

9094
_InverterDataMethods: Dict[ComponentMetricId, Callable[[InverterData], float]] = {
9195
ComponentMetricId.ACTIVE_POWER: lambda msg: msg.active_power,
92-
ComponentMetricId.ACTIVE_POWER_LOWER_BOUND: lambda msg: msg.active_power_lower_bound,
93-
ComponentMetricId.ACTIVE_POWER_UPPER_BOUND: lambda msg: msg.active_power_upper_bound,
96+
ComponentMetricId.ACTIVE_POWER_INCLUSION_LOWER_BOUND: lambda msg: (
97+
msg.active_power_inclusion_lower_bound
98+
),
99+
ComponentMetricId.ACTIVE_POWER_INCLUSION_UPPER_BOUND: lambda msg: (
100+
msg.active_power_inclusion_upper_bound
101+
),
94102
}
95103

96104
_EVChargerDataMethods: Dict[ComponentMetricId, Callable[[EVChargerData], float]] = {

src/frequenz/sdk/actor/power_distributing/power_distributing.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,10 @@ def _get_upper_bound(self, batteries: abc.Set[int], include_broken: bool) -> flo
244244
batteries, include_broken
245245
)
246246
return sum(
247-
min(battery.power_upper_bound, inverter.active_power_upper_bound)
247+
min(
248+
battery.power_inclusion_upper_bound,
249+
inverter.active_power_inclusion_upper_bound,
250+
)
248251
for battery, inverter in pairs_data
249252
)
250253

@@ -266,7 +269,10 @@ def _get_lower_bound(self, batteries: abc.Set[int], include_broken: bool) -> flo
266269
batteries, include_broken
267270
)
268271
return sum(
269-
max(battery.power_lower_bound, inverter.active_power_lower_bound)
272+
max(
273+
battery.power_inclusion_lower_bound,
274+
inverter.active_power_inclusion_lower_bound,
275+
)
270276
for battery, inverter in pairs_data
271277
)
272278

@@ -622,10 +628,10 @@ def _get_battery_inverter_data(
622628
return None
623629

624630
replaceable_metrics = [
625-
battery_data.power_lower_bound,
626-
battery_data.power_upper_bound,
627-
inverter_data.active_power_lower_bound,
628-
inverter_data.active_power_upper_bound,
631+
battery_data.power_inclusion_lower_bound,
632+
battery_data.power_inclusion_upper_bound,
633+
inverter_data.active_power_inclusion_lower_bound,
634+
inverter_data.active_power_inclusion_upper_bound,
629635
]
630636

631637
# If all values are ok then return them.
@@ -637,8 +643,8 @@ def _get_battery_inverter_data(
637643
# Replace NaN with the corresponding value in the adjacent component.
638644
# If both metrics are None, return None to ignore this battery.
639645
replaceable_pairs = [
640-
("power_lower_bound", "active_power_lower_bound"),
641-
("power_upper_bound", "active_power_upper_bound"),
646+
("power_inclusion_lower_bound", "active_power_inclusion_lower_bound"),
647+
("power_inclusion_upper_bound", "active_power_inclusion_upper_bound"),
642648
]
643649

644650
battery_new_metrics = {}

src/frequenz/sdk/microgrid/component/_component.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,10 @@ class ComponentMetricId(Enum):
134134
SOC_UPPER_BOUND = "soc_upper_bound"
135135
CAPACITY = "capacity"
136136

137-
POWER_LOWER_BOUND = "power_lower_bound"
138-
POWER_UPPER_BOUND = "power_upper_bound"
137+
POWER_INCLUSION_LOWER_BOUND = "power_inclusion_lower_bound"
138+
POWER_INCLUSION_UPPER_BOUND = "power_inclusion_upper_bound"
139139

140-
ACTIVE_POWER_LOWER_BOUND = "active_power_lower_bound"
141-
ACTIVE_POWER_UPPER_BOUND = "active_power_upper_bound"
140+
ACTIVE_POWER_INCLUSION_LOWER_BOUND = "active_power_inclusion_lower_bound"
141+
ACTIVE_POWER_INCLUSION_UPPER_BOUND = "active_power_inclusion_upper_bound"
142142

143143
TEMPERATURE = "temperature"

src/frequenz/sdk/power/_distribution_algorithm.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -490,8 +490,8 @@ def _distribute_consume_power(
490490
bounds: Dict[int, float] = {}
491491
for battery, inverter in components:
492492
# We can supply/consume with int only
493-
inverter_bound = inverter.active_power_upper_bound
494-
battery_bound = battery.power_upper_bound
493+
inverter_bound = inverter.active_power_inclusion_upper_bound
494+
battery_bound = battery.power_inclusion_upper_bound
495495
bounds[inverter.component_id] = min(inverter_bound, battery_bound)
496496

497497
result: DistributionResult = self._distribute_power(
@@ -528,8 +528,8 @@ def _distribute_supply_power(
528528
bounds: Dict[int, float] = {}
529529
for battery, inverter in components:
530530
# We can consume with int only
531-
inverter_bound = inverter.active_power_lower_bound
532-
battery_bound = battery.power_lower_bound
531+
inverter_bound = inverter.active_power_inclusion_lower_bound
532+
battery_bound = battery.power_inclusion_lower_bound
533533
bounds[inverter.component_id] = -1 * max(inverter_bound, battery_bound)
534534

535535
result: DistributionResult = self._distribute_power(

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -478,13 +478,13 @@ def __init__(
478478

479479
super().__init__(used_batteries)
480480
self._battery_metrics = [
481-
ComponentMetricId.POWER_LOWER_BOUND,
482-
ComponentMetricId.POWER_UPPER_BOUND,
481+
ComponentMetricId.POWER_INCLUSION_LOWER_BOUND,
482+
ComponentMetricId.POWER_INCLUSION_UPPER_BOUND,
483483
]
484484

485485
self._inverter_metrics = [
486-
ComponentMetricId.ACTIVE_POWER_LOWER_BOUND,
487-
ComponentMetricId.ACTIVE_POWER_UPPER_BOUND,
486+
ComponentMetricId.ACTIVE_POWER_INCLUSION_LOWER_BOUND,
487+
ComponentMetricId.ACTIVE_POWER_INCLUSION_UPPER_BOUND,
488488
]
489489

490490
@classmethod
@@ -550,12 +550,12 @@ def calculate(
550550

551551
# Consume and supply bounds are not related.
552552
# If one is missing, then we can still use the other.
553-
value = data.get(ComponentMetricId.POWER_UPPER_BOUND)
553+
value = data.get(ComponentMetricId.POWER_INCLUSION_UPPER_BOUND)
554554
if value is not None:
555555
result.timestamp = max(result.timestamp, data.timestamp)
556556
consume_upper_bounds.append(value)
557557

558-
value = data.get(ComponentMetricId.POWER_LOWER_BOUND)
558+
value = data.get(ComponentMetricId.POWER_INCLUSION_LOWER_BOUND)
559559
if value is not None:
560560
result.timestamp = max(result.timestamp, data.timestamp)
561561
supply_upper_bounds.append(value)
@@ -564,12 +564,12 @@ def calculate(
564564
if inverter_id in metrics_data:
565565
data = metrics_data[inverter_id]
566566

567-
value = data.get(ComponentMetricId.ACTIVE_POWER_UPPER_BOUND)
567+
value = data.get(ComponentMetricId.ACTIVE_POWER_INCLUSION_UPPER_BOUND)
568568
if value is not None:
569569
result.timestamp = max(data.timestamp, result.timestamp)
570570
consume_upper_bounds.append(value)
571571

572-
value = data.get(ComponentMetricId.ACTIVE_POWER_LOWER_BOUND)
572+
value = data.get(ComponentMetricId.ACTIVE_POWER_INCLUSION_LOWER_BOUND)
573573
if value is not None:
574574
result.timestamp = max(data.timestamp, result.timestamp)
575575
supply_upper_bounds.append(value)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class PowerMetrics:
3737
3838
supply_bound.lower = sum(
3939
max(
40-
battery.power_lower_bound, inverter.active_power_lower_bound)
40+
battery.power_inclusion_lower_bound, inverter.active_power_inclusion_lower_bound)
4141
for each working battery in battery pool
4242
)
4343
)
@@ -55,7 +55,7 @@ class PowerMetrics:
5555
5656
consume_bound.upper = sum(
5757
min(
58-
battery.power_upper_bound, inverter.active_power_upper_bound)
58+
battery.power_inclusion_upper_bound, inverter.active_power_inclusion_upper_bound)
5959
for each working battery in battery pool
6060
)
6161
)

tests/power/test_distribution_algorithm.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ def battery_msg( # pylint: disable=too-many-arguments
6767
soc=soc.now if soc.now is not None else math.nan,
6868
soc_lower_bound=soc.bound.lower if soc.bound is not None else math.nan,
6969
soc_upper_bound=soc.bound.upper if soc.bound is not None else math.nan,
70-
power_lower_bound=power.lower,
71-
power_upper_bound=power.upper,
70+
power_inclusion_lower_bound=power.lower,
71+
power_inclusion_upper_bound=power.upper,
7272
timestamp=timestamp,
7373
)
7474

@@ -92,8 +92,8 @@ def inverter_msg(
9292
return InverterDataWrapper(
9393
component_id=component_id,
9494
timestamp=timestamp,
95-
active_power_lower_bound=power.lower,
96-
active_power_upper_bound=power.upper,
95+
active_power_inclusion_lower_bound=power.lower,
96+
active_power_inclusion_upper_bound=power.upper,
9797
)
9898

9999

tests/timeseries/_battery_pool/test_battery_pool.py

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -829,17 +829,17 @@ async def run_power_bounds_test( # pylint: disable=too-many-locals
829829
BatteryDataWrapper(
830830
component_id=battery_id,
831831
timestamp=datetime.now(tz=timezone.utc),
832-
power_lower_bound=-1000,
833-
power_upper_bound=5000,
832+
power_inclusion_lower_bound=-1000,
833+
power_inclusion_upper_bound=5000,
834834
),
835835
sampling_rate=0.05,
836836
)
837837
streamer.start_streaming(
838838
InverterDataWrapper(
839839
component_id=inverter_id,
840840
timestamp=datetime.now(tz=timezone.utc),
841-
active_power_lower_bound=-900,
842-
active_power_upper_bound=6000,
841+
active_power_inclusion_lower_bound=-900,
842+
active_power_inclusion_upper_bound=6000,
843843
),
844844
sampling_rate=0.1,
845845
)
@@ -862,24 +862,24 @@ async def run_power_bounds_test( # pylint: disable=too-many-locals
862862
scenarios: list[Scenario[PowerMetrics]] = [
863863
Scenario(
864864
bat_inv_map[batteries_in_pool[0]],
865-
{"active_power_lower_bound": -100},
865+
{"active_power_inclusion_lower_bound": -100},
866866
PowerMetrics(now, Bound(-1000, 0), Bound(0, 10000)),
867867
),
868868
# Inverter bound changed, but metric result should not change.
869869
Scenario(
870870
component_id=bat_inv_map[batteries_in_pool[0]],
871-
new_metrics={"active_power_upper_bound": 9000},
871+
new_metrics={"active_power_inclusion_upper_bound": 9000},
872872
expected_result=None,
873873
wait_for_result=False,
874874
),
875875
Scenario(
876876
batteries_in_pool[0],
877-
{"power_lower_bound": 0, "power_upper_bound": 4000},
877+
{"power_inclusion_lower_bound": 0, "power_inclusion_upper_bound": 4000},
878878
PowerMetrics(now, Bound(-900, 0), Bound(0, 9000)),
879879
),
880880
Scenario(
881881
batteries_in_pool[1],
882-
{"power_lower_bound": -10, "power_upper_bound": 200},
882+
{"power_inclusion_lower_bound": -10, "power_inclusion_upper_bound": 200},
883883
PowerMetrics(now, Bound(-10, 0), Bound(0, 4200)),
884884
),
885885
# Test 2 things:
@@ -888,73 +888,76 @@ async def run_power_bounds_test( # pylint: disable=too-many-locals
888888
# Setting upper bound to NaN should not influence lower bound
889889
Scenario(
890890
batteries_in_pool[0],
891-
{"power_lower_bound": -50, "power_upper_bound": math.nan},
891+
{
892+
"power_inclusion_lower_bound": -50,
893+
"power_inclusion_upper_bound": math.nan,
894+
},
892895
PowerMetrics(now, Bound(-60, 0), Bound(0, 9200)),
893896
),
894897
Scenario(
895898
bat_inv_map[batteries_in_pool[0]],
896899
{
897-
"active_power_lower_bound": math.nan,
898-
"active_power_upper_bound": math.nan,
900+
"active_power_inclusion_lower_bound": math.nan,
901+
"active_power_inclusion_upper_bound": math.nan,
899902
},
900903
PowerMetrics(now, Bound(-60, 0), Bound(0, 200)),
901904
),
902905
Scenario(
903906
batteries_in_pool[0],
904-
{"power_lower_bound": math.nan},
907+
{"power_inclusion_lower_bound": math.nan},
905908
PowerMetrics(now, Bound(-10, 0), Bound(0, 200)),
906909
),
907910
Scenario(
908911
batteries_in_pool[1],
909912
{
910-
"power_lower_bound": -100,
911-
"power_upper_bound": math.nan,
913+
"power_inclusion_lower_bound": -100,
914+
"power_inclusion_upper_bound": math.nan,
912915
},
913916
PowerMetrics(now, Bound(-100, 0), Bound(0, 6000)),
914917
),
915918
Scenario(
916919
bat_inv_map[batteries_in_pool[1]],
917920
{
918-
"active_power_lower_bound": math.nan,
919-
"active_power_upper_bound": math.nan,
921+
"active_power_inclusion_lower_bound": math.nan,
922+
"active_power_inclusion_upper_bound": math.nan,
920923
},
921924
PowerMetrics(now, Bound(-100, 0), Bound(0, 0)),
922925
),
923926
# All components are sending NaN, can't calculate bounds
924927
Scenario(
925928
batteries_in_pool[1],
926929
{
927-
"power_lower_bound": math.nan,
928-
"power_upper_bound": math.nan,
930+
"power_inclusion_lower_bound": math.nan,
931+
"power_inclusion_upper_bound": math.nan,
929932
},
930933
None,
931934
),
932935
Scenario(
933936
batteries_in_pool[0],
934-
{"power_lower_bound": -100, "power_upper_bound": 100},
937+
{"power_inclusion_lower_bound": -100, "power_inclusion_upper_bound": 100},
935938
PowerMetrics(now, Bound(-100, 0), Bound(0, 100)),
936939
),
937940
Scenario(
938941
bat_inv_map[batteries_in_pool[1]],
939942
{
940-
"active_power_lower_bound": -400,
941-
"active_power_upper_bound": 400,
943+
"active_power_inclusion_lower_bound": -400,
944+
"active_power_inclusion_upper_bound": 400,
942945
},
943946
PowerMetrics(now, Bound(-500, 0), Bound(0, 500)),
944947
),
945948
Scenario(
946949
batteries_in_pool[1],
947950
{
948-
"power_lower_bound": -300,
949-
"power_upper_bound": 700,
951+
"power_inclusion_lower_bound": -300,
952+
"power_inclusion_upper_bound": 700,
950953
},
951954
PowerMetrics(now, Bound(-400, 0), Bound(0, 500)),
952955
),
953956
Scenario(
954957
bat_inv_map[batteries_in_pool[0]],
955958
{
956-
"active_power_lower_bound": -200,
957-
"active_power_upper_bound": 50,
959+
"active_power_inclusion_lower_bound": -200,
960+
"active_power_inclusion_upper_bound": 50,
958961
},
959962
PowerMetrics(now, Bound(-400, 0), Bound(0, 450)),
960963
),

0 commit comments

Comments
 (0)