dauert es bei Euch auch “ewig” - also um die 5 Minuten - bis die Daten in HA aktualisiert werden?
*edit: Update Intervall steht auf 60 Sekunden, auch alle anderen Einstellungen sind auf Default Einstellungen
dauert es bei Euch auch “ewig” - also um die 5 Minuten - bis die Daten in HA aktualisiert werden?
*edit: Update Intervall steht auf 60 Sekunden, auch alle anderen Einstellungen sind auf Default Einstellungen
Hallo! Wie habt ihr das hinbekommen mit der täglichen PV Leistung. Die ist bei mir immer niedriger als in der APP und ich denke das es am Intervall liegt. Der Sensor Solarleistung wird ja auch alle paar Minuten aktualisiert obwohl der Update Intervall auf 60sek
lg
Flo
Anker Solix Nulleinspeisung mit Home Assistant – ohne Anker Smart Meter
Die eingebaute Nulleinspeisung der Solix funktioniert nur mit einem gekoppelten Smart Meter (Anker oder Shelly). Wer das nicht installieren kann oder will, hat mit Home Assistant eine vollwertige Alternative.
Meine Lösung: Ein Tasmota-Zähler am Hausanschluss liefert den Netzbezug, eine HA-Automation setzt daraus die Einspeisevorgabe der Solarbank – Ergebnis ist eine stabile Nulleinspeisung ohne zusätzliche Hardware im Sicherungskasten.
Zusätzliche Vorteile gegenüber der App-Lösung:
Kein Anker Smart Meter nötig
Akkumanagement nach Jahreszeit und Tageszeit
Prognosesteuerung via Solcast (nachts weniger entladen bei gutem Solartag morgen)
SOC-Schutz und Wintermodus
Spike-Filterung für kurze Lastspitzen
Voraussetzungen:
Home Assistant
Tasmota-fähiger Stromzähler (z.B. am IR-Lesekopf)
Anker Solix HA-Integration
alias: Anker Solix3 Nulleinspeisung
description: v5.5.8
triggers:
- trigger: state
entity_id: sensor.bezug_geglattet
for:
seconds: 2
- trigger: state
entity_id: sensor.tasmota_ehz_power
for:
seconds: 2
- trigger: time_pattern
seconds: /45
- trigger: state
entity_id: sensor.none_prognose_morgen
for:
seconds: 10
- trigger: state
entity_id: sensor.none_forecast_today_remaining
for:
seconds: 10
conditions:
- condition: state
entity_id: input_boolean.solarbank_automatik
state: "on"
actions:
- variables:
sensor_bezug: sensor.bezug_geglattet
sensor_bezug_roh: sensor.tasmota_ehz_power
sensor_solarbank_soc: sensor.solarbank_3_e2700_pro_ladestand
sensor_solarbank_solar: sensor.solarbank_3_e2700_pro_solarleistung
sensor_solarbank_entladung: sensor.solarbank_3_e2700_pro_dc_ausgangsleistung
number_solarbank_vorgabe: number.solarbank_3_e2700_pro_system_einspeisevorgabe
sensor_forecast_morgen: sensor.none_prognose_morgen
sensor_forecast_heute_rest: sensor.none_forecast_today_remaining
RUNDUNG_WATT: 10
RUNDUNG_WATT_KLEIN: 5
EINSPEISUNG_SCHWELLE_WATT: -25
MAX_LEISTUNG_ABSOLUT: 2000
MAX_LEISTUNG_ANLAUF: 350
SOLAR_ANLAUF_EIN: 130
SOLAR_ANLAUF_AUS: 90
SOC_KRITISCH: 8
SOC_HYSTERESE: 2
SPITZEN_SCHWELLE_WATT: 340
SPITZEN_BESTAETIGUNG_FAKTOR: 0.68
SPITZEN_SEHR_HOCH: 550
HYST_BASE_WATT: 12
HYST_MIN_WATT: 8
HYST_MAX_WATT: 28
VORGABE_CACHE_SEKUNDEN: 80
NACHT_THROTTLE_SEKUNDEN: 300
SOLAR_THROTTLE_SEKUNDEN: 120
FORECAST_SEHR_GUT: 5
FORECAST_GUT: 3
FORECAST_MITTEL: 1.5
FORECAST_VORSTEUERUNG_VIEL: 80
FORECAST_VORSTEUERUNG_MITTEL: 40
FORECAST_VORSTEUERUNG_SOC_MIN: 40
REGELKORREKTUR_MIN_SHORTFALL: 60
REGELKORREKTUR_FAKTOR: 0.22
REGELKORREKTUR_CAP: 20
REGELKORREKTUR_MAX_PROZENT: 0.07
WINTER_MONATE:
- 10
- 11
- 12
- 1
- 2
WINTER_NACHT_FAKTOR: 0.75
SOLAR_THROTTLE_SCHWELLE_EIN: 5
SOLAR_THROTTLE_SCHWELLE_AUS: 15
PUFFER_SOC_99: 50
PUFFER_SOC_98: 30
PUFFER_SOC_95: 20
PUFFER_SOC_90: 10
MAX_LEISTUNG_TAG_BASIS: 1000
- variables:
last_timestamp: >-
{{ states('input_number.solarbank_letzte_vorgabe_timestamp') | float(0)
}}
seconds_since_last_set: >
{% set diff = (now().timestamp() | float - last_timestamp) | float %} {{
999 if diff < 0 or diff > 86400 else diff | int }}
- if:
- condition: template
value_template: >
{% set soc = states('sensor.solarbank_3_e2700_pro_ladestand') |
float(99) %} {% set forecast = states('sensor.none_prognose_morgen') |
float(0) %} {% set soc_aus_basis = 20 if now().month in [10,11,12,1,2]
else 10 %} {% set soc_ausschalten = soc_aus_basis + (5 if forecast <
1.5 else 3 if forecast < 3 else 0) %} {{ seconds_since_last_set < 30
and soc > SOC_KRITISCH and soc > soc_ausschalten }}
then:
- stop: "Hard-Cooldown: 30s Minimum-Change-Delay"
- variables:
sun_elevation: "{{ state_attr('sun.sun', 'elevation') | float(-90) }}"
ist_nacht: "{{ sun_elevation < -6 }}"
ist_abend: "{{ sun_elevation < 15 and sun_elevation >= -6 }}"
ist_winter: "{{ now().month in WINTER_MONATE }}"
- variables:
solar_raw: "{{ states(sensor_solarbank_solar) | float(0) }}"
solar_throttle_ok: >-
{{ states(sensor_solarbank_solar) not in ['unavailable', 'unknown',
'none'] }}
- choose:
- conditions:
- condition: template
value_template: >-
{{ solar_throttle_ok and solar_raw >= SOLAR_THROTTLE_SCHWELLE_AUS
}}
sequence:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.solar_kein_ertrag_aktiv
- conditions:
- condition: template
value_template: >-
{{ solar_throttle_ok and solar_raw < SOLAR_THROTTLE_SCHWELLE_EIN
}}
sequence:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.solar_kein_ertrag_aktiv
- if:
- condition: template
value_template: >
{% set ist_zeit_trigger = trigger.platform == 'time_pattern' %} {% set
kein_ertrag = is_state('input_boolean.solar_kein_ertrag_aktiv', 'on')
%} {% set diff = (now().timestamp() | float - last_timestamp) | float
%} {% set throttle = NACHT_THROTTLE_SEKUNDEN if ist_nacht else
(SOLAR_THROTTLE_SEKUNDEN if kein_ertrag else 0) %} {{ ist_zeit_trigger
and throttle > 0 and last_timestamp > 0 and diff < throttle }}
then:
- stop: Throttle aktiv
- variables:
raw_bezug: "{{ states(sensor_bezug) }}"
raw_bezug_roh: "{{ states(sensor_bezug_roh) }}"
raw_soc: "{{ states(sensor_solarbank_soc) }}"
raw_solar: "{{ states(sensor_solarbank_solar) }}"
raw_entladung: "{{ states(sensor_solarbank_entladung) }}"
raw_vorgabe: "{{ states(number_solarbank_vorgabe) }}"
raw_forecast_morgen: "{{ states(sensor_forecast_morgen) }}"
raw_forecast_heute_rest: "{{ states(sensor_forecast_heute_rest) }}"
sensor_ok: |
{{ raw_bezug not in ['unavailable','unknown','none'] and
raw_soc not in ['unavailable','unknown','none'] and
raw_solar not in ['unavailable','unknown','none'] and
raw_entladung not in ['unavailable','unknown','none'] }}
- if:
- condition: template
value_template: "{{ not sensor_ok }}"
then:
- action: system_log.write
data:
message: Solarbank v5.5.8 Sensor error detected
level: warning
- stop: Sensor error
- if:
- condition: state
entity_id: input_boolean.solarbank_fehler_gemeldet
state: "on"
then:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.solarbank_fehler_gemeldet
- action: persistent_notification.dismiss
data:
notification_id: solarbank_sensor_fehler
- variables:
bezug_watt: "{{ raw_bezug | float(0) }}"
bezug_roh_watt: "{{ raw_bezug_roh | float(0) }}"
soc_prozent: "{{ raw_soc | float(0) }}"
solar_watt: "{{ raw_solar | float(0) }}"
entladung_watt: "{{ raw_entladung | float(0) }}"
vorgabe_watt: "{{ raw_vorgabe | float(0) }}"
forecast_morgen_kwh: "{{ raw_forecast_morgen | float(0) }}"
forecast_heute_rest_kwh: "{{ raw_forecast_heute_rest | float(0) }}"
bezug_delta: "{{ (bezug_roh_watt - bezug_watt) | abs }}"
spitze_erkannt: >
{% if bezug_roh_watt <= 0 %}false {% elif bezug_delta >
SPITZEN_SEHR_HOCH %}true {% elif bezug_delta > SPITZEN_SCHWELLE_WATT %}
{{ not (bezug_watt > 12 and (bezug_roh_watt / bezug_watt) >= SPITZEN_BESTAETIGUNG_FAKTOR) }}
{% else %}false{% endif %}
bezug_effektiv: >
{% if spitze_erkannt %}{{ bezug_watt }} {% elif bezug_delta <=
SPITZEN_SCHWELLE_WATT + 30 %}{{ bezug_roh_watt }} {% else %}{{
bezug_watt }}{% endif %}
forecast_morgen_cat: >
{% if forecast_morgen_kwh >= FORECAST_SEHR_GUT %}SEHR_GUT {% elif
forecast_morgen_kwh >= FORECAST_GUT %}GUT {% elif forecast_morgen_kwh >=
FORECAST_MITTEL %}MITTEL {% else %}SCHLECHT{% endif %}
forecast_heute_cat: >
{% if forecast_heute_rest_kwh >= 3 %}VIEL {% elif
forecast_heute_rest_kwh >= 1.5 %}MITTEL {% else %}WENIG{% endif %}
soc_aus_basis: "{{ 20 if ist_winter else 10 }}"
soc_regel_basis: "{{ 25 if ist_winter else 15 }}"
soc_ausschalten: >
{% if forecast_morgen_cat == 'SEHR_GUT' %}{{ [soc_aus_basis - 2, 5] |
max }} {% elif forecast_morgen_cat == 'GUT' %}{{ soc_aus_basis }} {%
elif forecast_morgen_cat == 'MITTEL' %}{{ soc_aus_basis + 3 }} {% else
%}{{ soc_aus_basis + 5 }}{% endif %}
soc_einschalten: >-
{{ [soc_ausschalten + SOC_HYSTERESE, SOC_KRITISCH + SOC_HYSTERESE + 1] |
max }}
soc_regelstart: >
{% if forecast_morgen_cat == 'SEHR_GUT' %}{{ soc_regel_basis - 1 }} {%
elif forecast_morgen_cat == 'SCHLECHT' %}{{ soc_regel_basis + 3 }} {%
else %}{{ soc_regel_basis }}{% endif %}
betriebsmodus: |
{%- if soc_prozent <= SOC_KRITISCH -%}
KRITISCH
{%- elif soc_prozent <= soc_ausschalten -%}
AUSSCHALTEN
{%- elif soc_prozent < soc_einschalten -%}
{%- if solar_watt >= SOLAR_ANLAUF_EIN -%}ANLAUF_SOLAR{%- else -%}GESPERRT{%- endif -%}
{%- elif soc_prozent < soc_regelstart -%}
ANLAUF
{%- elif ist_abend and soc_prozent >= 80 -%}
ABEND_BOOST
{%- else -%}
NORMAL
{%- endif -%}
max_leistung_nacht: |
{% if forecast_morgen_cat == 'SEHR_GUT' %}
{{ 500 if soc_prozent >= 70 else 400 if soc_prozent >= 50 else 250 if soc_prozent >= 30 else 150 }}
{% elif forecast_morgen_cat == 'GUT' %}
{{ 350 if soc_prozent >= 60 else 300 if soc_prozent >= 40 else 150 }}
{% else %}150{% endif %}
max_leistung_nacht_final: >-
{{ (max_leistung_nacht * WINTER_NACHT_FAKTOR) | int if ist_winter else
max_leistung_nacht | int }}
max_entladeleistung: >
{% if ist_nacht and forecast_morgen_cat == 'SCHLECHT' and soc_prozent <
35 %}110 {% elif ist_nacht %}{{ max_leistung_nacht_final }} {% elif
ist_abend %}{{ 800 if forecast_heute_cat == 'VIEL' else 600 }} {% elif
betriebsmodus == 'ANLAUF' %}{{ MAX_LEISTUNG_ANLAUF }} {% else %}{{
MAX_LEISTUNG_TAG_BASIS }}{% endif %}
- if:
- condition: template
value_template: >
{{ states('input_text.solarbank_letzter_modus') | default('') !=
betriebsmodus and
states('input_text.solarbank_letzter_modus') != '' }}
then:
- action: system_log.write
data:
message: >-
Solarbank v5.5.8 Mode: {{
states('input_text.solarbank_letzter_modus') }} → {{ betriebsmodus
}}
level: warning
- action: input_text.set_value
target:
entity_id: input_text.solarbank_letzter_modus
data:
value: "{{ betriebsmodus }}"
- variables:
aktuelle_vorgabe: >
{% set gemerkt = states('input_number.solarbank_letzte_vorgabe_wert') |
float(-1) %} {% set diff = (now().timestamp() | float - last_timestamp)
| float %} {% set cache_ok = last_timestamp > 0 and 0 <= diff <
VORGABE_CACHE_SEKUNDEN %} {{ vorgabe_watt if betriebsmodus in
['KRITISCH', 'AUSSCHALTEN'] else (gemerkt if gemerkt >= 0 and cache_ok
else vorgabe_watt) }}
puffer_basis: >
{% if soc_prozent >= 99 %}{{ PUFFER_SOC_99 }} {% elif soc_prozent >= 98
%}{{ PUFFER_SOC_98 }} {% elif soc_prozent >= 95 %}{{ PUFFER_SOC_95 }} {%
elif soc_prozent >= 90 %}{{ PUFFER_SOC_90 }} {% else %}0{% endif %}
puffer_faktor: >-
{{ 1.5 if forecast_morgen_cat == 'SEHR_GUT' else 1.2 if
forecast_morgen_cat == 'GUT' else 1.0 }}
puffer_watt: >
{% set basis = (puffer_basis * puffer_faktor) | int %} {% if soc_prozent
>= 95 %}
{% if forecast_morgen_cat == 'SEHR_GUT' %}{{ (basis * 0.55) | int }}
{% elif forecast_morgen_cat == 'GUT' %}{{ (basis * 0.75) | int }}
{% else %}{{ (basis * 1.30) | int }}{% endif %}
{% else %}{{ basis }}{% endif %}
forecast_vorsteuerung: >
{% if betriebsmodus not in ['NORMAL', 'ABEND_BOOST', 'ANLAUF'] or
ist_nacht or soc_prozent < FORECAST_VORSTEUERUNG_SOC_MIN %}0 {% elif
forecast_heute_cat == 'VIEL' and soc_prozent >= 60 %}{{
FORECAST_VORSTEUERUNG_VIEL }} {% elif forecast_heute_cat == 'MITTEL' and
soc_prozent >= 50 %}{{ FORECAST_VORSTEUERUNG_MITTEL }} {% else %}0{%
endif %}
regelabweichung: "{{ aktuelle_vorgabe - entladung_watt }}"
regelkorrektur: >
{% if betriebsmodus not in ['NORMAL', 'ABEND_BOOST'] or regelabweichung
<= REGELKORREKTUR_MIN_SHORTFALL %}0 {% else %}{{ [[(regelabweichung *
REGELKORREKTUR_FAKTOR) | int, REGELKORREKTUR_CAP] | min,
(aktuelle_vorgabe * REGELKORREKTUR_MAX_PROZENT) | int] | min }}{% endif
%}
p_regler_ziel: >-
{{ (aktuelle_vorgabe + bezug_effektiv + puffer_watt +
forecast_vorsteuerung + regelkorrektur) | int }}
ziel_leistung_roh: >
{% if betriebsmodus in ['KRITISCH', 'AUSSCHALTEN', 'GESPERRT'] %}0 {%
elif betriebsmodus == 'ANLAUF_SOLAR' %}
{% set solar_limit = (solar_watt * 0.88) | int %}
{% set ziel = [0, [p_regler_ziel, solar_limit] | min] | max %}
{% set rundung = RUNDUNG_WATT_KLEIN if ziel < 100 else RUNDUNG_WATT %}
{{ ((ziel / rundung) | round(0) * rundung) | int }}
{% else %}
{% set ziel = [0, [p_regler_ziel, max_entladeleistung] | min] | max %}
{% set rundung = RUNDUNG_WATT_KLEIN if ziel < 100 else RUNDUNG_WATT %}
{{ ((ziel / rundung) | round(0) * rundung) | int }}
{% endif %}
ziel_leistung_final: "{{ [0, [ziel_leistung_roh, MAX_LEISTUNG_ABSOLUT] | min] | max }}"
hysterese_watt: >
{% set base = HYST_BASE_WATT %} {% set prop = (aktuelle_vorgabe * 0.045)
| round(0) | int %} {{ [HYST_MIN_WATT, [base, prop] | max,
HYST_MAX_WATT] | min }}
abweichung: "{{ (ziel_leistung_final - aktuelle_vorgabe) | abs }}"
seconds_since_update: >
{% set diff = (now().timestamp() | float - last_timestamp) | float %} {{
999 if last_timestamp == 0 or diff < 0 or diff > 86400 else diff }}
cooldown_effektiv: >
{%- if betriebsmodus in ['KRITISCH','AUSSCHALTEN','GESPERRT'] -%}0 {%-
elif betriebsmodus == 'ANLAUF_SOLAR' -%}25 {%- elif bezug_effektiv <
EINSPEISUNG_SCHWELLE_WATT -%}15 {%- elif abweichung > 250 -%}55 {%- elif
abweichung > 120 -%}45 {%- elif abweichung > 40 -%}35 {%- else -%}95{%-
endif -%}
soll_aendern: |
{{ ziel_leistung_final != aktuelle_vorgabe and
(abweichung >= hysterese_watt or bezug_effektiv < EINSPEISUNG_SCHWELLE_WATT or
betriebsmodus in ['KRITISCH','AUSSCHALTEN','ANLAUF_SOLAR','GESPERRT']) and
seconds_since_last_set >= 30 and
seconds_since_update > cooldown_effektiv }}
- if:
- condition: template
value_template: "{{ soll_aendern }}"
then:
- action: number.set_value
target:
entity_id: "{{ number_solarbank_vorgabe }}"
data:
value: "{{ ziel_leistung_final }}"
- action: input_number.set_value
target:
entity_id: input_number.solarbank_letzte_vorgabe_timestamp
data:
value: "{{ now().timestamp() | int }}"
- action: input_number.set_value
target:
entity_id: input_number.solarbank_letzte_vorgabe_wert
data:
value: "{{ ziel_leistung_final }}"
- choose:
- conditions:
- condition: state
entity_id: input_boolean.solarbank_debug
state: "on"
sequence:
- action: system_log.write
data:
message: >
Solarbank v5.5.8 [DEBUG] {{ aktuelle_vorgabe }}W → {{
ziel_leistung_final }}W H{{ hysterese_watt }} Δ{{ abweichung
}} {{ betriebsmodus }} SOC{{ soc_prozent }}%
level: debug
- conditions: []
sequence:
- action: system_log.write
data:
message: >
Solarbank v5.5.8 ✅ {{ aktuelle_vorgabe }}W → {{
ziel_leistung_final }}W | {{ betriebsmodus }} | SOC: {{
soc_prozent }}% {%- if ziel_leistung_final >=
MAX_LEISTUNG_ABSOLUT %} ⚠️ capped{% endif %}
level: info
mode: single
max_exceeded: silent
In der Anker App steht das auf Eigenverbrauch und damit regelt die Anker SB ziemlich exakt auf Null. Ohne HA Automatisierung.
Die Solix-App läuft bei mir im Eigenverbrauch-Modus. Die eigentliche Nulleinspeisung übernimmt aber eine HA-Automation, die die Einspeisevorgabe dynamisch an den aktuellen Hausverbrauch anpasst.