Skip to content

Commit cf75848

Browse files
authored
Fix reactive power retrieval (#927)
The data sourcing actor needs to know about the new metric. This commit exposes it, adds a trivial test and updates the release notes to do a hotfix right after this is merged.
2 parents 57337df + d560032 commit cf75848

File tree

3 files changed

+39
-39
lines changed

3 files changed

+39
-39
lines changed

RELEASE_NOTES.md

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,5 @@
11
# Frequenz Python SDK Release Notes
22

3-
## Summary
4-
5-
The most notable features for this release is the addition of the `PVPool` (exposed via `microgrid.pv_pool()`), which can be used to manage PV arrays as a single entity and the `EVChargerPool` (`microgrid.ev_charger_pool()`) learning to manage power for the whole pool (before it could only be used to control chargers individually).
6-
7-
Another notable change is the microgrid API client being moved to its own [repository](https://github.com/frequenz-floss/frequenz-client-microgrid-python/).
8-
9-
## Upgrading
10-
11-
- The SDK is now using the microgrid API client from [`frequenz-client-microgrid`](https://github.com/frequenz-floss/frequenz-client-microgrid-python/). You should update your code if you are using the microgrid API client directly.
12-
13-
- The minimum required `frequenz-channels` version is now [`v1.0.0-rc1`](https://github.com/frequenz-floss/frequenz-channels-python/releases/tag/v1.0.0-rc.1).
14-
15-
- The set of battery IDs managed by a battery pool are now available through `BatteryPool.component_ids`, and no longer through `BatteryPool.battery_ids`. This is done to have a consistent interface with other `*Pool`s.
16-
17-
- The `maxsize` parameter in calls to `BatteryPool.{soc/capacity/temperature}.new_receiver()` methods have now been renamed to `limit`, to be consistent with the channels repository.
18-
19-
- Support for per-component interaction in `EVChargerPool` has been removed. Please use the new `propose_power()` method to manage power for the whole pool. If you still need to manage power of chargers individually, you can create one pool per charger.
20-
21-
- PV power is now available from `microgrid.pv_pool().power`, and no longer from `microgrid.logical_meter().pv_power`.
22-
23-
## New Features
24-
25-
- `EVChargerPool`/`microgrid.ev_charger_pool()`: New `propose_power` and `power_status` methods have been added, similar to the `BatteryPool`. These method interface with the `PowerManager` and `PowerDistributor`, which currently uses a first-come-first-serve algorithm to distribute power to EVs.
26-
27-
- A PV pool (`PVPool`/`microgrid.pv_pool()`) was added, with `propose_power`, `power_status` and `power` methods similar to Battery and EV pools.
28-
29-
- The microgrid API client now exposes the reactive power for inverters, meters and EV chargers.
30-
31-
## Enhancements
32-
33-
- Warning messages are logged when multiple instances of `*Pool`s are created for the same set of batteries, with the same priority values.
34-
35-
- A warning message will now be logged if no relevant samples are found in a component for resampling.
36-
373
## Bug Fixes
384

39-
- A bug was fixed where the grid fuse was not created properly and would end up with a `max_current` with type `float` instead of `Current`.
40-
41-
- `BatteryPool.propose_discharge` now converts power values to the passive-sign convention. Earlier it was not doing this and that was causing it to charge instead of discharge.
42-
43-
- Fix a bug that was causing the power managing actor to crash and restart when cleaning up old proposals.
5+
- Fix getting reactive power from meters, inverters and EV chargers.

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@
3838
ComponentMetricId.VOLTAGE_PHASE_2: lambda msg: msg.voltage_per_phase[1],
3939
ComponentMetricId.VOLTAGE_PHASE_3: lambda msg: msg.voltage_per_phase[2],
4040
ComponentMetricId.FREQUENCY: lambda msg: msg.frequency,
41+
ComponentMetricId.REACTIVE_POWER: lambda msg: msg.reactive_power,
42+
ComponentMetricId.REACTIVE_POWER_PHASE_1: lambda msg: msg.reactive_power_per_phase[
43+
0
44+
],
45+
ComponentMetricId.REACTIVE_POWER_PHASE_2: lambda msg: msg.reactive_power_per_phase[
46+
1
47+
],
48+
ComponentMetricId.REACTIVE_POWER_PHASE_3: lambda msg: msg.reactive_power_per_phase[
49+
2
50+
],
4151
}
4252

4353
_BatteryDataMethods: dict[ComponentMetricId, Callable[[BatteryData], float]] = {
@@ -84,6 +94,16 @@
8494
ComponentMetricId.VOLTAGE_PHASE_2: lambda msg: msg.voltage_per_phase[1],
8595
ComponentMetricId.VOLTAGE_PHASE_3: lambda msg: msg.voltage_per_phase[2],
8696
ComponentMetricId.FREQUENCY: lambda msg: msg.frequency,
97+
ComponentMetricId.REACTIVE_POWER: lambda msg: msg.reactive_power,
98+
ComponentMetricId.REACTIVE_POWER_PHASE_1: lambda msg: msg.reactive_power_per_phase[
99+
0
100+
],
101+
ComponentMetricId.REACTIVE_POWER_PHASE_2: lambda msg: msg.reactive_power_per_phase[
102+
1
103+
],
104+
ComponentMetricId.REACTIVE_POWER_PHASE_3: lambda msg: msg.reactive_power_per_phase[
105+
2
106+
],
87107
}
88108

89109
_EVChargerDataMethods: dict[ComponentMetricId, Callable[[EVChargerData], float]] = {
@@ -98,6 +118,16 @@
98118
ComponentMetricId.VOLTAGE_PHASE_2: lambda msg: msg.voltage_per_phase[1],
99119
ComponentMetricId.VOLTAGE_PHASE_3: lambda msg: msg.voltage_per_phase[2],
100120
ComponentMetricId.FREQUENCY: lambda msg: msg.frequency,
121+
ComponentMetricId.REACTIVE_POWER: lambda msg: msg.reactive_power,
122+
ComponentMetricId.REACTIVE_POWER_PHASE_1: lambda msg: msg.reactive_power_per_phase[
123+
0
124+
],
125+
ComponentMetricId.REACTIVE_POWER_PHASE_2: lambda msg: msg.reactive_power_per_phase[
126+
1
127+
],
128+
ComponentMetricId.REACTIVE_POWER_PHASE_3: lambda msg: msg.reactive_power_per_phase[
129+
2
130+
],
101131
}
102132

103133

tests/actor/test_data_sourcing.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ async def test_data_sourcing_actor(self) -> None:
6565
).new_receiver()
6666
await req_sender.send(active_power_request)
6767

68+
reactive_power_request = ComponentMetricRequest(
69+
"test-namespace", 4, ComponentMetricId.REACTIVE_POWER, None
70+
)
71+
reactive_power_recv = registry.get_or_create(
72+
Sample[Quantity], reactive_power_request.get_channel_name()
73+
).new_receiver()
74+
await req_sender.send(reactive_power_request)
75+
6876
soc_request = ComponentMetricRequest(
6977
"test-namespace", 9, ComponentMetricId.SOC, None
7078
)

0 commit comments

Comments
 (0)