Skip to content
Open
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
2 changes: 1 addition & 1 deletion documentation/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Bugfixes
* Check read permissions for sensors referenced in forecasting and scheduling config payloads, and return a clearer 403 error when a referenced sensor is not readable [see `PR #2096 <https://www.github.com/FlexMeasures/flexmeasures/pull/2096>`_ and `PR #2125 <https://www.github.com/FlexMeasures/flexmeasures/pull/2125>`_]
* Standardize resolution formatting across API endpoints for consistent response payloads [see `PR #2152 <https://www.github.com/FlexMeasures/flexmeasures/pull/2152>`_]
* Make the auth check for CLI commands work with ``flask``, too, instead of only with the ``flexmeasures`` alias [see `PR #2169 <https://www.github.com/FlexMeasures/flexmeasures/pull/2169>`_]
* Fix ``StorageScheduler`` crash (``AttributeError: 'NoneType' object has no attribute 'event_resolution'``) when scheduling a site whose asset tree contains non-storage devices with only a ``power-capacity`` in their ``flex-model`` (no ``sensor`` key) [see `PR #2085 <https://github.com/FlexMeasures/flexmeasures/issues/2085>`_]


v0.32.3 | May 15, 2026
Expand Down Expand Up @@ -118,7 +119,6 @@ Bugfixes


v0.31.3 | April 11, 2026
============================

Bugfixes
-----------
Expand Down
2 changes: 1 addition & 1 deletion flexmeasures/data/models/planning/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,7 @@ def _prepare(self, skip_validation: bool = False) -> tuple: # noqa: C901
device_constraints[d]["efficiency"] = storage_efficiency[d]

# Convert efficiency from sensor resolution to scheduling resolution
if sensor_d.event_resolution != timedelta(0):
if sensor_d is not None and sensor_d.event_resolution != timedelta(0):
Copy link
Copy Markdown
Contributor

@Flix6x Flix6x Apr 2, 2026

Choose a reason for hiding this comment

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

I'm thinking of the case where the power sensor of the device is not mentioned in the flex-model of the API trigger message, but the device does have a storage-efficiency defined on the db flex-model.

The storage-efficiency will then become interpreted with respect to the scheduling resolution rather than the device's own power sensor resolution, and requesting the schedule in a different resolution would result in a different interpretation of the storage-efficiency over time.

This is a known shortcoming of our current implementation of the storage-efficiency (see #720), but your solution appears to me it might amplify the problem.

Four possible remedies I see going forward:

  1. Resolve Storage efficiency notation per any time unit. #720
  2. Keep requiring a sensor, but make it possible to define a power sensor in the db flex-model. feat: allow setting a power sensor in the flex-model of an asset when patching #2190
  3. If a storage-efficiency is defined in the db flex-model, and the corresponding power sensor is missing, throw a ValidationError.
  4. We document this shortcoming, for instance, in scheduling.rst under the storage-efficiency footnote, and move forward.

I'm assuming your device doesn't have a storage-efficiency, is that correct? Then 3 or 4 seem like a reasonable quick fix to me. Would you agree?

1 and/or 2 are the more long-term solutions, but they for sure require more work and whoever works on them might encounter complications along the way.

device_constraints[d]["efficiency"] **= (
resolution / sensor_d.event_resolution
)
Expand Down