Skip to content

Comments

Feat: Switching between gas and electricity#1934

Draft
Ahmad-Wahid wants to merge 24 commits intomainfrom
feat/switching-between-gas-and-electricity
Draft

Feat: Switching between gas and electricity#1934
Ahmad-Wahid wants to merge 24 commits intomainfrom
feat/switching-between-gas-and-electricity

Conversation

@Ahmad-Wahid
Copy link
Contributor

@Ahmad-Wahid Ahmad-Wahid commented Jan 27, 2026

This PR extends the Commitment model and device scheduler to support grouped devices within a single commitment.

Why

Until now, a commitment could apply to:

  • a single device, or
  • the entire EMS.

This was insufficient for real‑world setups such as:

  • multiple producers feeding a shared thermal buffer,
  • several devices jointly constrained by a single stock target,
  • aggregated soft limits that should be penalized once per group, not per device.

What changed

  • Commitments now support custom device groups, allowing a single

  • FlowCommitment or StockCommitment to aggregate over multiple devices.

  • The scheduler aggregates flows or stocks per device group and applies deviation penalties once per group per timestep.

  • Commitments may reference:

    • a single device,
    • multiple devices (via list‑valued device entries),
    • or multiple disjoint groups within the same commitment.
  • New Pyomo sets (cg, cjg) and constraints enforce grouped commitment
    equalities consistently for both flow and stock commitments.

  • Cost reporting correctly aggregates costs per logical commitment instead of
    duplicating them per device.

Result

This enables correct modelling of shared buffers and feeder‑level soft
constraints without artificial cost inflation or duplicated baselines.

How to test

1️⃣ Run the new unit test

 pytest -k test_multi_feed_device_scheduler_shared_buffer    

This test verifies:

  • two devices jointly satisfy a single stock target,
  • deviation costs are applied once per group, not per device,
  • gas and electricity commitments are costed separately and consistently.

2️⃣ Sanity‑check behaviour (what to look for)

  • Only one commitment group exists for the shared thermal buffer
  • Battery remains in its own independent group
  • Total commitment costs do not scale with number of devices
  • Electricity and gas costs match expected values

Flix6x and others added 19 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>
@read-the-docs-community
Copy link

read-the-docs-community bot commented Jan 27, 2026

Documentation build overview

📚 flexmeasures | 🛠️ Build #31222870 | 📁 Comparing ce307f8 against latest (e606e70)


🔍 Preview build

Show files changed (13 files in total): 📝 11 modified | ➕ 1 added | ➖ 1 deleted
File Status
changelog.html 📝 modified
genindex.html 📝 modified
index.html 📝 modified
py-modindex.html 📝 modified
_autosummary/flexmeasures.data.models.planning.html 📝 modified
_autosummary/flexmeasures.data.services.scheduling.html 📝 modified
_autosummary/flexmeasures.utils.html 📝 modified
_autosummary/flexmeasures.utils.job_utils.html ➖ deleted
api/v3_0.html 📝 modified
cli/change_log.html 📝 modified
concepts/commitments.html ➕ added
concepts/device_scheduler.html 📝 modified
plugin/customisation.html 📝 modified

@Flix6x Flix6x changed the base branch from main to docs/commitments-section January 27, 2026 19:43
Copy link
Contributor

@Flix6x Flix6x left a comment

Choose a reason for hiding this comment

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

Great draft! Let's start collecting todos in the PR description. We can decide what is in scope and what is out. One idea would be to split it up by feature:

Feature: multi-commodity

  • spec how we would encode the commodity per device in the flex-model
  • extend flex-model schema, limiting the commodity field to electricity and gas
  • exclude gas-fired devices from all current EMS commitments
  • add gas-price field to flex-context
  • set up gas commitment using gas-powered devices and gas-price
  • extend scheduling.rst
  • extend tutorial

Feature: beyond electricity and gas

  • add commodity field to commitment schema
  • document how to set up other commodities

Feature: multi-feed stocks

  • spec how we would encode the shared storage per device in the flex-model
  • extend flex-model schema
  • extend scheduling.rst
  • extend tutorial

Feature: multi-feed flows

  • spec how we would encode the shared capacity per device in the flex-model
  • extend flex-model schema
  • extend scheduling.rst
  • extend tutorial

Alternatively, we do one PR first to create support for all 3 features in the device_scheduler only, and touch the StorageScheduler just enough so we can safely experiment with the first two features in simulation. Then, once we're experienced we tackle the flex-model schema, and split up the documentation work for the 3 features.

NB for the schema speccing, we already have some results from a previous session regarding feature 3, in terms of defining a grid topology. I believe the design that came out of that should also fit the other two features, so we end up with a similar UX for what would at first glance appear to be three very different features.

)
commitments.append(
FlowCommitment(
name=device_commodity[d],
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm wondering whether we need commitments to be uniquely named, for the cost reporting (commitment_costs) in our StorageScheduler, and whether we need some way of computing totals. Something to check in the test by having an assert statement on the total expected electricity and gas costs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have added some assert statements, please look into them

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks. I think these must include some reasoning behind the values, though, because taking the scheduling results at face value and then asserting they are correct is rather worthless.

First follow-up question: why are the electricity costs negative?

Comment on lines +168 to +173
# ---- key behavioural check:
# total commitment cost should be <= 1 breach per group per timestep
#
# If baselines were duplicated, cost would be ~2x for the shared buffer.
expected_max_cost = len(index) * breach_price * 2
assert planned_costs <= expected_max_cost
Copy link
Contributor

Choose a reason for hiding this comment

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

A bit hard to follow, this one. Maybe there's something more straightforward we could use to check for the expected behaviour.

Copy link
Contributor

Choose a reason for hiding this comment

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

I still don't understand what these key behavioural checks are actually doing.

@Ahmad-Wahid Ahmad-Wahid self-assigned this Jan 31, 2026
Ahmad-Wahid and others added 5 commits January 31, 2026 17:23
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
…n-gas-and-electricity

# Conflicts:
#	flexmeasures/data/models/planning/tests/test_commitments.py
@Flix6x Flix6x mentioned this pull request Feb 13, 2026
2 tasks
Base automatically changed from docs/commitments-section to main February 18, 2026 12:48
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.

2 participants