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

Issue 273 add roundtrip efficiency to scheduler #291

Merged
merged 64 commits into from Jan 3, 2022

Conversation

Flix6x
Copy link
Contributor

@Flix6x Flix6x commented Jan 1, 2022

This PR rewrites our generic device scheduler to:

  • Deal with asymmetric efficiency losses of individual devices.
  • Deal with asymmetric up and down prices for deviating from previous commitments.

Furthermore, it allows round-trip efficiency to be communicated as a new optional field when POSTing UDI Events, with efficiency losses being assigned equally to charging and discharging.

Closes #273.

NB In a premature state, this PR applied round-trip efficiency by scaling charging and discharging prices accordingly. However, this approach is limited to use cases with a single device per EMS. With tariffs modeled as a commitment to zero prosumption, for a single-device EMS, the up price is equal to the consumption price (charging) and the down price is equal to the feed-in price (discharging).

Flix6x added 30 commits Dec 26, 2021
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
…nsor_data

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

Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Flix6x added 5 commits Jan 1, 2022
Signed-off-by: F.N. Claessen <felix@seita.nl>
…scale prices

Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
@Flix6x Flix6x self-assigned this Jan 1, 2022
@Flix6x Flix6x linked an issue Jan 1, 2022 that may be closed by this pull request
@Flix6x Flix6x marked this pull request as draft Jan 1, 2022
Flix6x added 4 commits Jan 1, 2022
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
…pplication of round-trip efficiency as price scalars and modeling device flows in more detail

Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
@Flix6x Flix6x marked this pull request as ready for review Jan 1, 2022
@Flix6x Flix6x requested a review from nhoening Jan 1, 2022
Copy link
Contributor

@nhoening nhoening left a comment

Looks pretty good, besides one potential error and some documentation I'd like.

And one fundamental question: It seems we are going from one power variable to ems_power, device_power_down and device_power_up. Does this mean that in principle (although it is usually isn't optimal) we could charge and discharge at the same time?

Also, I have some notes which don't necessarily block this PR, so you could either address them, or we make a new ticket:

For full understanding, I wanted to see how the battery and charging stations differ. I had a tough time really seeing how that is, as battery.py and charging_station.py seem to share a large amount of code.

My assumption: They both schedule only one sensor (one for a battery, one for a charging station) against SOC targets for lowest costs. The "EMS" is not being optimized, but it actually is the environment of the 1 device (e.g. the grid).

Is that correct?
The comments are sometimes talking about "devices" (plural) so I'm unsure.

A few smaller questions, maybe addressable in this PR (with a comment or so) but maybe rather as tickets:

  • What is the difference in treatment between battery and charging station? I compared the code for a few minutes, but I couldn't tell the major difference. Their docstring are also almost identical.
  • Can we formally distinguish (check) that we treat a sensor/asset of correct type before we schedule?
  • If the code is 75% (or so) identical, there might be an idea for future refactoring to note here.

flexmeasures/api/v1_3/routes.py Show resolved Hide resolved
flexmeasures/data/models/planning/battery.py Show resolved Hide resolved
flexmeasures/data/models/planning/solver.py Outdated Show resolved Hide resolved
Flix6x added 3 commits Jan 2, 2022
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
@Flix6x
Copy link
Contributor Author

Flix6x commented Jan 2, 2022

And one fundamental question: It seems we are going from one power variable to ems_power, device_power_down and device_power_up. Does this mean that in principle (although it is usually isn't optimal) we could charge and discharge at the same time?

Correct. At first I added the constraint device_power_up * device_power_down = 0, but that results in a non-linear (quadratic) program. The same goes for the constraint commitment_downwards_deviation * commitment_upwards_deviation = 0. Given efficiencies between 0 than 1 and given convex commitment prices, I believe we can go without these constraints.

For full understanding, I wanted to see how the battery and charging stations differ. I had a tough time really seeing how that is, as battery.py and charging_station.py seem to share a large amount of code.

My assumption: They both schedule only one sensor (one for a battery, one for a charging station) against SOC targets for lowest costs. The "EMS" is not being optimized, but it actually is the environment of the 1 device (e.g. the grid).

Is that correct? The comments are sometimes talking about "devices" (plural) so I'm unsure.

Our generic device scheduler (def device_scheduler) is able to handle an EMS with multiple devices, with constraints on the EMS level and on the device level, and market commitment on the EMS level. A typical example is a house with many devices. The two specific schedulers we coupled to the FlexMeasures API are for an EMS with a single device, i.e. a standalone Charge Point and a standalone battery system.

A few smaller questions, maybe addressable in this PR (with a comment or so) but maybe rather as tickets:

* What is the difference in treatment between battery and charging station? I compared the code for a few minutes, but I couldn't tell the major difference. Their docstring are also almost identical.

The differences are few, actually. Perhaps they have been dissipating as development progressed. I think at this point it's only in the min/max state of charge (which is assumed to be a known sensor property for a battery, but not so for a Charge Point, because it depends on the connected EV).

* Can we formally distinguish (check) that we treat a sensor/asset of correct type before we schedule?

Good idea. I made a card for project 6.

* If the code is 75% (or so) identical, there might be an idea for future refactoring to note here.

Refactoring is a good idea. I added a card to project 6.

@Flix6x Flix6x requested a review from nhoening Jan 2, 2022
Copy link
Contributor

@nhoening nhoening left a comment

Approved.

I feel that some comments you made during our discussion in this PR are worthwhile.

This one could be helpful in the solvers' docstring:

This generic device scheduler ( is able to handle an EMS with multiple devices, with constraints on the EMS level and on the device level, and market commitment on the EMS level. A typical example is a house with many devices.

The following one seems like a crucial list of assumptions we rely on - maybe in a comment:

(when discussing why we not make sure that charging and discharging cannot happen at the same time)

Given efficiencies between 0 than 1 and given convex commitment prices, I believe we can go without these constraints.

Are convex commitment prices a sure thing?

Signed-off-by: F.N. Claessen <felix@seita.nl>
Base automatically changed from Sub-issue-284d_Stop_saving_to_Power/Price/Weather_tables to Issue-284_Move_sensor_data_from_Power/Price/Weather_to_TimedBelief Jan 3, 2022
Base automatically changed from Issue-284_Move_sensor_data_from_Power/Price/Weather_to_TimedBelief to project-9 Jan 3, 2022
…undtrip_efficiency_to_scheduler

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

# Conflicts:
#	flexmeasures/api/__init__.py
#	flexmeasures/api/dev/tests/test_sensor_data.py
#	flexmeasures/data/models/time_series.py
#	flexmeasures/data/scripts/data_gen.py
#	flexmeasures/data/tests/test_queries.py
#	flexmeasures/data/utils.py
@Flix6x Flix6x merged commit e0af47a into project-9 Jan 3, 2022
4 checks passed
@Flix6x Flix6x deleted the Issue-273_Add_roundtrip_efficiency_to_scheduler branch Jan 3, 2022
@Flix6x Flix6x added this to the 0.8.0 milestone Jan 20, 2022
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.

Add roundtrip efficiency to scheduler
2 participants