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

feat(scheduling): Add multiple maxima and minima constraints into StorageScheduler #680

Merged
merged 19 commits into from May 29, 2023

Conversation

victorgarcia98
Copy link
Contributor

@victorgarcia98 victorgarcia98 commented May 11, 2023

This PR allows to set multiple maxima and minima SOC values as timeseries. These parameters can be passed into StorageScheduler in flex-model.

Closes #575.

Applications:

  • With soc-max and soc-min users can define a global maximum and minimum, respected during the whole scheduling period. I think of these two values as hard limits.
  • With soc-minima, users can define what is called soc-max-preference in Issue Handle SoC targets that exceed the maximum SoC #575.
  • soc-maxima can be used to apply hourly restrictions in congested hours.

Please, let me know your thoughts on this new feature.

…lable.

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
style: rename build_device_soc_targets to build_device_soc_values

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
@victorgarcia98 victorgarcia98 changed the title Max min soc timeseries feat(scheduling): Add multiple maxima and minima constraints into StorageScheduler May 11, 2023
@victorgarcia98 victorgarcia98 self-assigned this May 11, 2023
@nhoening nhoening added this to the 0.14.0 milestone May 11, 2023
Copy link
Contributor

@Flix6x Flix6x left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice feature. Here are some comments from a code read. I still need to think a bit about whether we are now covering our intended use case from Issue #575.

What happens if a target exceeds the maxima (to such an extent that maxima may have to be ignored even a couple of time steps before the target)? Is it the client's responsibility to present a solvable problem?

flexmeasures/data/models/planning/tests/test_solver.py Outdated Show resolved Hide resolved
flexmeasures/data/models/planning/tests/test_solver.py Outdated Show resolved Hide resolved
flexmeasures/data/models/planning/storage.py Outdated Show resolved Hide resolved
flexmeasures/data/models/planning/storage.py Outdated Show resolved Hide resolved
flexmeasures/data/models/planning/storage.py Outdated Show resolved Hide resolved
@victorgarcia98
Copy link
Contributor Author

victorgarcia98 commented May 12, 2023

What happens if a target exceeds the maxima (to such an extent that maxima may have to be ignored even a couple of time steps before the target)? Is it the client's responsibility to present a solvable problem?

Good question!

This could happen the same for the minima, were the user could raise the minima with a low target after it.

I'm not sure it will lead to an unfeasible problem as the derivate_max is set to capacity, so it could potentially discharge/charge the full storage in a time period (which is something we should discourage).

It would be a problem if there were more than one of the constraints (target, maxima and minima) defined in the same time slot, being incompatible i.e not fulfilling the condition maxima >= target >= minima.


Off topic

I think we should include the resolution into the calculations of derivative_max and derivative_min:

device_constraints[0]["derivative min"] = (
                sensor.get_attribute("capacity_in_mw") * -1 * ( resolution / timedelta(hours=1))
            )

That way, If the storage has a limit of 1MW -> 1MWh in 1 hour is equivalent to a limit 250kWh in 15min.

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
@Flix6x
Copy link
Contributor

Flix6x commented May 19, 2023

Upon further reflection, I believe this PR does in fact resolve #575, by implementing the first approach suggested there. We should still add documentation:

  • The new fields should at least be added to Example B of the trigger endpoint docstring.
  • A changelog entry
  • By now we have accumulated quite some scheduling options (in Example B) that aren't really explained in detail anywhere else. I suggest we open an Issue to add a new documentation section (e.g. to https://flexmeasures.readthedocs.io/en/latest/tut/forecasting_scheduling.html) where we can discuss some scheduling problems. There we can then also address the case detailed in Handle SoC targets that exceed the maximum SoC #575, and what the client can do to set up this problem as a feasible scheduling problem. This will require some combination of using the soc-maxima and soc-minima fields, instead of the soc-max and soc-targets fields. Something like:
    • setting soc-maxima to a list of values equal to the normally preferred maximum value, for each time step, but excluding some time range around each soc-target (to make the problem feasible),
    • setting the soc-minima to a list of 100% values, for each soc-target datetime.

One more thing: we should be able to raise informative validation errors by checking feasibility of constraints over consecutive time steps. For example: $SOC_{min}(t+1) \leq SOC_{max}(t) + power_{max}(t)$. Could also be a follow-up issue.

Can you open a new issue or discussion for the off-topic comment? I'll add my thoughts there.

…use soc_minima

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
flexmeasures/data/models/planning/tests/test_solver.py Outdated Show resolved Hide resolved
flexmeasures/data/models/planning/tests/test_solver.py Outdated Show resolved Hide resolved
flexmeasures/data/models/planning/storage.py Outdated Show resolved Hide resolved
flexmeasures/data/models/planning/storage.py Outdated Show resolved Hide resolved
flexmeasures/data/models/planning/storage.py Outdated Show resolved Hide resolved
flexmeasures/data/models/planning/storage.py Outdated Show resolved Hide resolved
Flix6x and others added 2 commits May 25, 2023 12:49
* style: sphinx docstrings

Signed-off-by: F.N. Claessen <felix@seita.nl>

* style: more detailed type annotation

Signed-off-by: F.N. Claessen <felix@seita.nl>

* style: consistency

Signed-off-by: F.N. Claessen <felix@seita.nl>

* fix: incomplete type annotation

Signed-off-by: F.N. Claessen <felix@seita.nl>

* fix: validation A.1)

Signed-off-by: F.N. Claessen <felix@seita.nl>

* fix: Validation B.2)

Signed-off-by: F.N. Claessen <felix@seita.nl>

* fix: Validation C.1)

Signed-off-by: F.N. Claessen <felix@seita.nl>

* fix: Validation C.3)

Signed-off-by: F.N. Claessen <felix@seita.nl>

* fix: Validation C.4)

Signed-off-by: F.N. Claessen <felix@seita.nl>

* refactor: move statements to where they matter

Signed-off-by: F.N. Claessen <felix@seita.nl>

* style: consistency (also: https://books.google.com/ngrams/graph?content=infeasible%2Cunfeasible&year_start=1800&year_end=2019&corpus=en-2019&smoothing=0&case_insensitive=true )

Signed-off-by: F.N. Claessen <felix@seita.nl>

* style: Validation B.2)

Signed-off-by: F.N. Claessen <felix@seita.nl>

---------

Signed-off-by: F.N. Claessen <felix@seita.nl>
* style: sphinx docstrings

Signed-off-by: F.N. Claessen <felix@seita.nl>

* style: more detailed type annotation

Signed-off-by: F.N. Claessen <felix@seita.nl>

* style: consistency

Signed-off-by: F.N. Claessen <felix@seita.nl>

* fix: incomplete type annotation

Signed-off-by: F.N. Claessen <felix@seita.nl>

* fix: validation A.1)

Signed-off-by: F.N. Claessen <felix@seita.nl>

* fix: Validation B.2)

Signed-off-by: F.N. Claessen <felix@seita.nl>

* fix: Validation C.1)

Signed-off-by: F.N. Claessen <felix@seita.nl>

* fix: Validation C.3)

Signed-off-by: F.N. Claessen <felix@seita.nl>

* fix: Validation C.4)

Signed-off-by: F.N. Claessen <felix@seita.nl>

* refactor: move statements to where they matter

Signed-off-by: F.N. Claessen <felix@seita.nl>

* style: consistency (also: https://books.google.com/ngrams/graph?content=infeasible%2Cunfeasible&year_start=1800&year_end=2019&corpus=en-2019&smoothing=0&case_insensitive=true )

Signed-off-by: F.N. Claessen <felix@seita.nl>

* style: Validation B.2)

Signed-off-by: F.N. Claessen <felix@seita.nl>

* refactor: Constraint validation for cases A and B

Signed-off-by: F.N. Claessen <felix@seita.nl>

* style: fixing typos

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* fix: add comments clarifying why we need to sort the `{equals, max, min}_extended` series

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* refactor:  create storage_device_constraints inside of add_storage_constraints

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* reactor: max_soc -> soc_max

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* reactor: min_soc -> soc_min

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* feat: update validate_constraint to accept arbitrary constraint expressions

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* style: fixing some refactor that affected the comments

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

---------

Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
Co-authored-by: Victor Garcia Reolid <victor@seita.nl>
Copy link
Contributor

@Flix6x Flix6x left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty amazing stuff you did with the constraint validation! 😎

flexmeasures/data/models/planning/storage.py Outdated Show resolved Hide resolved
flexmeasures/data/models/planning/storage.py Outdated Show resolved Hide resolved
Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
Signed-off-by: Victor <victor@seita.nl>
@victorgarcia98 victorgarcia98 merged commit a966d9f into main May 29, 2023
6 of 7 checks passed
@victorgarcia98 victorgarcia98 deleted the max_min_soc_timeseries branch May 29, 2023 16:05
@Flix6x
Copy link
Contributor

Flix6x commented Jun 9, 2023

Actually, note to self: we still need to update the API changelog.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Handle SoC targets that exceed the maximum SoC
3 participants