Skip to content

Commit

Permalink
Backport PR #918: fix(logs):reduce log messages from schedule (#918)
Browse files Browse the repository at this point in the history
* fix(logs):reduce log messages from schedule

Signed-off-by: GustaafL <guus@seita.nl>

* docs(changelog): add changelog entry

Signed-off-by: GustaafL <guus@seita.nl>

* refactor(imports): remove whitespaces

Signed-off-by: GustaafL <guus@seita.nl>

* docs(changelog): move fix to 0.17.1 instead of 0.18.0

Signed-off-by: GustaafL <guus@seita.nl>

* fix(scheduling): fix typo in log message

Signed-off-by: GustaafL <guus@seita.nl>

* feat(test): add entry within the window of the schedule

Signed-off-by: GustaafL <guus@seita.nl>

* feat(schedule): add different log message for single target out of window datetime

Signed-off-by: GustaafL <guus@seita.nl>

---------

Signed-off-by: GustaafL <guus@seita.nl>
  • Loading branch information
GustaafL authored and Flix6x committed Dec 7, 2023
1 parent 4a193a0 commit 9d32caa
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 6 deletions.
1 change: 1 addition & 0 deletions documentation/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ v0.17.1 | November 22, 2023
Bugfixes
-----------

* Reduce worker logs when datetime exceeds the end of the schedule [see `PR #918 <https://github.com/FlexMeasures/flexmeasures/pull/918>`_]
* Fix infeasible problem due to incorrect estimation of the big-M value [see `PR #905 <https://github.com/FlexMeasures/flexmeasures/pull/905>`_]
* Fix API version listing (GET /api/v3_0) for hosts running on Python 3.8 [see `PR #917 <https://github.com/FlexMeasures/flexmeasures/pull/917>`_]

Expand Down
17 changes: 12 additions & 5 deletions flexmeasures/data/models/planning/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,6 @@ def ensure_soc_min_max(self):


class StorageFallbackScheduler(MetaStorageScheduler):

__version__ = "1"
__author__ = "Seita"

Expand Down Expand Up @@ -630,6 +629,7 @@ def build_device_soc_values(
if isinstance(soc_values, pd.Series): # some tests prepare it this way
device_values = soc_values
else:
disregarded_datetimes = []
device_values = initialize_series(
np.nan,
start=start_of_schedule,
Expand All @@ -645,14 +645,22 @@ def build_device_soc_values(
) # otherwise DST would be problematic
if soc_datetime > end_of_schedule:
# Skip too-far-into-the-future target
disregarded_datetimes += [soc_datetime]
max_server_horizon = get_max_planning_horizon(resolution)
current_app.logger.warning(
f"Disregarding target datetime {soc_datetime}, because it exceeds {end_of_schedule}. Maximum scheduling horizon is {max_server_horizon}."
)
continue

device_values.loc[soc_datetime] = soc

if disregarded_datetimes:
if len(disregarded_datetimes) == 1:
current_app.logger.warning(
f"Disregarding 1 target datetime {disregarded_datetimes[0]}, because it exceeds {end_of_schedule}. Maximum scheduling horizon is {max_server_horizon}."
)
else:
current_app.logger.warning(
f"Disregarding {len(disregarded_datetimes)} target datetimes from {min(disregarded_datetimes)} until {max(disregarded_datetimes)}, because they exceed {end_of_schedule}. Maximum scheduling horizon is {max_server_horizon}."
)

# soc_values are at the end of each time slot, while prices are indexed by the start of each time slot
device_values = device_values[start_of_schedule + resolution : end_of_schedule]

Expand Down Expand Up @@ -904,7 +912,6 @@ def sanitize_expression(expression: str, columns: list) -> tuple[str, list]:
columns_involved = []

for column in columns:

if re.search(get_pattern_match_word(column), _expression):
columns_involved.append(column)

Expand Down
42 changes: 42 additions & 0 deletions flexmeasures/data/models/planning/tests/test_solver.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from datetime import datetime, timedelta
import pytest
import pytz
import logging

import numpy as np
import pandas as pd
Expand All @@ -13,6 +14,7 @@
StorageScheduler,
add_storage_constraints,
validate_storage_constraints,
build_device_soc_values,
)
from flexmeasures.data.models.planning.linear_optimization import device_scheduler
from flexmeasures.data.models.planning.tests.utils import check_constraints
Expand Down Expand Up @@ -1255,3 +1257,43 @@ def set_if_not_none(dictionary, key, value):

assert all(ems_constraints["derivative min"] == expected_site_production_capacity)
assert all(ems_constraints["derivative max"] == expected_site_consumption_capacity)


@pytest.mark.parametrize(
["soc_values", "log_message"],
[
(
[
{"datetime": datetime(2023, 5, 19, tzinfo=pytz.utc), "value": 1.0},
{"datetime": datetime(2023, 5, 22, tzinfo=pytz.utc), "value": 1.0},
{"datetime": datetime(2023, 5, 23, tzinfo=pytz.utc), "value": 1.0},
{"datetime": datetime(2023, 5, 21, tzinfo=pytz.utc), "value": 1.0},
],
"Disregarding 3 target datetimes from 2023-05-21 00:00:00+00:00 until 2023-05-23 00:00:00+00:00, because they exceed 2023-05-20 00:00:00+00:00",
),
(
[
{"datetime": datetime(2023, 5, 19, tzinfo=pytz.utc), "value": 1.0},
{"datetime": datetime(2023, 5, 23, tzinfo=pytz.utc), "value": 1.0},
],
"Disregarding 1 target datetime 2023-05-23 00:00:00+00:00, because it exceeds 2023-05-20 00:00:00+00:00",
),
],
)
def test_build_device_soc_values(caplog, soc_values, log_message):
caplog.set_level(logging.WARNING)
soc_at_start = 3.0
start_of_schedule = datetime(2023, 5, 18, tzinfo=pytz.utc)
end_of_schedule = datetime(2023, 5, 20, tzinfo=pytz.utc)
resolution = timedelta(minutes=5)

with caplog.at_level(logging.WARNING):
device_values = build_device_soc_values(
soc_values=soc_values,
soc_at_start=soc_at_start,
start_of_schedule=start_of_schedule,
end_of_schedule=end_of_schedule,
resolution=resolution,
)
print(device_values)
assert log_message in caplog.text
1 change: 0 additions & 1 deletion flexmeasures/data/schemas/scheduling/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ def __init__(self, *args, **kwargs):

@validates("value")
def validate_value(self, _value):

if self.value_validator is not None:
self.value_validator(_value)

Expand Down

0 comments on commit 9d32caa

Please sign in to comment.