Genau diese Gleichung benutze ich auch, um meinen zusätzlichen AC Speicher (16 kWh - max. Leistung +/- 3,7 kW) parallel zum ersten Speicher (10 kWh - max. Leistung +/- 4,3 kW) zu führen. Denn die Gleichung funktioniert ja auch in der Nacht. Ich teile die Leistung einfach im Verhältnis der Kapazitäten auf, wobei der erste Speicher der Master ist (wird bei mir durch einen Sunny Home Manager geregelt, weil alle meine Wechselrichter von SMA sind. Der große Speicher bekommt also 62 % des Überschusses, das bestimme ich mit einem Template im HA, die restlichen 38% bleiben dann zwangsläufig für den kleinen SMA Speicher. Das funktioniert solange sehr gut, als die eingestellte Maximalleistung des großen Speichers (ein Victron MP2 - 5000 GX) mit eben 3,7 kW nicht überschritten ist. Aber selbst wenn beide Speicher maximal liefern / laden müssen, ist es nicht schlimm, denn dann verschiebt eine einfache Gleichung im Template den Anteil des „benachteiligten“ Speichers nach oben. Sobald die max. Leistung wieder vorbei ist, beginnt der Ausgleich, ohne dass einer den anderen lädt oder entlädt.
Dreh- und Angelpunkt bei mir ist die externe Leistungsansteuerung meines Victron MP2 per Nodered / MQTT Datenaustausch. Im folgenden Template ermittle ich zunächst meinen Hausverbrauch. Der ist leider etwas kompliziert, da ich wegen der teilweise kaskadierten Zähler eine Fallunterscheidung machen muss.
{# Berechner für den Saldo aus PV Erzeugung und dem Gesamtverbrauch des Hauses und der Garage (Wallbox)#}
{% set pvg = states('sensor.pv_gesamtleistung') | float(0) %}
{% set wp = states('sensor.wp_power_gesamt_2') | float(0) %}
{% set eg = states('sensor.eg_power_gesamt_2') | float(0) %}
{% set og = states('sensor.og_power_gesamt_2') | float(0) %}
{% set dg = states('sensor.dg_power_gesamt_2') | float(0) %}
{% set gl1 = states('sensor.garage_l1_bezug') | float(0) %}
{% set wb = states('sensor.wallbox_leistung_gesamt') | float(0) %}
{% set soc = states('sensor.victron_system_battery_soc_2') | float(0) %}
{% set min_soc = states('input_number.min_soc_vic') | float(20) %}
{% set laden_victron = is_state('input_boolean.laden_aus_victron', 'on') %}
{% set wallbox_aus_victron =
wb > 100
and laden_victron
and soc > min_soc
%}
{% if wallbox_aus_victron %}
{{ ((pvg - wp - eg - og - dg - wb - 3) / 1000) | round(3) }}
{% else %}
{{ ((pvg - wp - eg - og - dg - gl1 - 3) / 1000) | round(3) }}
{% endif %}
{# Hier wird ermittelt, wie groß der prozentuale Leistungsbeitrag der Victron-Batterie sein soll, sowohl bei Aufladen als auch beim Entladen. Er hängt von der Differenz socdif der beiden Batterie-SOC, einem manuell einstellbaren Mittelwert mw wenn diese Differenz Null ist, und zwei je nach Vorzeichen unterschiedlich steilen Geraden ab. Er wird auf Werte zwischen 0 und 100 begrenzt. #}
{% set socdif = states('sensor.soc_differenz') | float(0) %}
{% set pv = states('sensor.hpvs') | float(0) %}
{% set mw = states('input_number.victron_anteil') | float(0) %}
{% set kpos = states('input_number.koeff_pos') | float(0) %}
{% set kneg = states('input_number.koeff_neg') | float(0) %}
{% set result =
socdif * kpos + mw if pv > 0 and socdif > 0
else socdif * kneg + mw if pv > 0 and socdif <= 0
else socdif * -kneg + mw if pv <= 0 and socdif > 0
else socdif * -kpos + mw
%}
{{ [ [result, 0] | max, 100 ] | min }}
Und schließlich:
{# Der Saldo aus PV Leistung und Hausverbrauch hpvs
wird mit dem Faktor für den Victron Batterieinverter multipliziert. Dieser Faktor wird über ein weiteres
Template ermittelt: vic_ant #}
{% set sd = float(states('sensor.hpvs'))*1000 | float(0)%}
{% set va = float(states("sensor.vic_ant"))/100 | float(0) %}
{{ sd*va }}
Zu guter Letzt kommt jetzt noch eine weitere Verarbeitung des „Rohwertes“, denn der muss jetzt noch innerhalb der Lade und Entladeleistungsmaxima (kann ich noch per Schieberegler verändern, wenn ich will) begrenzt werden.
{# Rohwert #}
{%- set raw = states("sensor.vic_bat_pwr_raw") | float(0) -%}
{# Limits aus Helfern #}
{%- set ladelimit_user = states("input_number.victron_ladelimit") | float(0) -%}
{%- set entladelimit = states("input_number.victron_entladelimit") | float(0) -%}
{# SOC, victron_system_battery_voltage #}
{%- set soc = states("sensor.victron_system_battery_soc_2") | float(0) -%}
{%- set u = states("sensor.victron_system_battery_voltage") | float(0) -%}
{%- set maxu = states("sensor.batterie_diy_01_zelle_maxvoltage") | float(0) -%}
{# SOC-basiertes Ladelimit (aufsteigend, daher von oben nach unten prüfen) #}
{%- set ladelimit_soc =
0 if u > 56 else
75 if maxu > 3.55 else
150 if u > 55.2 else
300 if u > 55 else
1000 if soc > 98 else
2000 if soc > 97 else
2500 if soc > 96 else
3000 if soc > 94 else
ladelimit_user
-%}
{# Effektives positives Ladelimit darf user-Limit nicht übersteigen #}
{%- set ladelimit_eff = [ladelimit_user, ladelimit_soc] | min -%}
{%- if raw > ladelimit_eff -%}
{{ ladelimit_eff }}
{%- elif raw < entladelimit -%}
{{ entladelimit }}
{%- else -%}
{{ raw }}
{%- endif -%}
Ist ein bisserl komplex, zugegeben. Ich hatte vorher einfachere Varianten getestet, aber die hatten immer wieder Lücken. So wie es jetzt ist (mit diesen aufeinander aufbauenden Templates) funzt es 100%.
Was hier noch fehlt: Die Übertragung des Steuerwertes an den Victron MP2. Das mache ich in der HA NodeRed Integration über einen simplen Flow, der eben diesen Steuerwert dem Inverter-Steuerwert zuweist. Das ist nun aber inverterspezifisch, muss man sich von Fall zu Fall dann neu ermitteln.