Skip to content

Commit 44576d5

Browse files
Update power Request attribute to Power type
The power Request is exposed through the power distributing Result in the BatteryPool. Using the Power type enhances code clarity and flexibility, as it supports various power units, power arithmetic operations, and precise logging, which improves code readability and error prevention. Signed-off-by: Daniel Zullo <[email protected]>
1 parent 976b6c9 commit 44576d5

File tree

4 files changed

+35
-35
lines changed

4 files changed

+35
-35
lines changed

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,9 @@ async def _run(self) -> None:
273273
)
274274
continue
275275

276-
distributed_power_value = request.power - distribution.remaining_power
276+
distributed_power_value = (
277+
request.power.as_watts() - distribution.remaining_power
278+
)
277279
battery_distribution = {
278280
self._inv_bat_map[bat_id]: dist
279281
for bat_id, dist in distribution.distribution.items()
@@ -369,11 +371,11 @@ def _get_power_distribution(
369371

370372
if request.include_broken_batteries and not available_bat_ids:
371373
return self.distribution_algorithm.distribute_power_equally(
372-
request.power, unavailable_inv_ids
374+
request.power.as_watts(), unavailable_inv_ids
373375
)
374376

375377
result = self.distribution_algorithm.distribute_power(
376-
request.power, inv_bat_pairs
378+
request.power.as_watts(), inv_bat_pairs
377379
)
378380

379381
if request.include_broken_batteries and unavailable_inv_ids:
@@ -414,9 +416,11 @@ def _check_request(
414416

415417
bounds = self._get_bounds(pairs_data)
416418

419+
power = request.power.as_watts()
420+
417421
# Zero power requests are always forwarded to the microgrid API, even if they
418422
# are outside the exclusion bounds.
419-
if is_close_to_zero(request.power):
423+
if is_close_to_zero(power):
420424
return None
421425

422426
if request.adjust_power:
@@ -425,15 +429,11 @@ def _check_request(
425429
#
426430
# If the requested power is in the exclusion bounds, it is NOT possible to
427431
# increase it so that it is outside the exclusion bounds.
428-
if bounds.exclusion_lower < request.power < bounds.exclusion_upper:
432+
if bounds.exclusion_lower < power < bounds.exclusion_upper:
429433
return OutOfBounds(request=request, bounds=bounds)
430434
else:
431-
in_lower_range = (
432-
bounds.inclusion_lower <= request.power <= bounds.exclusion_lower
433-
)
434-
in_upper_range = (
435-
bounds.exclusion_upper <= request.power <= bounds.inclusion_upper
436-
)
435+
in_lower_range = bounds.inclusion_lower <= power <= bounds.exclusion_lower
436+
in_upper_range = bounds.exclusion_upper <= power <= bounds.inclusion_upper
437437
if not (in_lower_range or in_upper_range):
438438
return OutOfBounds(request=request, bounds=bounds)
439439

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from collections import abc
99
from datetime import timedelta
1010

11+
from ...timeseries._quantities import Power
12+
1113

1214
@dataclasses.dataclass
1315
class Request:
@@ -20,8 +22,8 @@ class Request:
2022
channel registry.
2123
"""
2224

23-
power: float
24-
"""The requested power in watts."""
25+
power: Power
26+
"""The requested power."""
2527

2628
batteries: abc.Set[int]
2729
"""The component ids of the batteries to be used for this request."""

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

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ async def set_power(
143143
await self._power_distributing_sender.send(
144144
Request(
145145
namespace=self._power_distributing_namespace,
146-
power=power.as_watts(),
146+
power=power,
147147
batteries=self._batteries,
148148
adjust_power=adjust_power,
149149
request_timeout=request_timeout,
@@ -184,13 +184,12 @@ async def charge(
184184
Raises:
185185
ValueError: If the given power is negative.
186186
"""
187-
as_watts = power.as_watts()
188-
if as_watts < 0.0:
187+
if power < Power.zero():
189188
raise ValueError("Charge power must be positive.")
190189
await self._power_distributing_sender.send(
191190
Request(
192191
namespace=self._power_distributing_namespace,
193-
power=as_watts,
192+
power=power,
194193
batteries=self._batteries,
195194
adjust_power=adjust_power,
196195
request_timeout=request_timeout,
@@ -231,13 +230,12 @@ async def discharge(
231230
Raises:
232231
ValueError: If the given power is negative.
233232
"""
234-
as_watts = power.as_watts()
235-
if as_watts < 0.0:
233+
if power < Power.zero():
236234
raise ValueError("Discharge power must be positive.")
237235
await self._power_distributing_sender.send(
238236
Request(
239237
namespace=self._power_distributing_namespace,
240-
power=-as_watts,
238+
power=-power,
241239
batteries=self._batteries,
242240
adjust_power=adjust_power,
243241
request_timeout=request_timeout,

tests/actor/power_distributing/test_power_distributing.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ async def test_power_distributor_one_user(self, mocker: MockerFixture) -> None:
112112

113113
request = Request(
114114
namespace=self._namespace,
115-
power=1200.0,
115+
power=Power.from_kilowatts(1.2),
116116
batteries={9, 19},
117117
request_timeout=SAFETY_TIMEOUT,
118118
)
@@ -194,7 +194,7 @@ async def test_power_distributor_exclusion_bounds(
194194
## zero power requests should pass through despite the exclusion bounds.
195195
request = Request(
196196
namespace=self._namespace,
197-
power=0.0,
197+
power=Power.zero(),
198198
batteries={9, 19},
199199
request_timeout=SAFETY_TIMEOUT,
200200
)
@@ -220,7 +220,7 @@ async def test_power_distributor_exclusion_bounds(
220220
## rejected.
221221
request = Request(
222222
namespace=self._namespace,
223-
power=300.0,
223+
power=Power.from_watts(300.0),
224224
batteries={9, 19},
225225
request_timeout=SAFETY_TIMEOUT,
226226
)
@@ -262,7 +262,7 @@ async def test_battery_soc_nan(self, mocker: MockerFixture) -> None:
262262

263263
request = Request(
264264
namespace=self._namespace,
265-
power=1200.0,
265+
power=Power.from_kilowatts(1.2),
266266
batteries={9, 19},
267267
request_timeout=SAFETY_TIMEOUT,
268268
)
@@ -325,7 +325,7 @@ async def test_battery_capacity_nan(self, mocker: MockerFixture) -> None:
325325

326326
request = Request(
327327
namespace=self._namespace,
328-
power=1200.0,
328+
power=Power.from_kilowatts(1.2),
329329
batteries={9, 19},
330330
request_timeout=SAFETY_TIMEOUT,
331331
)
@@ -397,7 +397,7 @@ async def test_battery_power_bounds_nan(self, mocker: MockerFixture) -> None:
397397

398398
request = Request(
399399
namespace=self._namespace,
400-
power=1200.0,
400+
power=Power.from_kilowatts(1.2),
401401
batteries={9, 19},
402402
request_timeout=SAFETY_TIMEOUT,
403403
)
@@ -445,7 +445,7 @@ async def test_power_distributor_invalid_battery_id(
445445
channel_registry = ChannelRegistry(name="power_distributor")
446446
request = Request(
447447
namespace=self._namespace,
448-
power=1200.0,
448+
power=Power.from_kilowatts(1.2),
449449
batteries={9, 100},
450450
request_timeout=SAFETY_TIMEOUT,
451451
)
@@ -492,7 +492,7 @@ async def test_power_distributor_one_user_adjust_power_consume(
492492

493493
request = Request(
494494
namespace=self._namespace,
495-
power=1200.0,
495+
power=Power.from_kilowatts(1.2),
496496
batteries={9, 19},
497497
request_timeout=SAFETY_TIMEOUT,
498498
adjust_power=False,
@@ -543,7 +543,7 @@ async def test_power_distributor_one_user_adjust_power_supply(
543543

544544
request = Request(
545545
namespace=self._namespace,
546-
power=-1200.0,
546+
power=-Power.from_kilowatts(1.2),
547547
batteries={9, 19},
548548
request_timeout=SAFETY_TIMEOUT,
549549
adjust_power=False,
@@ -594,7 +594,7 @@ async def test_power_distributor_one_user_adjust_power_success(
594594

595595
request = Request(
596596
namespace=self._namespace,
597-
power=1000.0,
597+
power=Power.from_kilowatts(1.0),
598598
batteries={9, 19},
599599
request_timeout=SAFETY_TIMEOUT,
600600
adjust_power=False,
@@ -658,7 +658,7 @@ async def test_not_all_batteries_are_working(self, mocker: MockerFixture) -> Non
658658
):
659659
request = Request(
660660
namespace=self._namespace,
661-
power=1200.0,
661+
power=Power.from_kilowatts(1.2),
662662
batteries=batteries,
663663
request_timeout=SAFETY_TIMEOUT,
664664
)
@@ -707,7 +707,7 @@ async def test_use_all_batteries_none_is_working(
707707
):
708708
request = Request(
709709
namespace=self._namespace,
710-
power=1200.0,
710+
power=Power.from_kilowatts(1.2),
711711
batteries={9, 19},
712712
request_timeout=SAFETY_TIMEOUT,
713713
include_broken_batteries=True,
@@ -759,7 +759,7 @@ async def test_force_request_a_battery_is_not_working(
759759
):
760760
request = Request(
761761
namespace=self._namespace,
762-
power=1200.0,
762+
power=Power.from_kilowatts(1.2),
763763
batteries=batteries,
764764
request_timeout=SAFETY_TIMEOUT,
765765
include_broken_batteries=True,
@@ -812,7 +812,7 @@ async def test_force_request_battery_nan_value_non_cached(
812812
):
813813
request = Request(
814814
namespace=self._namespace,
815-
power=1200.0,
815+
power=Power.from_kilowatts(1.2),
816816
batteries=batteries,
817817
request_timeout=SAFETY_TIMEOUT,
818818
include_broken_batteries=True,
@@ -882,7 +882,7 @@ async def test_force_request_batteries_nan_values_cached(
882882
):
883883
request = Request(
884884
namespace=self._namespace,
885-
power=1200.0,
885+
power=Power.from_kilowatts(1.2),
886886
batteries=batteries,
887887
request_timeout=SAFETY_TIMEOUT,
888888
include_broken_batteries=True,

0 commit comments

Comments
 (0)