tuning BA81
This commit is contained in:
@@ -577,9 +577,12 @@ def solve_dispatch(
|
||||
if horizon_slots_h24 > 0
|
||||
else 4.0
|
||||
)
|
||||
terminal_factor = float(
|
||||
getattr(battery, "planner_terminal_soc_value_factor", TERMINAL_SOC_VALUE_FACTOR)
|
||||
)
|
||||
# Kč/Wh: ocenění energie ponechané v baterii na konci horizontu (receding horizon kotva).
|
||||
terminal_soc_kcz_per_wh = (
|
||||
avg_buy_terminal * TERMINAL_SOC_VALUE_FACTOR / 1000.0
|
||||
avg_buy_terminal * terminal_factor / 1000.0
|
||||
)
|
||||
|
||||
# Kotva: poslední slot před prvním sell<0 by měl končit u planner floor (pokud relaxace existuje).
|
||||
@@ -687,6 +690,11 @@ def solve_dispatch(
|
||||
if s.sell_price < 0:
|
||||
prob += w_arb[t] == 0
|
||||
prob += bd[t] <= pulp.lpSum(ev_via_bat[e][t] for e in range(EV))
|
||||
# BA81 (GEN port microinverters): pokud máme k dispozici GEN cut-off, držíme skutečný
|
||||
# BLOCK_EXPORT jako hard constraint: export do sítě v okně se záporným prodejem je zakázaný.
|
||||
# Přebytek pak řeší curtail PV A / nabíjení / případně GEN cut-off (reg 179).
|
||||
if z_gen_cutoff is not None:
|
||||
prob += ge[t] == 0
|
||||
|
||||
soc_prev_expr = current_soc_wh if t == 0 else soc[t - 1]
|
||||
arb_t = arb_floor_series[t]
|
||||
|
||||
9
db/migration/V062__planner_terminal_soc_value_factor.sql
Normal file
9
db/migration/V062__planner_terminal_soc_value_factor.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
alter table ems.asset_battery
|
||||
add column if not exists planner_terminal_soc_value_factor numeric not null default 0.9;
|
||||
|
||||
comment on column ems.asset_battery.planner_terminal_soc_value_factor is
|
||||
'Váha terminal SoC shadow price v LP solveru.
|
||||
0 = solver nemá motivaci držet energii v baterii na konci horizontu (agresivnější arbitráž / vybití).
|
||||
1 = odpovídá ~průměrné nákupní ceně (konzervativní držení energie).
|
||||
Používá se v backend/services/planning_engine.py (terminal_soc_kcz_per_wh).';
|
||||
|
||||
@@ -130,6 +130,13 @@ begin
|
||||
raise exception 'No site_grid_connection for site_id=%', p_site_id;
|
||||
end if;
|
||||
|
||||
-- LP tuning (battery-level): terminal SoC shadow price factor
|
||||
v_b := jsonb_set(
|
||||
v_b,
|
||||
'{planner_terminal_soc_value_factor}',
|
||||
to_jsonb(coalesce((v_b->>'planner_terminal_soc_value_factor')::numeric, 0.9))
|
||||
);
|
||||
|
||||
select coalesce(
|
||||
jsonb_agg(
|
||||
jsonb_build_object(
|
||||
|
||||
@@ -80,7 +80,7 @@ Z toho plyne: **cut-off GEN portu je smysluplné řídit podle očekávaného p
|
||||
## EMS politiky (nejsou fyzické stavy Deye)
|
||||
|
||||
- **PV_SELL_ONLY:** AUTO + constraint solveru `max_discharge_from_pv`
|
||||
- **BLOCK_EXPORT:** AUTO + záporná sell_price → `ge[t]=0`
|
||||
- **BLOCK_EXPORT:** AUTO + záporná sell_price → `ge[t]=0` (hard constraint, pokud má lokalita k dispozici GEN port cut-off; jinak solver export jen penalizuje přes zápornou cenu)
|
||||
- **NEGATIVE_HARVEST:** AUTO + záporná buy_price → max charge/load
|
||||
- **PROTECT:** SELF_SUSTAIN s konzervativními limity
|
||||
|
||||
|
||||
@@ -471,6 +471,17 @@ COMMENT ON COLUMN ems.planning_interval.pv_a_curtailed_w IS
|
||||
|
||||
---
|
||||
|
||||
## Tuning pro malé baterie (např. BA81)
|
||||
|
||||
Pokud solver „šetří baterku“ a raději importuje ze sítě (kvůli terminal SoC shadow price), lze per baterii upravit váhu této kotvy:
|
||||
|
||||
- `ems.asset_battery.planner_terminal_soc_value_factor`
|
||||
- `0.0` = žádná motivace držet SoC na konci horizontu (agresivnější arbitráž / vybití)
|
||||
- `0.9` = default (konzervativnější držení energie)
|
||||
|
||||
Pro BA81 typicky dává smysl menší hodnota (např. 0–0.3), aby solver klidně „vylil“ baterii do sítě při kladné `sell_price`
|
||||
a nechal si kapacitu na nabití v oknech záporných cen.
|
||||
|
||||
## Konfigurace (env proměnné)
|
||||
|
||||
```env
|
||||
|
||||
Reference in New Issue
Block a user