Skip to content

Commit 01c97c8

Browse files
authored
Improve docs for power manager algorithms (#1313)
2 parents afd91e2 + c73bf84 commit 01c97c8

File tree

2 files changed

+117
-62
lines changed

2 files changed

+117
-62
lines changed

RELEASE_NOTES.md

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

3-
## Bug Fixes
3+
## Summary
44

5-
- Doesn't repeat zero commands to battery inverters anymore, to not interfere with lower level logic that might want to do things only when there are no actors trying to use the batteries.
5+
This release improves the documentation for the implementation details of the power manager algorithms.

src/frequenz/sdk/microgrid/__init__.py

Lines changed: 115 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,11 @@
186186
method available for all pools, which also streams the bounds that an actor
187187
should comply with, based on its priority.
188188
189+
### Working with other actors to control Batteries
190+
191+
This section describes the details of the power manager's reconciliation
192+
algorithm for controlling batteries.
193+
189194
#### Adding the power proposals of individual actors
190195
191196
When an actor A calls the `propose_power` method with a power, the proposed
@@ -201,35 +206,39 @@
201206
202207
*Example 1*: Battery bounds available for use: -100kW to 100kW
203208
204-
| Actor | Priority | System Bounds | Requested Bounds | Requested | Adjusted | Aggregate |
205-
| | | | | Power | Power | Power |
206-
|-------|----------|-----------------|------------------|-----------|--------------|-----------|
207-
| A | 3 | -100kW .. 100kW | None | 20kW | 20kW | 20kW |
208-
| B | 2 | -120kW .. 80kW | None | 50kW | 50kW | 70kW |
209-
| C | 1 | -170kW .. 30kW | None | 50kW | 30kW | 100kW |
210-
| | | | | | target power | 100kW |
209+
| Actor | Priority | Available Bounds | Requested Bounds | Requested Power | Adjusted Power | Aggregate Power |
210+
|------:|---------:|-----------------:|-----------------:|----------------:|---------------:|----------------:|
211+
| A | 3 | -100kW .. 100kW | None | 20kW | 20kW | 20kW |
212+
| B | 2 | -120kW .. 80kW | None | 50kW | 50kW | 70kW |
213+
| C | 1 | -170kW .. 30kW | None | 50kW | 30kW | 100kW |
214+
| | | | | | target power | 100kW |
215+
216+
1. Actor A sees the full system: Available Bounds = `-100kW .. 100kW`. It
217+
proposes a power of `20kW`, but no bounds.
218+
219+
2. This becomes the operating point for actor B, so actor B sees bounds shifted
220+
by A's proposal = `-120kW .. 80kW`. It can operate only in this range.
221+
222+
3. Actor B proposes a power of `50kW` on this shifted range, and if this is
223+
applied on to the original bounds (aka shift the bounds back to the original
224+
range), it would be `20kW + 50kW = 70kW`.
211225
212-
Actor A proposes a power of `20kW`, but no bounds. In this case, actor B sees
213-
bounds shifted by A's proposal. Actor B proposes a power of `50kW` on this
214-
shifted range, and if this is applied on to the original bounds (aka shift the
215-
bounds back to the original range), it would be `20kW + 50kW = 70kW`.
226+
4. So Actor C sees bounds shifted by `70kW` from the original bounds, and sets
227+
`50kW` on this shifted range, but it can't exceed `30kW`, so its request gets
228+
limited to 30kW.
216229
217-
So Actor C sees bounds shifted by `70kW` from the original bounds, and sets
218-
`50kW` on this shifted range, but it can't exceed `30kW`, so its request gets
219-
limited to 30kW. Shifting this back by `70kW`, the target power is calculated
220-
to be `100kW`.
230+
5. Shifting this back by `70kW`, the target power is calculated to be `100kW`.
221231
222232
Irrespective of what any actor sets, the final power won't exceed the available
223233
battery bounds.
224234
225235
*Example 2*:
226236
227-
| Actor | Priority | System Bounds | Requested Bounds | Requested | Adjusted | Aggregate |
228-
| | | | | Power | Power | Power |
229-
|-------|----------|-----------------|------------------|-----------|--------------|-----------|
230-
| A | 3 | -100kW .. 100kW | None | 20kW | 20kW | 20kW |
231-
| B | 2 | -120kW .. 80kW | None | -20kW | -20kW | 0kW |
232-
| | | | | | target power | 0kW |
237+
| Actor | Priority | Available Bounds | Requested Bounds | Requested Power | Adjusted Power | Aggregate Power |
238+
|------:|---------:|-----------------:|-----------------:|----------------:|---------------:|----------------:|
239+
| A | 3 | -100kW .. 100kW | None | 20kW | 20kW | 20kW |
240+
| B | 2 | -120kW .. 80kW | None | -20kW | -20kW | 0kW |
241+
| | | | | | target power | 0kW |
233242
234243
Actors with exactly opposite requests cancel each other out.
235244
@@ -241,39 +250,39 @@
241250
242251
*Example 1*: Battery bounds available for use: -100kW to 100kW
243252
244-
| Actor | Priority | System Bounds | Requested Bounds | Requested | Adjusted | Aggregate |
245-
| | | | | Power | Power | Power |
246-
|-------|----------|-----------------|------------------|-----------|--------------|-----------|
247-
| A | 3 | -100kW .. 100kW | -20kW .. 100kW | 50kW | 40kW | 50kW |
248-
| B | 2 | -70kW .. 50kW | -90kW .. 0kW | -10kW | -10kW | 40kW |
249-
| C | 1 | -60kW .. 10kW | None | -20kW | -20kW | 20kW |
250-
| | | | | | target power | 20kW |
253+
| Actor | Priority | Available Bounds | Requested Bounds | Requested Power | Adjusted Power | Aggregate Power |
254+
|------:|---------:|-----------------:|-----------------:|----------------:|---------------:|----------------:|
255+
| A | 3 | -100kW .. 100kW | -20kW .. 100kW | 50kW | 50kW | 50kW |
256+
| B | 2 | -70kW .. 50kW | -90kW .. 0kW | -10kW | -10kW | 40kW |
257+
| C | 1 | -60kW .. 10kW | None | -20kW | -20kW | 20kW |
258+
| | | | | | target power | 20kW |
251259
252-
Actor A with the highest priority has the entire battery bounds available to it.
253-
It sets limited bounds of -20kW .. 100kW, and proposes a power of 50kW.
260+
1. Actor A with the highest priority has the entire battery bounds available to
261+
it. It sets limited bounds of `-20kW .. 100kW`, and proposes a power of
262+
`50kW`.
254263
255-
Actor B sees Actor A's limit of -20kW..100kW shifted by 50kW as -70kW..50kW, and
256-
can only propose powers within this range, which will get added (shifted back)
257-
to Actor A's proposed power.
264+
2. Actor B's operating point is now `50kW`. So, Actor B sees Actor A's limit of
265+
`-20kW..100kW` shifted by `50kW` as `-70kW..50kW`, and can only operate
266+
within this range.
258267
259-
Actor B tries to limit the bounds of actor C to -90kW .. 0kW, but it can only
260-
operate in the -70kW .. 50kW range because of bounds set by actor A, so its
261-
requested bounds get restricted to -70kW .. 0kW.
268+
3. Actor B tries to limit the bounds of actor C to `-90kW .. 0kW`, but it
269+
doesn't have access to that full range and can only operate in the
270+
`-70kW .. 50kW` range, so its specified bounds get restricted to
271+
`-70kW .. 0kW`.
262272
263-
Actor C sees this as -60kW .. 10kW, because it gets shifted by Actor B's
264-
proposed power of -10kW.
273+
4. Actor C sees this as `-60kW .. 10kW`, because it gets shifted by Actor B's
274+
proposed power of `-10kW`.
265275
266-
Actor C proposes a power within its bounds and the proposals of all the actors
267-
are added to get the target power.
276+
5. Actor C proposes a power within its bounds and the proposals of all the actors
277+
are added to get the target power.
268278
269279
*Example 2*:
270280
271-
| Actor | Priority | System Bounds | Requested Bounds | Requested | Adjusted | Aggregate |
272-
| | | | | Power | Power | Power |
273-
|-------|----------|-----------------|------------------|-----------|--------------|-----------|
274-
| A | 3 | -100kW .. 100kW | -20kW .. 100kW | 50kW | 50kW | 50kW |
275-
| B | 2 | -70kW .. 50kW | -90kW .. 0kW | -90kW | -70kW | -20kW |
276-
| | | | | | target power | -20kW |
281+
| Actor | Priority | Available Bounds | Requested Bounds | Requested Power | Adjusted Power | Aggregate Power |
282+
|------:|---------:|-----------------:|-----------------:|----------------:|---------------:|----------------:|
283+
| A | 3 | -100kW .. 100kW | -20kW .. 100kW | 50kW | 50kW | 50kW |
284+
| B | 2 | -70kW .. 50kW | -90kW .. 0kW | -90kW | -70kW | -20kW |
285+
| | | | | | target power | -20kW |
277286
278287
When an actor requests a power that's outside its available bounds, the closest
279288
available power is used.
@@ -282,19 +291,65 @@
282291
283292
Battery bounds available for use: -100kW to 100kW
284293
285-
| Priority | System Bounds | Requested Bounds | Requested | Adjusted | Aggregate |
286-
| | | | Power | Power | Power |
287-
|----------|-------------------|------------------|-----------|--------------|-----------|
288-
| 7 | -100 kW .. 100 kW | None | 10 kW | 10 kW | 10 kW |
289-
| 6 | -110 kW .. 90 kW | -110 kW .. 80 kW | 10 kW | 10 kW | 20 kW |
290-
| 5 | -120 kW .. 70 kW | -100 kW .. 80 kW | 80 kW | 70 kW | 90 kW |
291-
| 4 | -170 kW .. 0 kW | None | -120 kW | -120 kW | -30 kW |
292-
| 3 | -50 kW .. 120 kW | None | 60 kW | 60 kW | 30 kW |
293-
| 2 | -110 kW .. 60 kW | -40 kW .. 30 kW | 20 kW | 20 kW | 50 kW |
294-
| 1 | -60 kW .. 10 kW | -50 kW .. 40 kW | 25 kW | 10 kW | 60 kW |
295-
| 0 | -60 kW .. 0 kW | None | 12 kW | 0 kW | 60 kW |
296-
| -1 | -60 kW .. 0 kW | -40 kW .. -10 kW | -10 kW | -10 kW | 50 kW |
297-
| | | | | Target Power | 50 kW |
294+
| Priority | Available Bounds | Requested Bounds | Requested Power | Adjusted Power | Aggregate Power |
295+
|---------:|------------------:|-----------------:|----------------:|---------------:|----------------:|
296+
| 7 | -100 kW .. 100 kW | None | 10 kW | 10 kW | 10 kW |
297+
| 6 | -110 kW .. 90 kW | -110 kW .. 80 kW | 10 kW | 10 kW | 20 kW |
298+
| 5 | -120 kW .. 70 kW | -100 kW .. 80 kW | 80 kW | 70 kW | 90 kW |
299+
| 4 | -170 kW .. 0 kW | None | -120 kW | -120 kW | -30 kW |
300+
| 3 | -50 kW .. 120 kW | None | 60 kW | 60 kW | 30 kW |
301+
| 2 | -110 kW .. 60 kW | -40 kW .. 30 kW | 20 kW | 20 kW | 50 kW |
302+
| 1 | -60 kW .. 10 kW | -50 kW .. 40 kW | 25 kW | 10 kW | 60 kW |
303+
| 0 | -60 kW .. 0 kW | None | 12 kW | 0 kW | 60 kW |
304+
| -1 | -60 kW .. 0 kW | -40 kW .. -10 kW | -10 kW | -10 kW | 50 kW |
305+
| | | | | Target Power | 50 kW |
306+
307+
### Working with other actors to control PV inverters and EV chargers
308+
309+
The power manager reconciles power proposals for PV inverters and EV chargers
310+
similarly to batteries, but with one key difference:
311+
312+
There is no shifting of operating point between actors, and the powers are not
313+
added together.
314+
315+
Higher priority actors can strictly limit the bounds available to lower priority
316+
actors, but the power proposals by lower priority actors take precedence, as
317+
long as they are within the bounds set by higher priority actors.
318+
319+
This is because PV inverters can only produce power (negative power according to
320+
the PSC), and EV chargers can only consume power (positive power according to
321+
the PSC), and shifting bounds would make ranges available to actors that a PV
322+
inverter or EV charger can't operate in.
323+
324+
*A PV pool Example*
325+
326+
| Actor | Priority | Available Bounds | Requested Bounds | Requested Power | Adjusted Power |
327+
|------:|---------:|-----------------:|-----------------:|----------------:|---------------:|
328+
| A | 4 | -100kW .. 0W | -90kW .. 0kW | -20kW | -20kW |
329+
| B | 3 | -90kW .. 0kW | -75kW .. -20kW | -50kW | -50kW |
330+
| C | 2 | -75kW .. -20kW | None | -100kW | -75kW |
331+
| D | 1 | -75kW .. -20kW | -60kW .. -60kW | -60kW | -60kW |
332+
| E | 0 | -60kW .. -60kW | None | -20kW | -60kW |
333+
| | | | | Final Power | -60kW |
334+
335+
1. Actor A with the highest priority has access to the entire range of the PV
336+
inverters. In this case `-100kW .. 0W`.
337+
338+
2. It wants to limit production to a maximum of `-90kW`, so it sets bounds of
339+
`-90kW .. 0W`. It also proposes a power of `-20kW`. If there are no lower
340+
priority actors, that power will get set to the inverters. But here, it gets
341+
*overridden* by lower priority actors.
342+
343+
3. Actor B limits the bounds further, and proposes its preferred power.
344+
345+
4. Actor C proposes `-100kW`, which is outside of what Actor B has allowed, so it
346+
gets clamped to `-75kW`, which is the closest Actor C can get to its requested
347+
power in its available range of `-75kW .. -20kW`.
348+
349+
5. Actor D wants exactly `-60kW`, so it clamps the bounds to `-60kW .. -60kW`, and
350+
sets `-60kW`, making sure Actor E or other lower priority actors can't change
351+
the power further.
352+
298353
299354
## Withdrawing power proposals
300355
@@ -311,7 +366,7 @@
311366
| Batteries | Zero |
312367
| PV | Max production (Min power according to PSC) |
313368
| EV Chargers | Max consumption (Max power according to PSC) |
314-
""" # noqa: D205, D400
369+
""" # noqa: D205, D400, E501
315370

316371
from datetime import timedelta
317372

0 commit comments

Comments
 (0)