Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions documentation/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Infrastructure / Support

Bugfixes
-----------
* Return a clear validation error (instead of a server ZeroDivisionError) when posting instantaneous (0-minute) data to non-instantaneous sensors via ``[POST] /sensors/(id)/data`` [see `PR #2116 <https://www.github.com/FlexMeasures/flexmeasures/pull/2116>`_]


v0.32.0 | April 15, 2026
Expand Down
4 changes: 4 additions & 0 deletions flexmeasures/api/common/schemas/sensor_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,10 @@ def check_resolution_compatibility_of_sensor_data(self, data, **kwargs):
# The event frequency is inferred by assuming sequential, equidistant values within a time interval.
# The event resolution is assumed to be equal to the event frequency.
inferred_resolution = data["duration"] / len(data["values"])
if len(data["values"]) == 1 and inferred_resolution == timedelta(hours=0):
raise ValidationError(
f"Cannot infer a non-zero resolution from one value over zero duration. This sensor requires a resolution of {required_resolution}."
)
if inferred_resolution % required_resolution != timedelta(hours=0):
raise ValidationError(
f"Resolution of {inferred_resolution} is incompatible with the sensor's required resolution of {required_resolution}."
Expand Down
25 changes: 25 additions & 0 deletions flexmeasures/api/v3_0/tests/test_sensor_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,31 @@ def test_post_invalid_sensor_data(
)


@pytest.mark.parametrize(
"requesting_user", ["test_supplier_user_4@seita.nl"], indirect=True
)
def test_post_non_instantaneous_sensor_data_with_zero_duration_single_value(
client, setup_api_test_data, requesting_user
):
post_data = make_sensor_data_request_for_gas_sensor(
num_values=1,
duration="PT0M",
unit="m³/h",
)
sensor = setup_api_test_data["some gas sensor"]

response = client.post(
url_for("SensorAPI:post_data", id=sensor.id),
json=post_data,
)

assert response.status_code == 422
assert (
"Cannot infer a non-zero resolution from one value over zero duration"
in response.json["message"]["combined_sensor_data_description"]["_schema"][0]
)


@pytest.mark.parametrize(
"requesting_user", ["test_supplier_user_4@seita.nl"], indirect=True
)
Expand Down
Loading