Skip to content

Sign convention for consumption/production output sensors in schedule retrieval#2205

Draft
Copilot wants to merge 34 commits into
mainfrom
copilot/featsensor-in-db-flex-model
Draft

Sign convention for consumption/production output sensors in schedule retrieval#2205
Copilot wants to merge 34 commits into
mainfrom
copilot/featsensor-in-db-flex-model

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 27, 2026

make_schedule was calling result_sensor.set_attribute("consumption_is_positive", True/False) to tag output sensors, but set_attribute only updates existing attributes—it silently no-ops on new ones. So get_schedule always fell through to the default sign flip, returning inverted values for dedicated output sensors.

Approach

Store output sensor roles in the scheduler's data source rather than on the sensor itself. This follows the existing reporter/forecaster pattern for data_source.attributes["data_generator"]["config"] and survives job TTL expiry.

Changes

  • flexmeasures/data/services/scheduling.py — Remove broken set_attribute("consumption_is_positive", …) calls. Collect output sensor roles during the save loop and persist them as data_source.attributes["data_generator"]["config"]["output_sensor_roles"] (keyed by sensor ID → "consumption" | "production").

  • flexmeasures/api/v3_0/sensors.pyget_schedule now checks the data source config for the requested sensor before deciding on sign. Dedicated output sensors skip the sign flip (their DB values are already stored in the correct convention).

  • flexmeasures/api/v3_0/tests/test_sensor_schedules_fresh_db.py — 4 new parametrized tests (consumption × production × JSON flex-model × DB flex-model) asserting correct sign conventions end-to-end.

  • Docs — Added production-sensor example to the get_schedule OpenAPI spec; updated documentation/api/notation.rst with sign convention details for output sensors.

Sign convention summary

Sensor type DB convention API convention
Main power sensor production-positive consumption-positive (flipped)
Consumption output consumption-positive consumption-positive (no flip)
Production output production-positive production-positive (no flip)

Flix6x and others added 30 commits May 18, 2026 19:35
… patching

Signed-off-by: F.N. Claessen <claessen@seita.nl>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
… DBStorageFlexModelSchema

Signed-off-by: F.N. Claessen <claessen@seita.nl>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
Context:
- StorageScheduler could already write state-of-charge schedules to a secondary sensor
- Users wanted the same for consumption and production power
Change:
- Add StorageScheduler._build_consumption_production_schedules() static method
- Call it in compute(), with resampling and rounding matching the soc_schedule pattern
- If only consumption sensor defined: full power profile (consumption positive, production negative)
- If only production sensor defined: full power profile inverted (production positive, consumption negative)
- If both defined: split — non-negative part to consumption sensor, sign-flipped non-positive part to production sensor
- Include results in return_multiple output as consumption_schedule / production_schedule entries
- Sign convention is encoded in the key name so no consumption_is_positive attribute is needed
…ut sensors

Context:
- StorageScheduler now supports writing schedules to consumption and production sensors
Change:
- test_battery_solver_multi_commitment: add consumption and production output sensors
  to the battery, include them in the flex-model, and verify unit conversion (MW → kW)
  and the split logic (all-positive schedule → consumption all positive, production all zero)
- test_trigger_schedule_uses_state_of_charge_sensor_for_soc_at_start: add production
  output sensor and verify 96 beliefs are stored after scheduling
- test_add_storage_schedule_uses_state_of_charge_sensor_for_soc_at_start: add consumption
  output sensor and verify 48 beliefs are stored after scheduling
… changelog entry

Context:
- StorageScheduler now writes schedules to consumption/production sensors
Change:
- Expand CONSUMPTION and PRODUCTION metadata descriptions with the split logic
  (only consumption, only production, or both defined) and clarify that the sign
  convention is encoded in the key name (no consumption_is_positive attribute needed)
- Add changelog entry in v0.33.0 New features section (PR number TBD)
Signed-off-by: F.N. Claessen <claessen@seita.nl>
Fixes #2084

Context:
- StorageScheduler._prepare crashes with AttributeError when a device
  in the asset tree has no sensor in its flex-model (only power-capacity)
- Lines 672 and 740 already guard sensor_d against None, but line 902
  was missed

Change:
- Add 'sensor_d is not None' check before accessing event_resolution
- Matches the existing pattern used elsewhere in the same method

Signed-off-by: F.N. Claessen <claessen@seita.nl>
…x-model

# Conflicts:
#	documentation/changelog.rst
…o the scheduling resolution

Signed-off-by: F.N. Claessen <claessen@seita.nl>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
…ution

Signed-off-by: F.N. Claessen <claessen@seita.nl>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
…roduction output schedules

The StorageScheduler already applies correct sign conventions when returning
consumption/production schedules (e.g., production values are inverted to be
positive). However, the persistence layer was then applying the default power
sensor sign logic again, negating this carefully applied inversion.
This resulted in production sensors receiving negative values when they should
receive positive values, and vice versa for consumption sensors.
Solution: Skip the default sign inversion logic for consumption and production
output schedules (identified by result["name"] being "consumption_schedule"
or "production_schedule"), as their sign convention is already correctly
encoded by the scheduler.
…nsors

The previous fix was too broad - it skipped sign inversion for any result named
"consumption_schedule" or "production_schedule", but this broke backwards
compatibility with custom schedulers that return Series wrapped as such.
The key distinction is whether the result sensor is the main asset_or_sensor
(main power schedule) or a dedicated output sensor (consumption/production split).
New logic:
- If result_sensor == asset_or_sensor (or its sensor): it's the main power schedule
  → Apply default sign logic (backwards compat and regular storage schedules)
- If result_sensor is different AND result name is consumption/production: it's an
  output sensor → Skip sign logic (already handled by scheduler)
This ensures both the new consumption/production output features and existing
custom schedulers work correctly.

Signed-off-by: F.N. Claessen <claessen@seita.nl>
New function _resolve_schedule_output_sign() encapsulates the logic for
determining whether sign conversion is needed for a schedule output result.
Benefits:
- Clearer expression of intent (function name documents purpose)
- Proper RST docstring with parameter and return descriptions
- Inline comments explain the differentiation between main power schedules
  and consumption/production output schedules
- Easier to test and reuse logic if needed elsewhere
- make_schedule() is now more readable with the core logic delegated
No functional changes - purely a refactoring for code clarity.
…ion and production sensors to make sure the get_schedule doesn't flip the sign

Signed-off-by: F.N. Claessen <claessen@seita.nl>
…to copilot/featsensor-in-db-flex-model

Co-authored-by: Flix6x <30658763+Flix6x@users.noreply.github.com>
…tributes

Co-authored-by: Flix6x <30658763+Flix6x@users.noreply.github.com>
Copilot AI and others added 2 commits May 27, 2026 14:25
…details

Co-authored-by: Flix6x <30658763+Flix6x@users.noreply.github.com>
Co-authored-by: Flix6x <30658763+Flix6x@users.noreply.github.com>
Copilot AI changed the title Sign Convention for Consumption/Production Output Sensors in Schedule Retrieval Sign convention for consumption/production output sensors in schedule retrieval May 27, 2026
Copilot finished work on behalf of Flix6x May 27, 2026 14:28
Copilot AI requested a review from Flix6x May 27, 2026 14:29
@Flix6x Flix6x changed the base branch from main to feat/sensor-in-db-flex-model May 27, 2026 14:32
Base automatically changed from feat/sensor-in-db-flex-model to main May 30, 2026 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants