Allow a storage unit to be energy neutral over its EnergyType period - #170
Merged
Conversation
erikfilias
force-pushed
the
feature/storage-energy-neutrality
branch
2 times, most recently
from
August 30, 2026 13:11
b4f2d39 to
7a72b6b
Compare
eESSInventory links a unit's inventory to its own past and bounds it, but nothing requires it to end a period where it started. For a store that is the right default. For demand-side management it is not: shifted consumption is meant to be recovered within a window, not displaced across the horizon, and a unit ending each day away from where it started quietly relaxes the shifting it represents. eMinimumEnergy and eMaximumEnergy already bound the energy a unit produces over an EnergyType period, using the same window. They cannot express neutrality, because they compare output against an exogenous profile whereas neutrality ties output to charge, and the level the two must agree on is decided by the optimisation rather than given. This reuses that period rather than introducing a second way to say daily or weekly: EnergyNeutrality opts a unit in, EnergyType sets the block. Both columns are optional and default to off, so cases written before them load unchanged.
erikfilias
force-pushed
the
feature/storage-energy-neutrality
branch
from
August 30, 2026 13:48
7a72b6b to
3d844c3
Compare
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.
Change
Lets a storage unit be energy neutral over a period: the net of discharge and charge across each
block must be zero. Two optional columns in
oT_Data_Generation—EnergyNeutralityopts the unitin, and the existing
EnergyTypesets the block. Both default to off.No existing case needs to change.
EnergyTypeis not a new column — every shipped case alreadyhas it, blank.
EnergyNeutralityis the only addition and is read with a fallback, so an absentcolumn means off. No shipped case sets it, and the full suite passes, including all 27 solve cases,
each reading a generation table written before this existed. With no unit opted in the constraint is
never built.
Rationale
eESSInventorylinks a unit's inventory to its own past and bounds it, but nothing requires it toend a period where it started. For a store that is the right default. For demand-side management it
is not: shifted consumption is meant to be recovered within a window, not displaced across the
horizon, and a unit ending each day away from where it started quietly relaxes the shifting it
represents. A formulation that states daily neutrality currently has no way to enforce it.
Relation to eMinimumEnergy and eMaximumEnergy
Those already bound the energy a unit produces over an
EnergyTypeperiod, over the same window andwith the same
idxEnergymapping. This constraint reuses that period deliberately rather thanadding a second way to say daily or weekly.
They cannot express neutrality, though. They compare
vTotalOutputagainst an exogenous profile;neutrality ties
vTotalOutputtovESSTotalCharge, and the level the two must agree on is decidedby the optimisation rather than given, so it cannot be written as a min/max pair. No charge-side
energy constraint exists either.
Example
A demand-response unit that must recover shifted consumption within the same day:
01_ES_DSMDaily01_ES_BatteryThe battery is untouched. The DSM unit gets one constraint at the end of each 24-hour block:
EnergyTypeofWeeklymakes it 168 hours, and so on through the existing vocabulary.Effect
None by default, since no shipped case sets either column. Full test suite passes, 106 tests
including the solve cases.