flexmeasures.data.models.planning.highspy_optimization
Direct HiGHS (highspy) implementation of the device scheduler.
Warning
TWO MODELS TO KEEP IN SYNC
This module deliberately duplicates the mathematical model of the Pyomo implementation,
flexmeasures.data.models.planning.linear_optimization.device_scheduler(),
building the LP/MILP directly with the HiGHS Python API (highspy) instead.
The Pyomo implementation is the semantic reference:
any change to the variables, constraints or objective in device_scheduler MUST be mirrored here (and vice versa),
and the equivalence tests in tests/test_highspy_equivalence.py should be extended accordingly.
This trade-off (a second model to maintain) was accepted
because bypassing the Pyomo layer cuts roughly a second (single device) to several seconds (multiple devices)
of model construction and solution-ingestion overhead per scheduling job,
while the direct build takes milliseconds.
Deviations from the Pyomo implementation (all verified against the behavior of the appsi_highs path):
Rows whose computed bounds are impossible to satisfy for any finite value (upper bound of -inf, or lower bound of +inf, as happens when a commitment quantity is +/-inf) are skipped. On the Pyomo path such rows are rejected by HiGHS’
addRow(called by appsi) and thereby silently dropped, with the same net effect.Solver results and model objects are lightweight shims (see
HighspySolverResultsandHighspyModel) that expose the attributes callers actually consume, rather than Pyomo objects.
Functions
- flexmeasures.data.models.planning.highspy_optimization.device_scheduler_highspy(device_constraints: list[DataFrame], ems_constraints: DataFrame | list[DataFrame], commitment_quantities: list[Series] | None = None, commitment_downwards_deviation_price: list[Series] | list[float] | None = None, commitment_upwards_deviation_price: list[Series] | list[float] | None = None, commitments: list[DataFrame] | list[Commitment] | None = None, initial_stock: float | list[float] = 0, stock_groups: dict[int, list[int]] | None = None, ems_constraint_groups: list[list[int]] | None = None, device_power_bands: list[list[tuple[float, float]] | None] | None = None, coupling_groups: dict[str, list[tuple[int, float]]] | None = None, balance_groups: dict[str, list[int]] | None = None) tuple[list[Series], float, HighspySolverResults, HighspyModel]
Direct HiGHS implementation of
device_scheduler.Same inputs and same return contract as
flexmeasures.data.models.planning.linear_optimization.device_scheduler(), which also documents the semantics of all arguments; the third and fourth returned objects are lightweight shims rather than Pyomo objects (seeHighspySolverResultsandHighspyModel).
Classes
- class flexmeasures.data.models.planning.highspy_optimization.HighspyModel
Small stand-in for the Pyomo
ConcreteModelreturned bydevice_scheduler.Exposes the attributes that callers and tests consume:
commitment_costs: dict of realized costs per (original) commitmentcommodity_costs: dict of realized costs per commoditycosts: the objective value (a float;pyomo.environ.value()passes floats through unchanged, sovalue(model.costs)keeps working)dandj: the device and datetime index rangesems_power,device_power_up,device_power_down,device_power_sign: indexed variable views supportingvar[d, j].valueandvar.extract_values()
- __init__()