Nutze Deinen dynamischen Stromtarif effektiv mit Ladegerät, Akku und Wechselrichter.

Richtig Sinn macht der Balkonkraftwerk-Speicher im Winter leider nicht zu sehr… denkt man. Aber mit ein paar Hilfsmitteln und einem dynamischen Stromtarif von z.B. Tibber (50 Euro Startguthaben winken hier und die Befreiung von der Grundgebühr für 3 Jahre unter gewissen Voraussetzung bis 30.12.2024: https://invite.tibber.com/0jtc2yju) kann man den Speicher sehr gut ausnutzen um die „dunklen“ Preise des Winters sich zunutze zu machen.

Leider sind im Winter aufgrund weniger Sonneneinstrahlung sowohl der Ertrag des einen BKW’s, als auch die Strompreise der dynamischen Anbieter, die über EPEX Spot Ihren Strom weiterverkaufen nicht immer toll. Mit einigen Skripterweiterungen, Ladegerät und dem Balkonkraftwerksspeicher geht das aber super.

Wie kann ich da einen Vorteil daraus ziehen?

Dynamische Tarife leben davon, günstige, wie auch teure Tagespreiszeiten zu haben. Beispielsweise kann in der Nacht der Strompreis incl. Nebengebühren gerne auch mal bei 0,22-0,25 € aktuell liegen, dann aber zu Spitzenzeiten, z.B. wenn man Morgens die Kaffeemaschine anschmeißt oder Abends gerne Fernsehen will können die üblichen Preise auch zwischen 0,30-0,4€ liegen.

Wer seinen Verbrauch dynamisch regeln kann ist hier also klar im Vorteil und kann sich das zunutze machen, indem er sein BKW zu günstigen Zeiten auflädt und zu teuren entlädt.

Im folgenden Artikel zeige ich Euch, wie Ihr Euch die bekannten / errechneten Ladezeiten zunutze machen könnt.

Aber bitte nicht von Hand…. sondern vollautomatisch.

Was benötigen wir also? Zunächst einmal ein komplettes BKW incl Speicher. Ich verwende sowohl

3x Growatt Noah (https://amzlink.to/az05mMHGlv5uc), als auch einen

Marstek B2500 Speicher (https://amzlink.to/az0Yn31zFDoje)

Als Wechselrichter habe ich steuerbare AP-Systems EZ-1M im Einsatz. Diese sind für aktuell 119€ zu haben: https://amzlink.to/az04OVuIH7tO4

Bei den Solarpanelen scheiden sich ja oft die Geister, ich bin aber Fan von TrinaSolar Modulen (https://amzlink.to/az0KP9q3NDY8I), da diese sehr gut im Parallelbetrieb an den Noah 2000 angeschlossen werden können.

Letztlich müssen wir unseren Speicher laden können. Dazu empfehle ich folgende Komponenten, die ich auch im Einsatz habe:

Wie binde ich die Komponenten jetzt in Home Assistant ein?

Ich gehe davon aus, dass Ihr die Artikel zum Einbinden des Noah 2000 , als auch das Erstellen von Nulleinspeisung gelesen habt.

Zusätzlich benötigen wir die Möglichkeit, zu erkennen, wann günstige Zeiten und wann teure Zeiten sind und idealerweise, wie meine Ladezeit von z.B. 5h hier idealerweise auch aufgeteilt werden kann.

Ich habe mir mittlerweile Sensoren für die oben genannten Akku’s, mein E-Auto und noch einige weitere Geräte, die ich Stromtarifabhängig steuern will angelegt.

Sinn könnten z.B. auch Waschmaschine oder Spülmaschine machen, um diese zeitbasiert laufen zu lassen, wenn es günstig ist.

Den Knackpunkt brachte

ein custom Template Script von Github. Martijn van der Pol hat mit „CheapestEnergyHours“ die Basis gelegt, um dies alles steuern zu lassen.

Ich erstelle mir nun Binärsensoren, die mir sagen, wann es günstig und wann es teuer ist.

Für den NOAH 2000 sehen diese so aus:

template:
- binary_sensor:
    - unique_id: 911f0a21-48de-438f-90a2-4b46401268c4
      name: Noah 2000 günstige Ladezeit
      state: >
        {% if is_state("sensor.noah_2000_ladedauer_abzgl_solar_errechnet", "0.0") -%}
          off
          {% elif states('sensor.noah_2000_ladedauer_abzgl_solar_errechnet') | float < 0.0 %}
            Enough Solar power production remaining
        {% else %}
        {% set sensor = 'sensor.tibber_prices' %}
        {% set hours = states('sensor.noah_2000_ladedauer_abzgl_solar_errechnet') | float %}
        {% from 'cheapest_energy_hours.jinja' import cheapest_energy_hours %}
        {{ cheapest_energy_hours(sensor=sensor, hours=hours, include_tomorrow=true, split=true, look_ahead=true, mode='is_now') }}
        {% endif %}
      attributes:
        errechneteLadezeit: >
          {% if is_state("sensor.noah_2000_ladedauer_abzgl_solar_errechnet", "0.0") -%}
            off
          {% elif states('sensor.noah_2000_ladedauer_abzgl_solar_errechnet') | float < 0.0 %}
            Enough Solar power production remaining
          {% else %}
          {% set sensor = 'sensor.tibber_prices' %}
          {% set hours = states('sensor.noah_2000_ladedauer_abzgl_solar_errechnet') | float %}
          {% from 'cheapest_energy_hours.jinja' import cheapest_energy_hours %}
          {{ cheapest_energy_hours(sensor=sensor, hours=hours, include_tomorrow=true, split=true, look_ahead=true, mode='all') }}
          {% endif %}
        Ladezeiten: >
          {% set value = state_attr('binary_sensor.noah_2000_gunstige_ladezeit','errechneteLadezeit') %}
          {%- for item in value.split(':"') %}
          {%- if loop.index  != 1 %}
          {{ item.split(' ')[0]|truncate(19, true, '')|regex_replace(find='T', replace=' ', ignorecase=False) }}
          {%- endif %}
          {%- endfor %}

    - unique_id: 911f0a21-48de-438f-90a2-4b46401268c5
      name: Noah 2000 teuerste Entladezeit
      state: >
        {% if has_value("sensor.verbleibende_entladezeit") -%}
          {% set hours = states('sensor.verbleibende_entladezeit') | float %}
        {% else %}
          {% set hours = states('sensor.noah_2000_entladedauer_errechnet') | float %}
        {% endif %}
        {% if hours > states('sensor.ubrige_tageszeit_in_h') | int %}
          {% set hours = states('sensor.noah_2000_entladedauer_errechnet') | float %}
        {% endif %}
        {% set sensor = 'sensor.tibber_prices' %}
        {% from 'cheapest_energy_hours.jinja' import cheapest_energy_hours %}
        {{ cheapest_energy_hours(sensor=sensor, hours=hours, include_tomorrow=true, split=true, lowest=false, price_tolerance="10%", look_ahead=true, mode='is_now', value_on_error=true) }}
        #look_ahead=true,
      attributes:
        errechneteEntladezeit: >
          {% if has_value("sensor.verbleibende_entladezeit") -%}
            {% set hours = states('sensor.verbleibende_entladezeit') | float %}
          {% else %}
            {% set hours = states('sensor.noah_2000_entladedauer_errechnet') | float %}
          {% endif %}
          {% if hours > states('sensor.ubrige_tageszeit_in_h') | int %}
            {% set hours = states('sensor.noah_2000_entladedauer_errechnet') | float %}
          {% endif %}
          {% set sensor = 'sensor.tibber_prices' %}
          {% from 'cheapest_energy_hours.jinja' import cheapest_energy_hours %}
          {{ cheapest_energy_hours(sensor=sensor, hours=hours, include_tomorrow=true, split=true, lowest=false, price_tolerance="10%", look_ahead=true, mode='all', value_on_error=true) }}
        Entladezeiten: >
          {% set value = state_attr('binary_sensor.noah_2000_teuerste_entladezeit','errechneteEntladezeit') %}
          {%- for item in value.split(':"') %}
          {%- if loop.index  != 1 %}
          {{ item.split(' ')[0]|truncate(19, true, '')|regex_replace(find='T', replace=' ', ignorecase=False) }}
          {%- endif %}
          {%- endfor %}

Geht der „günstige“ on, lasse ich den Noah über eine Zigbee-Steckdose mit dem Netzteil aufladen. Dabei kommen die vollen 900W Eingangsleistung beim Noah auch an. Ich habe mein Netzteil tatsächlich am 3. Noah angeschlossen, da 1 und 2 schon mit Solar Panelen belegt sind. Andersrum geht er „off“ schaltet die Automation die Zigbee Steckdose wieder aus.

Die Automation dafür sieht dann so aus:

alias: Noah 2000 - Akku laden
description: ""
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.noah_2000_gunstige_ladezeit
    to: "on"
    id: ein
    for:
      hours: 0
      minutes: 2
      seconds: 0
  - trigger: state
    entity_id:
      - binary_sensor.noah_2000_gunstige_ladezeit
    to: "off"
    id: aus
    for:
      hours: 0
      minutes: 2
      seconds: 0
conditions:
  - condition: not
    conditions:
      - condition: state
        entity_id: sensor.noah_2000_soc
        state: "100"
actions:
  - if:
      - condition: trigger
        id:
          - ein
    then:
      - type: turn_on
        device_id: 069d42c5025235c61c8b614cf5b93eb7
        entity_id: ef1775ceb135393df3754305512b6cf3
        domain: switch
      - action: number.set_value
        target:
          entity_id: number.noah_2000_system_output_power
        data:
          value: "0"
  - if:
      - condition: trigger
        id:
          - aus
    then:
      - type: turn_off
        device_id: 069d42c5025235c61c8b614cf5b93eb7
        entity_id: ef1775ceb135393df3754305512b6cf3
        domain: switch
mode: single

Die für den Binärsensor verwendeten Sensoren kommen wie folgt zustande:

sensor.noah_2000_ladedauer_abzgl_solar_errechnet

Dieser Sensor sieht wie folgt aus:
{{(6.144 – states(„sensor.noah_2000_aktueller_ladestand“) | float(0) – states(„sensor.energy_production_today_remaining_2“) | float(0) – states(„sensor.energy_production_today_remaining_3“) |float(0) – states(„sensor.energy_production_today_remaining_4“) |float(0)) / 0.9}}

6144 ist meine Akku-Kapazität. Davon ziehen wir den aktuellen Ladestand in Wh ab.
Des Weiteren subtrahiere ich die übrige Vorhersage meines Solarertrags. Ich will schließlich nicht laden, wenn die Sonne an dem Tag noch alles auf 100% pumpt.
Anschließend wird das ganze durch 0,9 geteilt, was den 900 Watt Eingangsleistung des Netzteils entspricht. Daraus errechnet sich die mögliche Ladedauer.

Im Template Sensor „Noah 2000 günstige Ladezeit“ kann dieser Wert 0 sein -> Akku voll.
oder Negativ -> es gibt genügend Solarstrom, um den Akku zu laden.
wenn er positiv ist, wir mit Martijn’s Script berechnet, wann die günstigste Zeit für’s Laden ist.

Zerlegen wir kurz das verwendete Script:

{{ cheapest_energy_hours(sensor=sensor, hours=hours, include_tomorrow=true, split=true, look_ahead=true, mode=’is_now‘) }}
sensor: Über sensor gebe ich dem script die „Stundenpreise von Tibber“ mit.
hours: übermittelt den errechneten Wert, damit das Script weiß, wie lange die Ladedauer ist.
include_tomorrow: durch den Wert true, nehme ich ab 13 Uhr auch die Werte von Morgen mit ins Kalkül.
split: ermöglicht es die Aufsplittung in mehrere Abschnitte. Evtl lade ich von 1-3 Uhr, und später noch von 13-16 Uhr, weil der Preis zu dieser Zeit günstig ist.
look_ahead: schaue von jetzt nach vorne. Ansonsten würde er auch um 14 Uhr noch die Werte von heute Morgen mit ins Kalkül ziehen.
mode: hier gibt es verschiedene Modi, für mich ist aber der „is_now“ notwendig, da ich die Betrachtung von jetzt benötige, ob er den Binärsensor an oder ausschaltet.

Das Script für’s Entladen bei Teuer:

Vorher bitte noch idealerweise Eure Betriebsmodi im Noah löschen. Damit funktioniert die Steuerung wie unten angeben über den Output.

Auch hier wird der obige Binärsensor „Noah 2000 teuerste Entladezeit“ verwendet.
Dieser hat noch zusätzlich den Parameter lowest=false, was Ihn „An“ gehen lässt, wenn’s teuer wird.

Die Automation, die ich für’s Entladen verwende hat diesen Code:

alias: Noah 2000 - Akku entladen
description: ""
triggers:
  - entity_id:
      - sensor.noah_2000_soc
    to: "100"
    id: batteryfull
    trigger: state
  - trigger: state
    entity_id:
      - binary_sensor.noah_2000_teuerste_entladezeit
    not_from: unavailable
    to: "on"
    id: teuersteEntladezeitAnfang
    for:
      hours: 0
      minutes: 2
      seconds: 0
  - trigger: state
    entity_id:
      - binary_sensor.noah_2000_teuerste_entladezeit
    not_from: unavailable
    to:
      - "off"
      - unavailable
    id: teuersteEntladezeitEnde
    for:
      hours: 0
      minutes: 2
      seconds: 0
conditions: []
actions:
  - if:
      - condition: trigger
        id:
          - teuersteEntladezeitAnfang
    then:
      - wait_template: "{{ is_state('binary_sensor.noah_2000_gunstige_ladezeit', 'off') }}"
        continue_on_timeout: true
        timeout: "60"
      - type: turn_off
        device_id: 069d42c5025235c61c8b614cf5b93eb7
        entity_id: ef1775ceb135393df3754305512b6cf3
        domain: switch
      - action: number.set_value
        target:
          entity_id: number.noah_2000_system_output_power
        data:
          value: "800"
  - if:
      - condition: trigger
        id:
          - teuersteEntladezeitEnde
    then:
      - action: number.set_value
        target:
          entity_id: number.noah_2000_system_output_power
        data:
          value: "0"
  - if:
      - condition: trigger
        id:
          - batteryfull
    then:
      - type: turn_off
        device_id: 069d42c5025235c61c8b614cf5b93eb7
        entity_id: ef1775ceb135393df3754305512b6cf3
        domain: switch
      - action: number.set_value
        target:
          entity_id: number.noah_2000_system_output_power
        data:
          value: "800"
        enabled: false
mode: single

3 Trigger starten die Automation und führen unterschiedliche Aktionen aus:

SOC 100% -> Akku voll
Hier stoppt das Script die Zigbee Steckdose (will ja nicht weiter laden). Des Weiteren setze ich den Output auf voll 800. Die Steuerung übernimmt wieder meine Nulleinspeisung, damit ich nicht alles verwende.

Binärsensor für Entladen geht on
Wir checken, dass keine Überschneidung mit der günstigen Ladezeit besteht.
Schalten nach 60 Sekunden aber trotzdem mal die Zigbee Steckdose aus und
schalten den Noah auf 800 Watt Output. Den Rest übernimmt die Nulleinspeisung.

Binärsensor für Entladen geht off
Jetzt wird’s ja wieder billig, also schalte ich den Output vom Noah wieder auf „0“.

Jetzt habe wir komplett angeschaut, wie Ihr einen Akku über die günstige Stromzeiten Laden und Entladen. Weiter geht’s mit dem E-Auto.

Wie schaut das beim E-Auto aus?

Tibber bietet hier zwar auch eine eigene Steuerung bei unterstützten Auto’s, ich habe es aber lieber selbst im Griff:

Nehmen wir mal an, mein E-Auto hat einen Akku von 77kW. Mit meiner Wallbox kann ich pro Stunde 11kW laden. Also bräuchte ein ganz leeres Auto 7h. Im dynamischen Tarif ist es leider nicht immer so, dass wir eine Kurve wie hier haben, in der wir von 22-5h durchladen könnten und den günstigsten Preis haben:

Hier kommt dann das Script von Martijn zum Einsatz. Ich erstelle mir binäre Sensoren, die je nach Stromtarif on oder off gehen. Zusätzlich kann ich mit der Option Split arbeiten, über die ich die 7h auch auf mehrere Segmente aufteilen lassen kann.

template:
- binary_sensor:
    - unique_id: 911f0a21-48de-438f-90a2-4b46401268b3
      name: ID.4 günstigste Ladezeit
      state: >
        {% if is_state("sensor.id_4_ladedauer_errechnet_11kwh", "0.0") -%}
          off
        {% else %}
        {% set sensor = 'sensor.tibber_prices' %}
        {% set hours = states('sensor.id_4_ladedauer_errechnet_11kwh') | float %}
        {% from 'cheapest_energy_hours.jinja' import cheapest_energy_hours %}
        {{ cheapest_energy_hours(sensor=sensor, hours=hours, include_tomorrow=true, look_ahead=true, split=true, mode='is_now') }}
        {% endif %}
      availability: >
        {{
        is_state('sensor.kebap30_cable_state_text', 'cable_ready') and states('sensor.mosquitto_broker_vw_id_4_ubrige_ladezeit') | is_number
        }}
      attributes:
        errechneteLadezeit: >
          {% if is_state("sensor.id_4_ladedauer_errechnet_11kwh", "0.0") -%}
            off
          {% else %}
          {% set sensor = 'sensor.tibber_prices' %}
          {% set hours = states('sensor.id_4_ladedauer_errechnet_11kwh') | float %}
          {% from 'cheapest_energy_hours.jinja' import cheapest_energy_hours %}
          {{ cheapest_energy_hours(sensor=sensor, hours=hours, include_tomorrow=true, look_ahead=true, split=true, mode='all') }}
          {% endif %}
        Ladezeiten: >
          {% set value = state_attr('binary_sensor.id_4_gunstigste_ladezeit','errechneteLadezeit') %}
          {%- for item in value.split(':"') %}
          {%- if loop.index  != 1 %}
          {{ item.split(' ')[0]|truncate(19, true, '')|regex_replace(find='T', replace=' ', ignorecase=False) }}
          {%- endif %}
          {%- endfor %}

Auch diesen Binärsensor kann ich verwenden, um mein Auto zu laden und damit dann die Wallbox einzuschalten:

alias: Auto laden starten - Tibber Cheapest Price
description: ""
triggers:
  - entity_id:
      - binary_sensor.id_4_gunstigste_ladezeit
    enabled: true
    trigger: state
    to: "on"
conditions:
  - condition: not
    conditions:
      - condition: numeric_state
        entity_id: sensor.mosquitto_broker_vw_id_4_ladestand
        above: 99
actions:
  - action: switch.turn_on
    metadata: {}
    data: {}
    target:
      entity_id: switch.kebap30_onoff
  - delay:
      hours: 0
      minutes: 0
      seconds: 30
      milliseconds: 0
    enabled: true
  - if:
      - condition: numeric_state
        entity_id: sensor.keba_p30_charging_power
        below: 1
    then:
      - data:
          message: " Auto wird noch nicht geladen!! Starten war nicht möglich. "
        action: notify.telegramralph
    else:
      - data:
          message: " Auto wird geladen!!"
        action: notify.telegramralph
mode: single

und auszuschalten:

alias: Auto laden stoppen - Tibber Cheapest Price
description: ""
triggers:
  - entity_id:
      - binary_sensor.id_4_gunstigste_ladezeit
    enabled: true
    trigger: state
    to: "off"
    from: "on"
  - entity_id:
      - sensor.kebap30_cable_state_text
    not_from:
      - unknown
      - unavailable
    to: cable_not_ready
    enabled: true
    trigger: state
conditions: []
actions:
  - action: switch.turn_off
    metadata: {}
    data: {}
    target:
      entity_id: switch.kebap30_onoff
  - delay:
      hours: 0
      minutes: 0
      seconds: 30
      milliseconds: 0
  - if:
      - condition: numeric_state
        entity_id: sensor.keba_p30_charging_power
        above: 0.5
    then:
      - action: switch.turn_off
        metadata: {}
        data: {}
        target:
          entity_id: switch.kebap30_onoff
      - data: {}
        target:
          entity_id: button.keba_p30_disable
        enabled: false
        action: button.press
      - data:
          message: " Auto wird weiterhin geladen!! Stoppen war nicht möglich. Evtl teurer Preis!!! "
        action: notify.telegramralph
    else:
      - data:
          message: " Auto wird nicht mehr geladen!! Geladene Energie: {{ states.sensor.kebap30_session_energy.state }} kWh"
        action: notify.telegramralph
mode: single

Ich hoffe, ich konnte Euch hier in diesem sehr langen Artikel Einblicke geben, wie Ihr Euren dynamischen Tarif gut mit Eurem Balkonkraftwerk am Beispiel des Growatt Noah 2000 verbinden könnt oder Eurer E-Auto(, Spülmaschine, Waschmaschine, Computer, ….) zu günstigen Zeiten laufen lassen könntet.

Hinweis: Durch die Nutzung der obigen Links erhalte ich unter Umständen eine kleine Provision.