Skip to content

Commit 976b6c9

Browse files
Update the timeout type in power Request
The power Request is at least exposed through power Result in BatteryPool. Using timedelta offers improved code readability, time unit handling, making it a more reliable choice for working with time intervals. Signed-off-by: Daniel Zullo <[email protected]>
1 parent 791c6cd commit 976b6c9

File tree

5 files changed

+46
-44
lines changed

5 files changed

+46
-44
lines changed

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class PowerDistributingActor(Actor):
9898
9999
It is recommended to wait for PowerDistributingActor output with timeout. Otherwise if
100100
the processing function fails then the response will never come.
101-
The timeout should be Result:request_timeout_sec + time for processing the request.
101+
The timeout should be Result:request_timeout + time for processing the request.
102102
103103
Edge cases:
104104
* If there are 2 requests to be processed for the same subset of batteries, then
@@ -285,7 +285,7 @@ async def _run(self) -> None:
285285
)
286286

287287
failed_power, failed_batteries = await self._set_distributed_power(
288-
api, distribution, request.request_timeout_sec
288+
api, distribution, request.request_timeout
289289
)
290290

291291
response: Success | PartialFailure
@@ -321,14 +321,14 @@ async def _set_distributed_power(
321321
self,
322322
api: MicrogridApiClient,
323323
distribution: DistributionResult,
324-
timeout_sec: float,
324+
timeout: timedelta,
325325
) -> Tuple[float, Set[int]]:
326326
"""Send distributed power to the inverters.
327327
328328
Args:
329329
api: Microgrid api client
330330
distribution: Distribution result
331-
timeout_sec: How long wait for the response
331+
timeout: How long wait for the response
332332
333333
Returns:
334334
Tuple where first element is total failed power, and the second element
@@ -341,13 +341,13 @@ async def _set_distributed_power(
341341

342342
_, pending = await asyncio.wait(
343343
tasks.values(),
344-
timeout=timeout_sec,
344+
timeout=timeout.total_seconds(),
345345
return_when=ALL_COMPLETED,
346346
)
347347

348348
await self._cancel_tasks(pending)
349349

350-
return self._parse_result(tasks, distribution.distribution, timeout_sec)
350+
return self._parse_result(tasks, distribution.distribution, timeout)
351351

352352
def _get_power_distribution(
353353
self, request: Request, inv_bat_pairs: List[InvBatPair]
@@ -632,7 +632,7 @@ def _parse_result(
632632
self,
633633
tasks: Dict[int, asyncio.Task[None]],
634634
distribution: Dict[int, float],
635-
request_timeout_sec: float,
635+
request_timeout: timedelta,
636636
) -> Tuple[float, Set[int]]:
637637
"""Parse the results of `set_power` requests.
638638
@@ -644,7 +644,7 @@ def _parse_result(
644644
set the power for this inverter. Each task should be finished or cancelled.
645645
distribution: A dictionary where the key is the inverter ID and the value is how much
646646
power was set to the corresponding inverter.
647-
request_timeout_sec: The timeout that was used for the request.
647+
request_timeout: The timeout that was used for the request.
648648
649649
Returns:
650650
A tuple where the first element is the total failed power, and the second element is
@@ -678,7 +678,7 @@ def _parse_result(
678678
_logger.warning(
679679
"Battery %d didn't respond in %f sec. Mark it as broken.",
680680
battery_id,
681-
request_timeout_sec,
681+
request_timeout.total_seconds(),
682682
)
683683

684684
return failed_power, failed_batteries

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import dataclasses
88
from collections import abc
9+
from datetime import timedelta
910

1011

1112
@dataclasses.dataclass
@@ -25,7 +26,7 @@ class Request:
2526
batteries: abc.Set[int]
2627
"""The component ids of the batteries to be used for this request."""
2728

28-
request_timeout_sec: float = 5.0
29+
request_timeout: timedelta = timedelta(seconds=5.0)
2930
"""The maximum amount of time to wait for the request to be fulfilled."""
3031

3132
adjust_power: bool = True

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ async def set_power(
146146
power=power.as_watts(),
147147
batteries=self._batteries,
148148
adjust_power=adjust_power,
149-
request_timeout_sec=request_timeout.total_seconds(),
149+
request_timeout=request_timeout,
150150
include_broken_batteries=include_broken_batteries,
151151
)
152152
)
@@ -193,7 +193,7 @@ async def charge(
193193
power=as_watts,
194194
batteries=self._batteries,
195195
adjust_power=adjust_power,
196-
request_timeout_sec=request_timeout.total_seconds(),
196+
request_timeout=request_timeout,
197197
include_broken_batteries=include_broken_batteries,
198198
)
199199
)
@@ -240,7 +240,7 @@ async def discharge(
240240
power=-as_watts,
241241
batteries=self._batteries,
242242
adjust_power=adjust_power,
243-
request_timeout_sec=request_timeout.total_seconds(),
243+
request_timeout=request_timeout,
244244
include_broken_batteries=include_broken_batteries,
245245
)
246246
)

tests/actor/power_distributing/test_power_distributing.py

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ async def test_power_distributor_one_user(self, mocker: MockerFixture) -> None:
114114
namespace=self._namespace,
115115
power=1200.0,
116116
batteries={9, 19},
117-
request_timeout_sec=SAFETY_TIMEOUT,
117+
request_timeout=SAFETY_TIMEOUT,
118118
)
119119

120120
attrs = {"get_working_batteries.return_value": request.batteries}
@@ -135,7 +135,7 @@ async def test_power_distributor_one_user(self, mocker: MockerFixture) -> None:
135135

136136
done, pending = await asyncio.wait(
137137
[asyncio.create_task(result_rx.receive())],
138-
timeout=SAFETY_TIMEOUT,
138+
timeout=SAFETY_TIMEOUT.total_seconds(),
139139
)
140140

141141
assert len(pending) == 0
@@ -196,15 +196,15 @@ async def test_power_distributor_exclusion_bounds(
196196
namespace=self._namespace,
197197
power=0.0,
198198
batteries={9, 19},
199-
request_timeout_sec=SAFETY_TIMEOUT,
199+
request_timeout=SAFETY_TIMEOUT,
200200
)
201201

202202
await channel.new_sender().send(request)
203203
result_rx = channel_registry.new_receiver(self._namespace)
204204

205205
done, pending = await asyncio.wait(
206206
[asyncio.create_task(result_rx.receive())],
207-
timeout=SAFETY_TIMEOUT,
207+
timeout=SAFETY_TIMEOUT.total_seconds(),
208208
)
209209

210210
assert len(pending) == 0
@@ -222,15 +222,15 @@ async def test_power_distributor_exclusion_bounds(
222222
namespace=self._namespace,
223223
power=300.0,
224224
batteries={9, 19},
225-
request_timeout_sec=SAFETY_TIMEOUT,
225+
request_timeout=SAFETY_TIMEOUT,
226226
)
227227

228228
await channel.new_sender().send(request)
229229
result_rx = channel_registry.new_receiver(self._namespace)
230230

231231
done, pending = await asyncio.wait(
232232
[asyncio.create_task(result_rx.receive())],
233-
timeout=SAFETY_TIMEOUT,
233+
timeout=SAFETY_TIMEOUT.total_seconds(),
234234
)
235235

236236
assert len(pending) == 0
@@ -264,7 +264,7 @@ async def test_battery_soc_nan(self, mocker: MockerFixture) -> None:
264264
namespace=self._namespace,
265265
power=1200.0,
266266
batteries={9, 19},
267-
request_timeout_sec=SAFETY_TIMEOUT,
267+
request_timeout=SAFETY_TIMEOUT,
268268
)
269269

270270
attrs = {"get_working_batteries.return_value": request.batteries}
@@ -291,7 +291,7 @@ async def test_battery_soc_nan(self, mocker: MockerFixture) -> None:
291291

292292
done, pending = await asyncio.wait(
293293
[asyncio.create_task(result_rx.receive())],
294-
timeout=SAFETY_TIMEOUT,
294+
timeout=SAFETY_TIMEOUT.total_seconds(),
295295
)
296296

297297
assert len(pending) == 0
@@ -327,7 +327,7 @@ async def test_battery_capacity_nan(self, mocker: MockerFixture) -> None:
327327
namespace=self._namespace,
328328
power=1200.0,
329329
batteries={9, 19},
330-
request_timeout_sec=SAFETY_TIMEOUT,
330+
request_timeout=SAFETY_TIMEOUT,
331331
)
332332
attrs = {"get_working_batteries.return_value": request.batteries}
333333
mocker.patch(
@@ -347,7 +347,7 @@ async def test_battery_capacity_nan(self, mocker: MockerFixture) -> None:
347347

348348
done, pending = await asyncio.wait(
349349
[asyncio.create_task(result_rx.receive())],
350-
timeout=SAFETY_TIMEOUT,
350+
timeout=SAFETY_TIMEOUT.total_seconds(),
351351
)
352352

353353
assert len(pending) == 0
@@ -399,7 +399,7 @@ async def test_battery_power_bounds_nan(self, mocker: MockerFixture) -> None:
399399
namespace=self._namespace,
400400
power=1200.0,
401401
batteries={9, 19},
402-
request_timeout_sec=SAFETY_TIMEOUT,
402+
request_timeout=SAFETY_TIMEOUT,
403403
)
404404
attrs = {"get_working_batteries.return_value": request.batteries}
405405
mocker.patch(
@@ -419,7 +419,7 @@ async def test_battery_power_bounds_nan(self, mocker: MockerFixture) -> None:
419419

420420
done, pending = await asyncio.wait(
421421
[asyncio.create_task(result_rx.receive())],
422-
timeout=SAFETY_TIMEOUT,
422+
timeout=SAFETY_TIMEOUT.total_seconds(),
423423
)
424424

425425
assert len(pending) == 0
@@ -447,7 +447,7 @@ async def test_power_distributor_invalid_battery_id(
447447
namespace=self._namespace,
448448
power=1200.0,
449449
batteries={9, 100},
450-
request_timeout_sec=SAFETY_TIMEOUT,
450+
request_timeout=SAFETY_TIMEOUT,
451451
)
452452

453453
attrs = {"get_working_batteries.return_value": request.batteries}
@@ -468,7 +468,7 @@ async def test_power_distributor_invalid_battery_id(
468468

469469
done, _ = await asyncio.wait(
470470
[asyncio.create_task(result_rx.receive())],
471-
timeout=SAFETY_TIMEOUT,
471+
timeout=SAFETY_TIMEOUT.total_seconds(),
472472
)
473473

474474
assert len(done) == 1
@@ -494,7 +494,7 @@ async def test_power_distributor_one_user_adjust_power_consume(
494494
namespace=self._namespace,
495495
power=1200.0,
496496
batteries={9, 19},
497-
request_timeout_sec=SAFETY_TIMEOUT,
497+
request_timeout=SAFETY_TIMEOUT,
498498
adjust_power=False,
499499
)
500500

@@ -517,7 +517,7 @@ async def test_power_distributor_one_user_adjust_power_consume(
517517

518518
done, pending = await asyncio.wait(
519519
[asyncio.create_task(result_rx.receive())],
520-
timeout=SAFETY_TIMEOUT,
520+
timeout=SAFETY_TIMEOUT.total_seconds(),
521521
)
522522

523523
assert len(pending) == 0
@@ -545,7 +545,7 @@ async def test_power_distributor_one_user_adjust_power_supply(
545545
namespace=self._namespace,
546546
power=-1200.0,
547547
batteries={9, 19},
548-
request_timeout_sec=SAFETY_TIMEOUT,
548+
request_timeout=SAFETY_TIMEOUT,
549549
adjust_power=False,
550550
)
551551

@@ -568,7 +568,7 @@ async def test_power_distributor_one_user_adjust_power_supply(
568568

569569
done, pending = await asyncio.wait(
570570
[asyncio.create_task(result_rx.receive())],
571-
timeout=SAFETY_TIMEOUT,
571+
timeout=SAFETY_TIMEOUT.total_seconds(),
572572
)
573573

574574
assert len(pending) == 0
@@ -596,7 +596,7 @@ async def test_power_distributor_one_user_adjust_power_success(
596596
namespace=self._namespace,
597597
power=1000.0,
598598
batteries={9, 19},
599-
request_timeout_sec=SAFETY_TIMEOUT,
599+
request_timeout=SAFETY_TIMEOUT,
600600
adjust_power=False,
601601
)
602602

@@ -619,7 +619,7 @@ async def test_power_distributor_one_user_adjust_power_success(
619619

620620
done, pending = await asyncio.wait(
621621
[asyncio.create_task(result_rx.receive())],
622-
timeout=SAFETY_TIMEOUT,
622+
timeout=SAFETY_TIMEOUT.total_seconds(),
623623
)
624624

625625
assert len(pending) == 0
@@ -660,15 +660,15 @@ async def test_not_all_batteries_are_working(self, mocker: MockerFixture) -> Non
660660
namespace=self._namespace,
661661
power=1200.0,
662662
batteries=batteries,
663-
request_timeout_sec=SAFETY_TIMEOUT,
663+
request_timeout=SAFETY_TIMEOUT,
664664
)
665665

666666
await channel.new_sender().send(request)
667667
result_rx = channel_registry.new_receiver(self._namespace)
668668

669669
done, pending = await asyncio.wait(
670670
[asyncio.create_task(result_rx.receive())],
671-
timeout=SAFETY_TIMEOUT,
671+
timeout=SAFETY_TIMEOUT.total_seconds(),
672672
)
673673

674674
assert len(pending) == 0
@@ -709,7 +709,7 @@ async def test_use_all_batteries_none_is_working(
709709
namespace=self._namespace,
710710
power=1200.0,
711711
batteries={9, 19},
712-
request_timeout_sec=SAFETY_TIMEOUT,
712+
request_timeout=SAFETY_TIMEOUT,
713713
include_broken_batteries=True,
714714
)
715715

@@ -718,7 +718,7 @@ async def test_use_all_batteries_none_is_working(
718718

719719
done, pending = await asyncio.wait(
720720
[asyncio.create_task(result_rx.receive())],
721-
timeout=SAFETY_TIMEOUT,
721+
timeout=SAFETY_TIMEOUT.total_seconds(),
722722
)
723723

724724
assert len(pending) == 0
@@ -761,7 +761,7 @@ async def test_force_request_a_battery_is_not_working(
761761
namespace=self._namespace,
762762
power=1200.0,
763763
batteries=batteries,
764-
request_timeout_sec=SAFETY_TIMEOUT,
764+
request_timeout=SAFETY_TIMEOUT,
765765
include_broken_batteries=True,
766766
)
767767

@@ -770,7 +770,7 @@ async def test_force_request_a_battery_is_not_working(
770770

771771
done, pending = await asyncio.wait(
772772
[asyncio.create_task(result_rx.receive())],
773-
timeout=SAFETY_TIMEOUT,
773+
timeout=SAFETY_TIMEOUT.total_seconds(),
774774
)
775775

776776
assert len(pending) == 0
@@ -814,7 +814,7 @@ async def test_force_request_battery_nan_value_non_cached(
814814
namespace=self._namespace,
815815
power=1200.0,
816816
batteries=batteries,
817-
request_timeout_sec=SAFETY_TIMEOUT,
817+
request_timeout=SAFETY_TIMEOUT,
818818
include_broken_batteries=True,
819819
)
820820

@@ -841,7 +841,7 @@ async def test_force_request_battery_nan_value_non_cached(
841841

842842
done, pending = await asyncio.wait(
843843
[asyncio.create_task(result_rx.receive())],
844-
timeout=SAFETY_TIMEOUT,
844+
timeout=SAFETY_TIMEOUT.total_seconds(),
845845
)
846846

847847
assert len(pending) == 0
@@ -884,7 +884,7 @@ async def test_force_request_batteries_nan_values_cached(
884884
namespace=self._namespace,
885885
power=1200.0,
886886
batteries=batteries,
887-
request_timeout_sec=SAFETY_TIMEOUT,
887+
request_timeout=SAFETY_TIMEOUT,
888888
include_broken_batteries=True,
889889
)
890890

@@ -893,7 +893,7 @@ async def test_force_request_batteries_nan_values_cached(
893893
async def test_result() -> None:
894894
done, pending = await asyncio.wait(
895895
[asyncio.create_task(result_rx.receive())],
896-
timeout=SAFETY_TIMEOUT,
896+
timeout=SAFETY_TIMEOUT.total_seconds(),
897897
)
898898
assert len(pending) == 0
899899
assert len(done) == 1

0 commit comments

Comments
 (0)