Skip to content

Smarter commodity-context defaults and Commitment commodity field#2272

Open
Flix6x wants to merge 168 commits into
mainfrom
feat/commodity-context-defaults
Open

Smarter commodity-context defaults and Commitment commodity field#2272
Flix6x wants to merge 168 commits into
mainfrom
feat/commodity-context-defaults

Conversation

@Flix6x

@Flix6x Flix6x commented Jul 8, 2026

Copy link
Copy Markdown
Member

Description

New in-scope features for the multi-commodity flex-context (follow-up to #2172, stacked on #2271) ahead of the v1 release.

Commitment schema commodity field

  • CommitmentSchema gets an undocumented commodity field, defaulting to electricity, for internal bookkeeping — matching a commitment to the device(s) sharing that commodity. Not the documented way for API users to associate a commitment with a commodity; that remains the multi-commodity commodities list, one context per commodity.

Smarter defaults for commodity contexts

A commodity context that omits grid-connection fields now gets sensible defaults instead of raising or leaving the grid unconstrained, based on which fields are explicitly given:

  • Nothing given (e.g. bare {"commodity": "gas"}, no grid connection): zero site-consumption-capacity and zero site-production-capacity as soft constraints, unlimited site-power-capacity.
  • Only consumption-price given: unlimited site-power-capacity and site-consumption-capacity, 0 site-production-capacity.
  • Only production-price given: unlimited site-power-capacity and site-production-capacity, 0 site-consumption-capacity.
  • Only site-consumption-capacity given: unlimited site-power-capacity, that consumption capacity, 0 consumption-price, 0 site-production-capacity (and 0 production-price).
  • Only site-production-capacity given: unlimited site-power-capacity, that production capacity, 0 production-price, 0 site-consumption-capacity (and 0 consumption-price).
  • Only site-power-capacity given: hard constraint at that capacity; site-consumption/production-capacity equal to it; 0 consumption- and production-price.

A relax-constraints: False context that ends up with a smart-defaulted 0 hard capacity now logs a warning, since this can make the schedule infeasible.

Correctness fix (found while implementing the above)

  • A commodity context with no user-given price fields was stamped with a fallback "EUR" currency, which could spuriously trip cross-commodity currency-mismatch checks against a differently-currencied portfolio. Such price-free contexts are now tagged and excluded from the mismatch check; their fallback-currency fields get re-expressed under the portfolio's real currency once it's known (from a top-level price or a sibling commodity context).
  • StorageScheduler.convert_to_commitments now logs a warning when a commitment's commodity matches zero devices (aid for catching typos).

Regression tests

7 parametrized DB-free cases for the 6 smart-default cases (+ a multi-field combination); price-free-context currency handling (top-level price sets currency, sibling context sets currency, nothing given anywhere falls back to EUR, genuine mismatches still 422).

  • Added changelog item in documentation/changelog.rst

How to test

pytest flexmeasures/data/schemas/tests/test_scheduling.py flexmeasures/data/models/planning/tests/test_commitments.py

Related Items

Stacked on #2271; follow-up to #2172; prepares #1946 for release.

Flix6x and others added 30 commits December 5, 2025 16:50
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
…ontext

Signed-off-by: F.N. Claessen <felix@seita.nl>
…formulation

Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
…and map them to the respective group id

Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
…chemas

Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
Flix6x added 3 commits July 8, 2026 13:37
…regate fields

Per self-review: these commented-out notes on aggregate-consumption
and aggregate-production are intentional placeholders for planned
future UI support, not dead code to remove.

Signed-off-by: F.N. Claessen <claessen@seita.nl>
The field's comment previously read like it documented a supported way
to bind a commitment to a commodity. Clarify that it's internal
bookkeeping, and that the documented way to associate a commitment
with a commodity is to place it under the relevant entry of the
multi-commodity flex-context's commodities list.

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

# Conflicts:
#	documentation/changelog.rst
Signed-off-by: F.N. Claessen <claessen@seita.nl>

# Conflicts:
#	flexmeasures/data/models/planning/storage.py
#	flexmeasures/data/services/scheduling.py

@Flix6x Flix6x left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Self-review.

Comment thread documentation/changelog.rst Outdated
Comment thread flexmeasures/data/schemas/scheduling/__init__.py Outdated
Comment thread flexmeasures/data/schemas/scheduling/__init__.py Outdated
Comment thread flexmeasures/data/schemas/scheduling/__init__.py Outdated
@Flix6x Flix6x self-assigned this Jul 8, 2026
@Flix6x Flix6x added this to the 1.0.0 milestone Jul 8, 2026
Copilot AI and others added 3 commits July 8, 2026 17:29
…2274)

Context:
- PR #2072 added scheduling_result output to StorageScheduler.compute()
  when return_multiple=True, and added _compute_unresolved_targets.
- In single-sensor mode (self.sensor is set), flex_model entries lack a
  "sensor" key, so _compute_unresolved_targets was skipping every device
  and returning empty unresolved/resolved lists.

Changes:
- storage.py: fall back to self.sensor in _compute_unresolved_targets
  when the flex_model entry has no "sensor" key (single-sensor mode)
- test_commitments.py: update schedule-count assertions (+1 for the new
  scheduling_result entry added by PR #2072)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Flix6x <30658763+Flix6x@users.noreply.github.com>
…nto feat/commodity-context-defaults

# Conflicts:
#	documentation/changelog.rst
Base automatically changed from fix/multi-commodity-hardening to main July 8, 2026 18:31
Flix6x added 3 commits July 8, 2026 20:39
…t-defaults

chore: update openapi-specs.json

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>
@Flix6x Flix6x requested a review from Ahmad-Wahid July 8, 2026 19:27
@Flix6x Flix6x added documentation Improvements or additions to documentation AI Infra labels Jul 8, 2026

@nhoening nhoening left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Very nice that we have this, another improvement to make flex-configuration have less unexplainable failures.
There might be new questions if things default to something, but at least we make it explicit, and this can also be read by LLMs which can hopefully offer useful answers.

Comment thread documentation/features/scheduling.rst Outdated
For multi-commodity scheduling problems, each entry of the top-level ``commodities`` list is itself a flex-context (a "commodity context") describing the grid connection for that commodity.
A commodity context that leaves out some or all of its grid-connection fields (``consumption-price``, ``production-price``, ``site-consumption-capacity``, ``site-production-capacity`` and ``site-power-capacity``) gets sensible defaults for the missing fields, rather than failing or silently leaving the grid unconstrained.

As a rule of thumb, a price given for a direction (consumption or production) implies a grid connection in that direction, with an unlimited capacity unless a capacity is also given; a capacity given for a direction (without a price) implies a 0 price in that direction; and anything not implied by a given field defaults to "no connection" (0 capacity, as a soft constraint).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does "a 0 price" refer to a peak price or usage (energy/power) price ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Usage.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

But you are right, that can be made more explicit, maybe by writing zero consumption/production-price. (I actually prefer zero over 0 in these sentences.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Clarified in dff1977: the docs now say "a zero consumption-price or production-price (respectively)", and "zero" is preferred over "0" throughout the section.

Comment thread documentation/features/scheduling.rst Outdated
This leads to the following defaults, depending on which fields are explicitly given:

- **Nothing given** (e.g. just ``{"commodity": "gas"}``): both ``site-consumption-capacity`` and ``site-production-capacity`` default to 0, as soft constraints (a breach is possible, but penalized). ``site-power-capacity`` stays unlimited.
- **Only** ``consumption-price``: ``site-power-capacity`` and ``site-consumption-capacity`` stay unlimited; ``site-production-capacity`` defaults to 0 (soft).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
- **Only** ``consumption-price``: ``site-power-capacity`` and ``site-consumption-capacity`` stay unlimited; ``site-production-capacity`` defaults to 0 (soft).
- **Only** ``consumption-price``: Then,``site-power-capacity`` and ``site-consumption-capacity`` stay unlimited; ``site-production-capacity`` defaults to 0 (soft).

I got confused, trying to help reading flow

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Applied in dff1977 (the "Then, ..." phrasing is used in the site-consumption-capacity and site-power-capacity bullets as well).

Comment thread documentation/features/scheduling.rst Outdated
- **Nothing given** (e.g. just ``{"commodity": "gas"}``): both ``site-consumption-capacity`` and ``site-production-capacity`` default to 0, as soft constraints (a breach is possible, but penalized). ``site-power-capacity`` stays unlimited.
- **Only** ``consumption-price``: ``site-power-capacity`` and ``site-consumption-capacity`` stay unlimited; ``site-production-capacity`` defaults to 0 (soft).
- **Only** ``production-price``: the mirror image, for production.
- **Only** ``site-consumption-capacity``: ``site-power-capacity`` stays unlimited; ``consumption-price`` defaults to 0; ``site-production-capacity`` (and, transitively, ``production-price``) default to 0.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
- **Only** ``site-consumption-capacity``: ``site-power-capacity`` stays unlimited; ``consumption-price`` defaults to 0; ``site-production-capacity`` (and, transitively, ``production-price``) default to 0.
- **Only** ``site-consumption-capacity``: Then, ``site-power-capacity`` stays unlimited; ``consumption-price`` defaults to 0; ``site-production-capacity`` (and, transitively, ``production-price``) default to 0.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Applied in dff1977.

Comment thread documentation/features/scheduling.rst Outdated
- **Nothing given** (e.g. just ``{"commodity": "gas"}``): both ``site-consumption-capacity`` and ``site-production-capacity`` default to 0, as soft constraints (a breach is possible, but penalized). ``site-power-capacity`` stays unlimited.
- **Only** ``consumption-price``: ``site-power-capacity`` and ``site-consumption-capacity`` stay unlimited; ``site-production-capacity`` defaults to 0 (soft).
- **Only** ``production-price``: the mirror image, for production.
- **Only** ``site-consumption-capacity``: ``site-power-capacity`` stays unlimited; ``consumption-price`` defaults to 0; ``site-production-capacity`` (and, transitively, ``production-price``) default to 0.

@nhoening nhoening Jul 9, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If site-consumption-capacity and site-production-capacity are given, and site-power-capacity unlimited, I see the point.

What would happen actually, if all would be given? Is that maybe not valid?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

That's perfectly valid. The site-consumption/production-capacities will be used as a soft constraints, and the site-power-constraint will be used as a hard constraint.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Documented in dff1977: "Giving all capacity fields is perfectly valid, too: the directional capacities then act as soft constraints, within the hard site-power-capacity limit."



def test_commitment_commodity_does_not_bind_other_commodity_devices():
"""test_commitment_commodity_does_not_bind_other_commodity_devices: a commitment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
"""test_commitment_commodity_does_not_bind_other_commodity_devices: a commitment
"""a commitment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Applied in dff1977.

Flix6x and others added 2 commits July 10, 2026 20:56
…t-defaults

# Conflicts:
#	.claude/agents/api-backward-compatibility-specialist.md
#	.claude/agents/architecture-domain-specialist.md
#	.claude/agents/coordinator.md
#	.claude/agents/data-time-semantics-specialist.md
#	.claude/agents/documentation-developer-experience-specialist.md
#	.claude/agents/performance-scalability-specialist.md
#	.claude/agents/test-specialist.md
#	.claude/agents/tooling-ci-specialist.md
#	.claude/agents/ui-specialist.md
- Give this PR its own concise changelog entry (pointing at the new
  commodity_context_defaults docs section) instead of only tagging the
  multi-commodity entry.
- Reword the smart-defaults docs per review: prefer 'zero' over '0',
  clarify that zero prices refer to the usage (energy) prices, adopt the
  suggested 'Then, ...' phrasing in the per-case bullets, and state that
  giving all capacity fields is valid (directional capacities soft within
  the hard site-power-capacity limit).
- Drop the redundant test-name prefix from a test docstring.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016MLCUiSdXDqDBmg8GbYp1B
@Flix6x

Flix6x commented Jul 10, 2026

Copy link
Copy Markdown
Member Author

Interaction note with #2279: the smart defaults fill a zero consumption-price into price-free commodity contexts, which defeats #2279's internal-node detection (a priceless commodity like a steam network should become a hard balance node). Tested fix on a local merge of both branches: record prices_are_defaulted in fill_grid_connection_defaults (this PR's code) and consume it in _prepare (#2279's code). I'll open the follow-up PR once both have landed; no change needed here.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Infra documentation Improvements or additions to documentation Scheduling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants