OSTEC Simple Module¶
Type: OSTEC_SIMPLE
Category: Local Optimization
Maturity: PRODUCTION (v2.0.0)
OSTEC Simple uses Mixed Integer Linear Programming (MILP) to optimize a community's flexible resources — batteries, EVs, and electric water heaters — over a rolling horizon.
What It Optimizes¶
The optimizer minimizes the total energy cost for the community by deciding:
- Battery storage: when to charge and when to discharge
- EV charging: optimal charging schedule given connection forecasts
- EWH: when to heat water based on tariff periods
Input Data¶
| Input | Source | Description |
|---|---|---|
| Energy forecasts | External (pushed via API) | Predicted consumption/production per meter |
| OMIE prices | OMIE router | Day-ahead market prices (€/kWh) |
| Grid tariffs | ERSE tariffs | Time-of-use network charges |
| Storage state | Database | Current battery state of charge (SOC) |
| EV connection forecast | Database | Predicted EV connection windows |
| Opportunity costs | Database | Resource-level cost overrides |
Optimization Horizon¶
Controlled by the configuration:
| Parameter | Description |
|---|---|
horizon |
Number of hours to optimize (e.g., 24 for day-ahead) |
delta_t |
Time step size in hours (1.0 = hourly, 0.5 = 30-minute) |
Decision Variables¶
For each resource r and time step t:
| Variable | Type | Description |
|---|---|---|
p_charge[r,t] |
Continuous | Charge power (kW) |
p_discharge[r,t] |
Continuous | Discharge power (kW) |
soc[r,t] |
Continuous | State of charge (kWh) |
u_charge[r,t] |
Binary | Charging active (1/0) |
u_discharge[r,t] |
Binary | Discharging active (1/0) |
Objective Function¶
Minimize total energy cost across all meters and time steps:
minimize Σ_{m,t} [ l_grid[m,t] · p_grid_import[m,t]
- l_lem[m,t] · p_lem_sell[m,t]
+ l_market_buy · p_market_buy[t]
- l_market_sell · p_market_sell[t]
+ l_extra · slack[m,t] ]
Where:
l_grid— grid import price (tariff + OMIE) (€/kWh)l_lem— LEM selling price (€/kWh)l_market_buy/sell— penalty bounds for market imbalancel_extra— penalty for constraint relaxation
Key Constraints¶
- Power balance: at each timestep, generation + discharge + grid_import = consumption + charge + grid_export
- SOC continuity:
soc[t] = soc[t-1] + charge_eff·p_charge[t]·Δt - p_discharge[t]·Δt/discharge_eff - Capacity bounds:
soc_min ≤ soc[t] ≤ capacity_kwh - Power bounds:
0 ≤ p_charge[t] ≤ power_kw · u_charge[t] - Mutual exclusion:
u_charge[t] + u_discharge[t] ≤ 1 - EV availability:
p_charge[t] = 0when EV is not connected
Supported Solvers¶
| Solver | Open Source | Notes |
|---|---|---|
CPLEX |
No | Best performance; requires IBM license |
CBC |
Yes | Good for small/medium instances |
GLPK |
Yes | Slower; fallback option |
Output¶
For each resource and time step, the module writes an EnergySetpoint record to the database:
setpoint_value— the commanded power (kW)setpoint_type—STORAGE_CHARGE,STORAGE_DISCHARGE,EV_CHARGE,EWH_HEATINGcalculation_metadata— solver status, objective value, solve time
Configuration Schema¶
| Field | Default | Description |
|---|---|---|
l_extra |
10.0 |
Penalty cost for slack variables (€/kWh) |
l_market_buy |
500.0 |
Upper bound on market buy price (€/kWh) |
l_market_sell |
-500.0 |
Lower bound on market sell price (€/kWh) |
solver |
"CPLEX" |
MILP solver to use |