Where
edisgo/io/powermodels_io.py (in to_powermodels):
pm["time_elapsed"] = int(
(psa_net.snapshots[1] - psa_net.snapshots[0]).seconds / 3600
) # length of timesteps in hours
This single global value drives all inter-timestep couplings in the Julia OPF (battery,
heat storage, DSM energy balances, EV charging energy).
Three independent defects
.seconds instead of .total_seconds() — .seconds is the seconds component of the
Timedelta (0–86399), not its total duration. A gap of exactly 1 day yields 0; a gap of
25 h yields 1 h. Silently wrong.
int(...) truncation — 15-min resolution: int(900/3600) = int(0.25) = 0. With
time_elapsed = 0 the storage coupling se₂ − se₁ == −0·ps₂ degenerates to 0 == 0 for
any ps: power and energy are completely decoupled. The battery becomes an
inexhaustible storage with no energy accounting (results look plausible — power bounds are
respected — but are physically meaningless). With flexible charging points the model becomes
infeasible instead (cpe₂ == cpe₁ is forced while the flexibility-band midpoint moves).
Real 15-min runs have been executed and were affected by this.
- Only the first snapshot gap is used, globally — non-equidistant time indices are
silently mis-scaled for every step after the first.
Suggested fix
Where
edisgo/io/powermodels_io.py(into_powermodels):This single global value drives all inter-timestep couplings in the Julia OPF (battery,
heat storage, DSM energy balances, EV charging energy).
Three independent defects
.secondsinstead of.total_seconds()—.secondsis the seconds component of theTimedelta(0–86399), not its total duration. A gap of exactly 1 day yields0; a gap of25 h yields 1 h. Silently wrong.
int(...)truncation — 15-min resolution:int(900/3600) = int(0.25) = 0. Withtime_elapsed = 0the storage couplingse₂ − se₁ == −0·ps₂degenerates to0 == 0forany
ps: power and energy are completely decoupled. The battery becomes aninexhaustible storage with no energy accounting (results look plausible — power bounds are
respected — but are physically meaningless). With flexible charging points the model becomes
infeasible instead (
cpe₂ == cpe₁is forced while the flexibility-band midpoint moves).Real 15-min runs have been executed and were affected by this.
silently mis-scaled for every step after the first.
Suggested fix
total_seconds(), keep the value afloat(the Julia side handles non-integer hours;note the interaction with the heat-storage standing-loss exponent, see [BUG] Heat-storage standing loss uses fixed exponent
(1-p_loss)^(1/24)— wrong for non-hourly timesteps #697).to_powermodels: snapshots must beequidistant and contiguous, otherwise raise. The OPF's time-coupling formulation is
meaningless across gaps.