Skip to content

solar_cap: MIN_CHARGE_RATE (500 W) verbraucht die reservierte Kapazitaet am Anfang des Clip-Fensters #409

Description

@MaStr

Zusammenfassung

Die solar_cap-Regel setzt bei knapper freier Kapazitaet bewusst cap == floor, damit die Batterie ausschliesslich Clip-Energie aufnimmt und exportierbarer Ueberschuss ins Netz geht statt Kapazitaet zu belegen. Am Anfang des Clip-Fensters ist der Floor aber noch klein (zweistellige bis niedrige dreistellige Watt), und enforce_min_pv_charge_rate() hebt jeden Wert zwischen 1 und 499 W auf 500 W an. Die Batterie laedt dadurch ein Vielfaches der beabsichtigten Menge und verbraucht genau die Reserve, die die Regel kurz zuvor geschuetzt hat -- mit der Folge, dass am Peak abgeregelt wird.

Netto regelt solar_cap allein in unserem Beispieltag mehr ab als die reine Zeit-Regel, obwohl es die Anti-Abregelungs-Regel ist.

Reproduktion

python scripts/generate_peak_shaving_csv.py

Ergebnis fuer den Beispieltag (10 kWh Batterie, PV-Peak 5000 W, Grundlast 400 W, feed_in_limit_w: 4000, 15-min-Aufloesung):

Konfiguration Batterie voll abgeregelt
ohne Peak Shaving 11:45 1,03 kWh
nur time based 14:00 0,01 kWh
nur solar_cap 13:30 0,20 kWh
time + solar_cap 15:15 0,00 kWh

Sichtbar auch im Chart auf der Doku-Seite features/peak-shaving-scenarios.md (Szenario "Solar cap only").

Ursache

Auszug aus docs/assets/data/peak_shaving/solar.csv:

time,surplus_w,limit_w,charge_w,curtailed_w,soc_pct,rule_floor_w
11:45,4054.3,500,500.0,0.0,90.85,54
12:00,4243.5,500,500.0,0.0,92.10,243
12:15,4396.2,500,500.0,0.0,93.35,396
...
13:30,4508.4,508,399.4,109.0,100.00,508
13:45,4396.2,500,0.0,396.2,100.00,396
14:00,4243.5,500,0.0,243.5,100.00,243
14:15,4054.3,500,0.0,54.3,100.00,54

Rechnung fuer die drei ersten Clip-Slots:

Clip-Energie (54 + 243 + 396) W * 0,25 h = 173,2 Wh   <- beabsichtigt
tatsaechlich geladen 500 W * 0,25 h * 3  = 375,0 Wh
Ueberschuss                              = 201,8 Wh

Die spaeter abgeregelte Energie betraegt (109,0 + 396,2 + 243,5 + 54,3) W * 0,25 h = 200,8 Wh -- also praktisch exakt der Betrag, den die Mindestladerate vorne zu viel eingeladen hat.

Codepfad

src/batcontrol/logic/solar_limit.py (Case B, knappe Kapazitaet) setzt den Cap gleich dem Floor:

extra_wh = max(0.0, free_capacity_wh - remaining_clip_wh)   # 0
cap_w = int(floor_w + extra_wh / remaining_prod_h)          # == floor_w

src/batcontrol/logic/next.py in _apply_solar_limit() hebt das Ergebnis anschliessend an:

final_w = solar_limit.merge_limits(floor_w, [settings.limit_battery_charge_rate, cap_w])
if final_w > 0:
    final_w = self.common.enforce_min_pv_charge_rate(final_w)   # 54 W -> 500 W

Zielkonflikt

Beide Seiten haben einen legitimen Grund:

  • MIN_CHARGE_RATE = 500 existiert, um ineffizientes Troepfchenladen zu vermeiden -- 54 W in die Batterie zu schieben ist tatsaechlich verlustbehaftet.
  • Die dokumentierte Absicht der Regel (docs/features/peak-shaving.md: "If free capacity is scarce, the cap equals the floor (absorb only clip power, grid feed-in at the limit)") wird dadurch unterlaufen.

Es ist also kein eindeutiger Bug, aber die Kosten sind messbar und die Doku beschreibt derzeit ein Verhalten, das so nicht eintritt.

Moegliche Richtungen

  1. Nichts aendern, nur dokumentieren. Der Effekt tritt nur bei knapper Kapazitaet auf und kostet im Beispiel 0,2 kWh. (Die Doku-Beschreibung wird unabhaengig von diesem Issue ergaenzt.)
  2. Floor von der Mindestladerate ausnehmen. Wenn cap == floor gilt, den Wert nicht auf 500 W anheben, sondern entweder exakt den Floor fahren oder auf 0 setzen. Fuehrt kurzzeitig zu sehr kleinen Laderaten.
  3. Schwellwert statt Anhebung. Liegt der Floor unter MIN_CHARGE_RATE, gar nicht laden (0) und die Kapazitaet vollstaendig fuer den Peak aufsparen. Vermeidet Troepfchenladen und den Reserveverbrauch, verschenkt aber die kleinen Clip-Mengen am Rand des Fensters.
  4. Reserve nachfuehren. Den Mehrverbrauch durch die Mindestladerate in der Reservierung einkalkulieren.

Aus den Zahlen des Beispieltags waere Variante 3 am wirksamsten, weil die Randslots ohnehin nur wenige Wh Clip enthalten, die spaeteren Peak-Slots aber viel.

Kontext

Gefunden beim Erstellen der Peak-Shaving-Szenarien fuer die Doku. Verwandt mit #39.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions