Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple Matryoshka pools in the Power Manager that can be aggregated #905

Open
shsms opened this issue Mar 27, 2024 · 13 comments · May be fixed by #957
Open

Support multiple Matryoshka pools in the Power Manager that can be aggregated #905

shsms opened this issue Mar 27, 2024 · 13 comments · May be fixed by #957
Assignees
Labels
part:power-management Affects the management of battery power and distribution priority:❓ We need to figure out how soon this should be addressed type:enhancement New feature or enhancement visitble to users
Milestone

Comments

@shsms
Copy link
Contributor

shsms commented Mar 27, 2024

What's needed?

There should be multiple matryoshka based target power calculation pools in the PowerManager, and their target powers need to be aggregated (added) to get the final target power.

This would allow use cases like FCR to set their adjustment power always relative to the target power of the other use case actors.

cc: @thomas-nicolai-frequenz

@shsms shsms added part:❓ We need to figure out which part is affected priority:❓ We need to figure out how soon this should be addressed type:enhancement New feature or enhancement visitble to users labels Mar 27, 2024
@shsms shsms added this to the v1.0.0-rc7 milestone Mar 27, 2024
@shsms shsms added part:power-management Affects the management of battery power and distribution and removed part:❓ We need to figure out which part is affected priority:❓ We need to figure out how soon this should be addressed labels Mar 28, 2024
@shsms
Copy link
Contributor Author

shsms commented Mar 28, 2024

@thomas-nicolai-frequenz If there are multiple separate pools, do we start with the same full available bounds on each of them, calculate the target power for each pool, add them, and apply the bounds again on the final target power?

Alternatively we can get the remaining bounds to propagate downwards, but then we'd be introducing priorities for the pools as well. So highest priority pool will have entire bounds, then lower priority pools will have the bounds permitted by the higher pools.

I feel that both approaches would have similar results, but maybe I'm missing something, or there are alternative approaches.

@thomas-nicolai-frequenz
Copy link

thomas-nicolai-frequenz commented Mar 28, 2024

and apply the bounds again on the final target power

Group 1: "none-incremental" charge actors (default)

Actor Priority Lower Bound Set power Upper Bound
Actor_1 1 (highest) 100 100 -
Actor_2 2 120 120 -

Group 2: FCR like "incremental" actors

Actor Priority Lower Bound Set power Upper Bound
Actor_3 3 20 25 30
Actor_4 4 26 28 30

Actor 1 and 2 would be looking to charge with a set amount of power and no upper bound.
The actual output would be computed by adding up both pools power requests 120 + 28 = 148. Now all actors would see 148 in the batteries real power output. Actor 3 and 4 would need to know that their bounds have been respected but they are also aware that they are "incremental" to the none-incremental actors 1 and 2.

From a flow perspective once actor 1 and 2 requests are accounted for we'd look at actors 3 and 4 bounds and power request. So from a priority perspective actor 2 will give us [120,120,-] and applying the combination of actor 3 and 4 on top would give us [146,148,150]. These bounds would be in line with actor 1 and 2s requirements.

The only question left would be what happens if the upper bound of actor 1 or 2 would be something like 140. In this case the additional, incremental ask of actor 3 and 4 could not be granted. However, I'm not sure this is a problem though.

If we follow the approach above I'm not sure we really need two independent pools but rather just a different logic on how and when these two different type of power requests are applied. The incremental power request would always have the lowest priority though as it can only be applied once all incremental power requests have been accounted for. In order to be able to provide the FCR actors the highest priority they would be turned into the none-incremental and the charge actor would turn incremental instead.

@thomas-nicolai-frequenz
Copy link

thomas-nicolai-frequenz commented Apr 1, 2024

In order to be able to provide the FCR actors the highest priority they would be turned into the none-incremental and the charge actor would turn incremental instead.

Thats indeed what we would need. The only thing thats important to consider is that a charging actor might request 100kW on top of e.g. 20kW being asked by the FCR actor and in case the inverter would only support 100kW max charging power the charging actor would only get 80kW but accept that. In most cases a charging actor would rather work on requesting energy for a 15-min period instead of requesting absolute power. Hence it does not matter if the charging actor gets 80kW assigned but the actor might also reject that if its being asked for power instead of energy for a given time period. Of course these are internals to the actor do decide what he can accept in terms of true power output.

@matthias-wende-frequenz any thoughts on this?

@llucax llucax modified the milestones: v1.0.0-rc7, v1.0.0-rc8 Apr 9, 2024
@llucax llucax added the priority:❓ We need to figure out how soon this should be addressed label Apr 9, 2024
@shsms
Copy link
Contributor Author

shsms commented Apr 23, 2024

If we follow the approach above I'm not sure we really need two independent pools but rather just a different logic on how and when these two different type of power requests are applied.

I think implementation this needs to be two different pools, because we still need to use the matryoshka algorithm to find the target power for actors 3 and 4 (incremental actors). Then add that to the target power of the non-incremental actors.

Do you think there would be only two pools - some non-incremental actors and some incremental actors? Then the interface can simply change to sending a incremental = True along with the proposed power.


I'd like to try out another example scenario to work out the top level details and see if you agree:

Lets say there are two actors - one non-incremental (NIA) and one incremental (IA). Total available battery bounds is -100kW to 100kW.

NIA sees -100kW to 100kW as bounds, and sets 80kW power and 70kW to 80kW bounds,
IA sees -100kW to 100kW and sets 50kW power and 45kW to 50kW bounds.

The bounds set by these actors are not seen by the other actors, because they are on different pools. So they both keep seeing the full power available from the batteries.

power manager calculates target power as 100kW (= min(100kW, 80 + 50kW)), and both actors see 100kW as the target power.

Does that sound correct?

@thomas-nicolai-frequenz

Do you think there would be only two pools - some non-incremental actors and some incremental actors? Then the interface can simply change to sending a incremental = True along with the proposed power.

Right now I can't think of needing more than two pools tbh. The incremental piece is a really special case so I sense that your proposal might make sense.

@thomas-nicolai-frequenz

The bounds set by these actors are not seen by the other actors, because they are on different pools.

The key point here is that one pool has to give and hence the question of priority. The flag incremental = True is not sufficient because whats also important is whether the incremental actor has priority. In the case I describe above it in fact does. That means the IA always gets the maximum available power. The NIA only gets what is left. Does that make sense?

@thomas-nicolai-frequenz

power manager calculates target power as 100kW (= min(100kW, 80 + 50kW)), and both actors see 100kW as the target power.

No. Based on the the above the IA gets its minimum power of either 50kW or we lower it to 45kW defined in the bounds (45kW to 50kW). The NIA only gets the remaining power which in this case should be 50kW or 45kW if 100kW is the max combined power output. The question of course is if we receive the first IA power bounds and they take priority if we communicate to the NAI right away that the bounds of -100,100 have been lowered to -100,50 for example by the "system".

@shsms
Copy link
Contributor Author

shsms commented Apr 23, 2024

Okay, understood.

Th left-over from higher priority pool's final calculated bounds is the maximum available for the lower pri pool. So this means, users don't have to specify incremental = True every time when making a power proposal, they can do it once when creating the BatteryPool, along with the priority.

Then I think the only edge case I can think of now is: when there are 3 actors:

actor priority
IA-1 high
NIA-1 med
IA-2 low

We could log a warning saying there might be some mis-configuration, but continue operation with IA* having higher priority than NIA. Or do we just raise an error as soon as the overlap is identified (likely when user is creating a BatteryPool instance)?

@shsms
Copy link
Contributor Author

shsms commented Apr 23, 2024

Also, currently the priority for an actor gets set at startup. We have an issue to allow it to change at runtime, but scheduled for post-1.0: #728

@thomas-nicolai-frequenz
Copy link

thomas-nicolai-frequenz commented Apr 28, 2024

Then I think the only edge case I can think of now is: when there are 3 actors:

I don't quite understand where you see the edge case. There is two IA actors and on NIA actor. That means we still have two pools. Each pools is negotiated separately. In the example you've given IA-2 low priority would have no impact on the NIA actor as this is a separately negotiated pool.

The challenge though is if the IA pool has higher priority than the NIA actor pool. Thats a tricky one and might depend on the actor composition. I'm not have a clear view on that yet though.

@shsms
Copy link
Contributor Author

shsms commented May 28, 2024

The question of course is if we receive the first IA power bounds and they take priority if we communicate to the NAI right away that the bounds of -100,100 have been lowered to -100,50 for example by the "system".

I've implemented it such that non-incremental actors will get notified of changed bounds as soon as incremental actors have set some power, and vice-versa when non-incremental actors are higher priority. It is not much cost because we have to do the calculations anyway.

@shsms
Copy link
Contributor Author

shsms commented May 28, 2024

The other thing is about how bounds change: If batteries can do -100kW to 100kW, and high priority IA sets 50kW, then the NIA pool will see system bounds -150kW to 50kW.

The NIA can set upto -150kW, because when added to the IA target power of 50kW, we'd still remain within the battery limit of -100kW.

I hope that makes sense.

@shsms shsms self-assigned this May 31, 2024
@shsms shsms modified the milestones: v1.0.0-rc900, v1.0.0-rc700 May 31, 2024
@shsms
Copy link
Contributor Author

shsms commented Jun 5, 2024

This was discussed during the SDK meeting and the feeling was that incremental doesn't sufficiently explain the feature and introduces ambiguities. We settled on calling it "shifting group" instead of "incremental pool", because actors in the shifting group are actually shifting the zero of the regular actors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
part:power-management Affects the management of battery power and distribution priority:❓ We need to figure out how soon this should be addressed type:enhancement New feature or enhancement visitble to users
Projects
Status: Review in progress
Development

Successfully merging a pull request may close this issue.

3 participants