Advisory: integration branch for the multi-commodity + commitments PR family - #2301
Closed
Flix6x wants to merge 302 commits into
Closed
Advisory: integration branch for the multi-commodity + commitments PR family#2301Flix6x wants to merge 302 commits into
Flix6x wants to merge 302 commits into
Conversation
…multi-feed-stock # Conflicts: # flexmeasures/data/models/planning/tests/test_commitments.py
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>
This reverts commit 2becd02.
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>
Introduce stock_groups mapping to link multiple devices to a shared SOC. Aggregate stock delta across devices sharing the same battery. Update stock change calculation to use combined device flows. Add device-to-group and group-to-devices lookup for efficient shared stock computation. Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
…er and discharge later, rather than on the EPEX price transition, as the inline test documentation advertised Signed-off-by: F.N. Claessen <claessen@seita.nl>
…ckCommitment to prefer being full Signed-off-by: F.N. Claessen <claessen@seita.nl>
…artificial price slope 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>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
…itment, using a tiny price slope to prefer a fuller SoC sooner rather than later, by lowering penalties later 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>
This reverts commit bf16e63. Signed-off-by: F.N. Claessen <claessen@seita.nl>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
…ng resolution Signed-off-by: F.N. Claessen <claessen@seita.nl>
…eat/multi-commodity # Conflicts: # documentation/concepts/commitments.rst # flexmeasures/data/models/planning/__init__.py # flexmeasures/data/models/planning/storage.py
Flag explicitly that partially-specified commodity contexts used to leave capacities unlimited and hard-error on a missing consumption price, whereas they now get 0-capacity soft constraints and 0 prices; and that price-free contexts no longer trip a spurious cross-currency error against a differently-currencied portfolio. Signed-off-by: F.N. Claessen <claessen@seita.nl>
Move the relax-constraints breaking-change entry to the top of its section, and fold the PR #2271 hardening-fix summary into the existing multi-commodity feature entry (appending the PR reference) instead of listing it as a separate bugfix bullet. Signed-off-by: F.N. Claessen <claessen@seita.nl>
…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
…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>
…ulti-commodity-hardening
…nto feat/commodity-context-defaults # Conflicts: # documentation/changelog.rst
…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>
…nstraint analysis #2072, CI/agents #2275) Conflict resolution policy: - Schema layer: main's design wins wholesale (commodities list nesting, commodity default 'electricity', uniqueness + shared-currency validators). - Engine: main's #1946 multi-commodity device_scheduler plus this branch's coupling_groups primitive (coupling_alpha variables and per-device flow-coupling constraints), keeping the branch's group_to_devices mapping which supports overlapping stock-group membership. - storage.py: main's _prepare/_build_soc_schedule structure wins, with the branch's coupling-group construction re-added; main's strict price-presence validation is restored (the branch had it commented out). - Tests: kept both sides' distinct tests (branch: CHP coupling + factory dispatch; main: gas-only flex-model, per-commodity inflexible sensors, directional-capacity fallback). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016MLCUiSdXDqDBmg8GbYp1B
The sign of a coupling coefficient is inferred from directional capacities, and a device with both directions open (or blocked) was silently treated as an input. Reject such flex-models with a validation error instead. Also promote the coupling field descriptions to MetaData constants and document both fields in the storage flex-model table. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016MLCUiSdXDqDBmg8GbYp1B
Adds a balance_groups argument to device_scheduler: each group lists the devices of an internal commodity node (e.g. a heat or steam network without a grid connection) whose stock-side flows must sum to zero at every time step. This replaces the reference-device min=max=0 stock-group workaround used by the factory scenario, which is now tested in both modes. The StorageScheduler derives balance groups from the flex-config: a non-electricity commodity without energy prices becomes an internal node (previously this raised 'Missing consumption price'). Together with coupling groups (one flex-model entry per converter port), this makes the factory scenario (CHP + gas boiler + e-heater meeting a fixed steam demand) schedulable end-to-end through StorageScheduler.compute(). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016MLCUiSdXDqDBmg8GbYp1B
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016MLCUiSdXDqDBmg8GbYp1B
…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
…l combo branch Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016MLCUiSdXDqDBmg8GbYp1B
…efaults The smart defaults (#2272) fill a zero consumption-price into price-free commodity contexts, which defeated the priceless-commodity internal-node detection (#2279). Record durably on the context whether any price field was user-given (prices_are_defaulted), and treat a context whose prices were all defaulted as an internal node. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016MLCUiSdXDqDBmg8GbYp1B
…terms A device can sit in both a commodity balance group (via its commodity) and a shared-stock group (via its state-of-charge sensor), e.g. a steamer that discharges a heat buffer to produce steam. Its derivative efficiencies and stock delta (e.g. the buffer's soc-usage losses assigned to it) describe the stock-side conversion and must not leak into the commodity balance: what crosses the node is the device's power flow (ems_power). Found while running a realistic factory scenario, where the heat buffer's soc-usage drain was distorting the steam balance. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016MLCUiSdXDqDBmg8GbYp1B
…gregate flow A flex-context commitment gains an optional 'sensors' field: instead of binding each device of the matching commodity separately, the commitment binds the aggregate flow of the devices whose power sensors are listed, as one grouped commitment (device_group machinery). Useful to commit a band on a subset of devices, e.g. an aFRR upward-regulation band on a site's e-heaters (aggregate consumption >= band, deviation penalized). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016MLCUiSdXDqDBmg8GbYp1B
Documentation build overview
29 files changed ·
|
Member
Author
|
Consolidation status update (main has since absorbed the solver rewrite #2282/#2321/#2322/#2325 and merged #2272 + #2281): Done — rebased onto current main, tested, pushed (fast-forward, no history rewrite):
Remaining: #2295 (scoped commitments), UI #2284→#2287, #2285, then a refresh of this integration branch onto current main. The two fixes above are the ones flagged in the interaction notes — now landed on their respective PR branches. 🤖 update via Claude Code |
Member
Author
|
Closing this advisory now that only #2289 needs to land. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose — do not merge
This was a mock-main integration branch combining the open PRs of the multi-commodity/commitments family, opened to advise on merge order and cross-PR interactions.
Its advice has been carried out. Seven of the eight PRs it tracked are merged, and the branch itself is stale (last updated 2026-07-20). It is kept only as a record of the interactions found, which are noted below with how each was resolved.
Status of the family
main, greenThe recommended merge order was followed, with #2289 the only piece left.
How each interaction turned out
a) #2272 × #2289 — #2272's smart defaults fill in zero prices for bare commodity contexts, defeating #2289's internal-node detection. This was the real one. #2272 landed first, so #2289 carries the fix:
fill_grid_connection_defaultsrecords anis_internal_nodeflag, and_preparetreats a commodity as internal only when the user gave no grid-connection signal at all — neither prices nor capacity fields. A commodity given a capacity but no price still carries smart-defaulted zero prices, and still declares a grid connection, so it is not an internal node.b) #2285 × #2287 — moot. #2285 was closed without merging, so there is no
custom:prefix and no test to adapt.c) #2289 base — resolved; the balance rule sums plain
ems_power, and this is part of #2289.d) Squash-merging stacked branches conflicts spuriously — confirmed in practice, and the advice here was superseded by something better.
When #2218 was squash-merged, #2289 conflicted across 11 files, because
mainheld #2218's content as one commit with no shared history while #2289 carried its original commits. The recommendation above (rebase each branch onmainafter its base merges) works, but rewrites a branch that already has review history and needs a force-push.The approach actually used, which needs neither:
mainfrom just before the squash-merge commit.origin/maininto the stacked branch with-X ours.Step 4 is safe by construction: every conflict is then between two representations of the same content, so taking the stacked branch's side is correct rather than a judgement call. Verify by measuring the stacked branch's unique content before starting (
git diff <old stack base> <tip> --stat) and confirming the post-mergegit diff origin/main --statmatches — it did exactly, at 13 files / +405 −16.What has changed underneath the family since
Worth knowing for anyone reading this branch as a guide, as it predates all of the following:
Not included
🤖 Generated with Claude Code