fix toolu
Some checks failed
CI and deploy / migration-check (push) Failing after 12s
CI and deploy / deploy (push) Has been skipped

This commit is contained in:
Dusan Vojacek
2026-05-12 22:41:35 +02:00
parent 851ec2b637
commit 30f16a14c2
2 changed files with 17 additions and 6 deletions

View File

@@ -145,6 +145,8 @@ Volitelně pak na celý součet aplikuje:
Tato logika je implementovaná přímo ve `build_buy_prices_96()` v `scripts/analysis/battery_sizing_screen.py`. Účel je screening nové lokality nebo obchodního modelu ještě před seedem do DB; nejde o náhradu `ems.fn_effective_buy_price`.
Skript navíc v `solve_one_day()` explicitně zakazuje současný import a export do sítě v jednom 15min slotu a zároveň současné nabíjení a vybíjení baterie. Tím se eliminuje artefakt, kdy by při výhodnějším `buy` než `sell` model vytvářel umělý „loop“ bez fyzického významu.
Ověření:
- spusť skript nad krátkým vzorkem OTE (`--price-csv` nebo `--db`) a zkontroluj vypsané shrnutí režimu nákupu

View File

@@ -41,8 +41,9 @@ E_d z PVGIS CSV (--pvgis-csv, opakovat pro více orientací); denní energie = E
NT/VT podle hodin Europe/Prague (--buy-nt-kwh, VT = NT + --buy-vt-surcharge-kwh),
nebo od raw OTE spotu: --buy-spot-add-fixed-kwh / --buy-spot-asym-pct; u všech režimů
lze přičíst --buy-distribution-kwh a --buy-other-fees-kwh a výslednou cenu násobit
--buy-vat-multiplier. Mikroinvertory / GEN nejsou; zelený bonus není v účelové funkci.
Výsledek = screening, ne nabídka.
--buy-vat-multiplier. Model explicitně zakazuje současný import+export a současné
nabíjení+vybíjení v jednom slotu. Mikroinvertory / GEN nejsou; zelený bonus není
v účelové funkci. Výsledek = screening, ne nabídka.
"""
from __future__ import annotations
@@ -404,15 +405,23 @@ def solve_one_day(
gexp = pulp.LpVariable.dicts("gexp", range(SLOTS_PER_DAY), lowBound=0)
gimp = pulp.LpVariable.dicts("gimp", range(SLOTS_PER_DAY), lowBound=0)
curt = pulp.LpVariable.dicts("curt", range(SLOTS_PER_DAY), lowBound=0)
batt_is_charging = pulp.LpVariable.dicts(
"batt_is_charging", range(SLOTS_PER_DAY), lowBound=0, upBound=1, cat="Binary"
)
grid_is_import = pulp.LpVariable.dicts(
"grid_is_import", range(SLOTS_PER_DAY), lowBound=0, upBound=1, cat="Binary"
)
prob += soc[0] == soc_start_wh
obj = []
for t in range(SLOTS_PER_DAY):
prob += ch[t] <= max_ch
prob += dis[t] <= max_dis
prob += gexp[t] <= max_exp
prob += gimp[t] <= max_imp
# Anti-loop constraints: a slot cannot both charge and discharge the battery,
# and it cannot both import from and export to the grid.
prob += ch[t] <= max_ch * batt_is_charging[t]
prob += dis[t] <= max_dis * (1 - batt_is_charging[t])
prob += gimp[t] <= max_imp * grid_is_import[t]
prob += gexp[t] <= max_exp * (1 - grid_is_import[t])
prob += curt[t] <= pv_wh[t]
prob += (
pv_wh[t] - curt[t] + dis[t] + gimp[t] == load_wh[t] + ch[t] + gexp[t]