Skip to content

Commit

Permalink
Backport PR #758: fix(storage): fixes too many args in constraint_mes…
Browse files Browse the repository at this point in the history
…sage function (#758)

* fix(storage): fixes too many args in constraint_message function

Signed-off-by: GustaafL <[email protected]>

* refactor: removes time_parameters refactor function

Signed-off-by: GustaafL <[email protected]>

* refactor: remove soc-minima and maxima from test

Signed-off-by: GustaafL <[email protected]>

* docs(storage): changelog bugfix infeasible constraints

Signed-off-by: GustaafL <[email protected]>

* docs(storage): puts bugfix changelog into version 0.14.2

Signed-off-by: GustaafL <[email protected]>

---------

Signed-off-by: GustaafL <[email protected]>
Co-authored-by: Nicolas Höning <[email protected]>
  • Loading branch information
2 people authored and Flix6x committed Jul 25, 2023
1 parent 30eb64b commit e61e7fd
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 12 deletions.
9 changes: 9 additions & 0 deletions documentation/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
FlexMeasures Changelog
**********************

v0.14.2 | July 21, 2023
============================

Bugfixes
-----------

* The error handling for infeasible constraints in storage.py was given too many arguments. This caused the response from the API to be unhelpful when a schedule was requested with infeasible constraints. [see `PR #758 <https://github.com/FlexMeasures/flexmeasures/pull/758>`_]


v0.14.1 | June 26, 2023
============================

Expand Down
4 changes: 1 addition & 3 deletions flexmeasures/data/models/planning/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,7 @@ def compute(self, skip_validation: bool = False) -> pd.Series | None:

if len(constraint_violations) > 0:
# TODO: include hints from constraint_violations into the error message
message = create_constraint_violations_message(
constraint_violations, self.round_to_decimals
)
message = create_constraint_violations_message(constraint_violations)
raise ValueError(
"The input data yields an infeasible problem. Constraint validation has found the following issues:\n"
+ message
Expand Down
70 changes: 61 additions & 9 deletions flexmeasures/data/models/planning/tests/test_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ def test_storage_loss_function(
def test_battery_solver_day_1(
add_battery_assets, add_inflexible_device_forecasts, use_inflexible_device
):
epex_da = Sensor.query.filter(Sensor.name == "epex_da").one_or_none()
battery = Sensor.query.filter(Sensor.name == "Test battery").one_or_none()
assert battery.get_attribute("market_id") == epex_da.id
epex_da, battery = get_sensors_from_db()
tz = pytz.timezone("Europe/Amsterdam")
start = tz.localize(datetime(2015, 1, 1))
end = tz.localize(datetime(2015, 1, 2))
Expand Down Expand Up @@ -118,9 +116,7 @@ def test_battery_solver_day_2(
and so we expect the scheduler to only:
- completely discharge within the last 8 hours
"""
epex_da = Sensor.query.filter(Sensor.name == "epex_da").one_or_none()
battery = Sensor.query.filter(Sensor.name == "Test battery").one_or_none()
assert battery.get_attribute("market_id") == epex_da.id
_epex_da, battery = get_sensors_from_db()
tz = pytz.timezone("Europe/Amsterdam")
start = tz.localize(datetime(2015, 1, 2))
end = tz.localize(datetime(2015, 1, 3))
Expand Down Expand Up @@ -490,9 +486,7 @@ def test_soc_bounds_timeseries(add_battery_assets):
"""

# get the sensors from the database
epex_da = Sensor.query.filter(Sensor.name == "epex_da").one_or_none()
battery = Sensor.query.filter(Sensor.name == "Test battery").one_or_none()
assert battery.get_attribute("market_id") == epex_da.id
epex_da, battery = get_sensors_from_db()

# time parameters
tz = pytz.timezone("Europe/Amsterdam")
Expand Down Expand Up @@ -792,3 +786,61 @@ def test_validate_constraints(
)

assert set(expected_constraint_type_violations) == constraint_type_violations_output


def test_infeasible_problem_error(add_battery_assets):
"""Try to create a schedule with infeasible constraints. soc-max is 4.5 and soc-target is 8.0"""

# get the sensors from the database
_epex_da, battery = get_sensors_from_db()

# time parameters
tz = pytz.timezone("Europe/Amsterdam")
start = tz.localize(datetime(2015, 1, 2))
end = tz.localize(datetime(2015, 1, 3))
resolution = timedelta(hours=1)

def compute_schedule(flex_model):
scheduler = StorageScheduler(
battery,
start,
end,
resolution,
flex_model=flex_model,
)
schedule = scheduler.compute()

soc_schedule = integrate_time_series(
schedule,
soc_at_start,
decimal_precision=1,
)

return soc_schedule

# soc parameters
soc_at_start = battery.get_attribute("soc_in_mwh")
infeasible_max_soc_targets = [
{"datetime": "2015-01-02T16:00:00+01:00", "value": 8.0}
]

flex_model = {
"soc-at-start": soc_at_start,
"soc-min": 0.5,
"soc-max": 4.5,
"soc-targets": infeasible_max_soc_targets,
}

with pytest.raises(
ValueError, match="The input data yields an infeasible problem."
):
compute_schedule(flex_model)


def get_sensors_from_db():
# get the sensors from the database
epex_da = Sensor.query.filter(Sensor.name == "epex_da").one_or_none()
battery = Sensor.query.filter(Sensor.name == "Test battery").one_or_none()
assert battery.get_attribute("market_id") == epex_da.id

return epex_da, battery

0 comments on commit e61e7fd

Please sign in to comment.