dalsi
Some checks failed
CI and deploy / migration-check (push) Failing after 21s
CI and deploy / deploy (push) Has been skipped

This commit is contained in:
Dusan Vojacek
2026-05-23 00:34:52 +02:00
parent a52be1b792
commit 1ec92bdf79
5 changed files with 313 additions and 63 deletions

View File

@@ -276,6 +276,22 @@ def _select_discharge_export_slots(
]
candidates.sort(key=lambda x: (-x[1], -x[0]))
first_neg = next(
(i for i, s in enumerate(slots) if float(s.sell_price) < 0),
None,
)
neg_day = _prague_date(slots[first_neg]) if first_neg is not None else None
candidates = [
(t, sell)
for t, sell in candidates
if not (
neg_day is not None
and _prague_date(slots[t]) == neg_day
and _prague_hour(slots[t]) < 5
)
]
selected: set[int] = set()
cum = 0.0
for t, _sell in candidates:
@@ -284,31 +300,49 @@ def _select_discharge_export_slots(
selected.add(t)
cum += per_slot_wh
max_sell = max((float(s.sell_price) for s in slots), default=0.0)
if max_sell > 0:
if first_neg is not None and neg_day is not None:
evening_by_day: dict = {}
for t, s in enumerate(slots):
if float(s.sell_price) >= max_sell - degrad and float(s.sell_price) > sell_min:
selected.add(t)
d = _prague_date(s)
if _prague_hour(s) < 17:
continue
evening_by_day[d] = max(evening_by_day.get(d, 0.0), float(s.sell_price))
for t, s in enumerate(slots):
d = _prague_date(s)
peak = evening_by_day.get(d, 0.0)
if peak > 0 and _prague_hour(s) >= 17 and float(s.sell_price) >= peak - degrad:
if float(s.sell_price) > sell_min:
selected.add(t)
first_neg = next(
(i for i, s in enumerate(slots) if float(s.sell_price) < 0),
None,
)
preneg_min_soc = min_soc_wh + max(per_slot_wh, 1000.0)
if (
first_neg is not None
and first_neg > 0
and current_soc_wh >= preneg_min_soc
and neg_day is not None
):
neg_day = _prague_date(slots[first_neg])
positive = [
i
morning_sells = [
float(slots[i].sell_price)
for i in range(first_neg)
if float(slots[i].sell_price) >= 0 and _prague_date(slots[i]) == neg_day
if float(slots[i].sell_price) >= 0
and _prague_date(slots[i]) == neg_day
and 5 <= _prague_hour(slots[i]) <= 11
]
if positive:
peak_t = max(positive, key=lambda i: (float(slots[i].sell_price), i))
selected.add(peak_t)
if morning_sells:
zone_peak = max(morning_sells)
for i in range(first_neg):
if (
_prague_date(slots[i]) == neg_day
and 5 <= _prague_hour(slots[i]) <= 11
and float(slots[i].sell_price) >= zone_peak - degrad
):
selected.add(i)
for i in range(first_neg):
if _prague_date(slots[i]) != neg_day:
continue
h = _prague_hour(slots[i])
if 5 <= h < 17 and float(slots[i].sell_price) < zone_peak - degrad:
selected.discard(i)
return selected