Energie Management mit evcc

Hallo Community,

wir besitzen seit Oktober 2024 eine Solaranlage von Solarwatt und sind damit alles andere als zufrieden. Neben vielen, vielen anderen Gründen ist hier das absolut mangelhafte Energie Management …

  • das kein PV-Optimiertes Laden unseres E-Autos ermöglichte, geschweige denn, dass das E-Auto in den Ladeprozess integriert war (“SoC”, Kapazität, …)
  • dessen EM-Trend (“thermisches Energie Management” von Stiebel Eltron) für die Wärmepumpe
    • nicht aufgesetzt war
    • unklar/intransparent war, wie/wann diese Komponente mit den Rest des Systems zusammenspielen soll

… zu nennen.

Auf Grund dieser Defizite haben wir eine, auf Home Assistant/evcc basierte Lösung entwickelt, die …

  • auf einem Raspberry PI installiert ist
  • seit mehreren Monaten (E-Auto) bzw. Wochen (Wärmepumpe) stabil läuft

… und die wir hier vorstellen möchten. Sie ermöglicht eine einheitliche Bedienung für E-Auto und PV-optimierte Wärmepumpensteuerung (im Sinne von SG Ready Betriebszustand 3).

Die Architektur unserer Lösung sieht wie folgt aus:

Das “Gehirn” der Lösung ist evcc. Es …

  • detektiert einen PV-Überschuss
  • priorätisiert Wallbox bzw. Wärmepumpe
  • steuert unsere Wallbox so, dass unser E-Auto PV-Optimiert geladen wird und regelt tatsächlich bei Wolken herunter :wink:
  • integriert unser E-Auto bzw. die Wärmepumpe in den Ladeprozess (SoC)

… und liefert eine einheitliche Visualisierung des Ablaufs:

Die Wärmepumpe wird von evcc als “Smart Switch” (“Schaltsteckdose”) angesteuert und erhält bei entsprechendem PV-Überschuss einen “An” Befehl. Dieser wird von Home Assistant interpretiert und an einen, auf ESPHome basierten, "SG Ready Controller” weitergeleitet, der über zwei Relais die “SG Ready” Schnittstelle unserer Wärmepumpe ansteuert.

Home Assistant liefert, über seine Stiebel Eltron ISG Integration einen virtuellen “SoC” an evcc zurück (100 * “aktuelle Temperatur” / Zieltemperatur) und teilt so evcc mit, dass der “Ladevorgang” beendet ist.

Wie oben beschrieben läuft das Ganze seit mehren Wochen stabil und berücksichtigt Parameter wie:

  • E-Auto hat höhere Priorität wie Wärmepumpe (evcc)
  • Haus-Akku muss geladen sein ansonsten erfolgt kein Betriebszustand 3 der Wärmepumpe
  • PV-Überschuss muss stabil für längere Zeit anliegen (konfigurierbar)
  • PV-Optimierung der Wärmepumpe findet zeitgetrieben statt (Vormittag, Nachmittag)

Sofern Interesse besteht, sind wir gerne bereit weitere Information zu teilen.

Hat auf jeden Fall Spass gemacht das Ganze aufzubauen und würden uns über Feedback freuen :grinning_face:

4 „Gefällt mir“

Hi, cool :slight_smile:

Hast du auch einen dynamischen Stromtarif und steuerst Auto/Speicher damit über EVCC?

Macht EVCC out of the Box.

Hallo TschonDoe,

wie Mark geschrieben hat: das kann evcc out-of-the-box (siehe Dynamische Stromtarife | evcc - Sonne tanken ☀️🚘 ). In unserem Fall optimieren mit evcc das Laden unseres E-Autos mit unserem selbst produzierten Strom und verwenden keine dynamischen Tarife.

Hallo Community,

sind gerade dabei ein github Projekt für die Geschichte aufzusetzen, danach sollte es einfacher sein, die Scripte sowie die Definitionen für den SG Ready Controller zu teilen. Aus Sicht des Benutzers stellt sich die ganze Sache so dar, dass es einmal ein …

… Admin Interface gibt, das es erlaubt, die Parameter für die Wärmepumpe für die OV-Optimierung zu konfigurieren. Der “daily-user” hat ein vereinfachtes Interface in einem Dashboard …

… um simple Aufgaben wie:

  • ist die PV-Optimierung der Wärmepumpe erwünscht bzw. nicht
  • ab welcher Uhrzeit Vormittags bzw. Nachmittags soll diese stattfinden

zu erledigen. Ansonsten überprüft das System automatisch: befindet sich die Wärempumpe …

  • im Programm-
  • nicht im Sommer-

Betrieb, da nur dann die PV-Optimierung angeworfen wird.

Update:

Hallo Community,

hoffen, dass die Geschichte mit github geklappt hat. Hier https://github.com/alb-sch/SG_Ready_Controller wäre der entsprechende Link, der Zugriff zur ESPHome Konfiguration des Controllers sowie den Home Assistant Scripts und Automations ermöglichen sollte.

Wie im Architekturbild dargestellt wird unsere Wärmepumpe (Fabrikat: Stiebel Eltron) über eine “SG Ready” Schnittstelle per Relaiskontakte gesteuert. Der Grund für diesen Ansatz ist schnell erklärt: die Steuerung über Relaiskontakte ist …

  • einfach
  • portabel … keine Modbus Register, die angepasst werden müssten, …

das Board …

…, das zur Implementierung verwendet wurde, ist bei einem großen Versandhaus für unter 15€ zu bekommen und funktioniert seit Monaten problemlos.

Der Controller, wie der Name schon impliziert :wink: , ist zuständig für die Ansteuerung der “SG Ready” Relais. Hier seine Repräsentation im Home Assistant UI:

Er stellt drei switches, die sehr leicht über Home Assistant angesteuert werden können, für die Betriebszustände 1, 3 und 4 zur Verfügung (Betriebszustand 2, also “Normalbetrieb”, wird repräsentiert über alle Schalter “aus”). Um sicherzustellen, dass die Wärmepumpe tatsächlich umgeschaltet hat, findet …

  • eine Synchronisation zwischen der “Stiebel Eltron ISG Integration” und dem Controller statt (konkret wird die Entity “sensor.stiebel_eltron_isg_sg_ready_state” synchronisiert)
  • wird diese Synchronisation über einen Timeout (“SG Ready Timeout”, siehe Bild oben) überwacht

Der Controller besitzt die Möglichkeit über “SG Ready Betriebszustand” in Richtung Homeassistant

  • Pending … Controller wartet auf Synchronisation mit der Wärmepumpe
  • Wärmepumpe hat die Betriebszustände 1-4 erreicht
  • Fehler (negativer Wert)

zu signalisieren. Dummerweise wird der Betriebszustand als float dargestellt … ist wohl eine Limitation von ESPHome, dass keine int übertragen werden können :roll_eyes: .

Neben einer möglichen fehlerhaften Synchronisation überwacht der Controller auch “wildes schalten” der Betriebszustände und erkennt dies als Fehler. “Wildes schalten” bedeutet z.B.

  • warte auf Betriebszustand 3 Rückmeldung der Wärmepumpe
  • EVU-Sperre wird gesetzt (ja, die EVU-Sperre hat “eigentlich” eine höhere Priorität ABER unser Controller erwartet hier ein sauberes “Zurückfahren” durch Home Assistant als Management System auf Betriebszustand 2 und dann erst ein Schalten von Betriebszustand 1)

Zusätzlich merkt sich der Controller wann er in die unterschiedlichen Betriebszustände geschaltet wurde:

  • Betriebszustand 1 Aktivierung
  • Betriebszustand 2 Aktivierung
  • Betriebszustand 3 Aktivierung
  • Betriebszustand 4 Aktivierung

Diese Information wird in den Automatisierung Scripten von Home Assistant genutzt um sicherzustellen, dass z.B. zwischen der Aktivierung von Betriebszustand 3 der Wärmepumpe (PV-Optimierung) mindestens 1h liegt (Vermeidung von zu häufigem Aktivieren der Wärmepumpe innerhalb eines kurzen Zeitraums).

Zuletzt stellt der Controller den Zustand der Relaiskontakte sowie einen Service zum Löschen eines Fehlerzustands zur Verfügung.

Im Nachhinein müssen wir “eingestehen”, dass unser Controller etwas “unterfordert” ist :wink: und noch zuviel an “Intelligenz” in den Jinja Templates bzw. Scripten von Home Assistant steckt. Für einen zukünftigen Release ist geplant dies besser auszubalancieren … aber nun soll sich dieser Setup zuerst im “Alltag” bewähren.

:crayon:by HarryP: Zusammenführung Doppelpost (bei Änderungen oder hinzufügen von Inhalten bitte die „Bearbeitungsfunktion“ anstatt „Antworten“ zu nutzen)

3 „Gefällt mir“

Danke für die super Doku. Ich finde leider bei den großen Online Anbietern das Board nicht. Kannst du bitte noch einen Hinweis oder einen Link posten?

Gruß

Martin

Hallo MartyBr,

here we go: das Versandhaus

Gruß

:+1:
Danke, habe das Teil bestellt.
Gruß
Martin

Hallo MartyrBr,

vergaß zu erwähnen, dass für die erste Programmierung ein USB-to-serial Adapter notwendig ist …

… inklusive einem Jumber Kabel …

… da das Board keinen USB-Port besitzt. Wir nutzen dafür:

… da geht mit Sicherheit auch etwas einfacheres. Das Ganze wird nur für die erste Programmierung benötigt, danach funktioniert der Update per WLAN.

Kannst du mir noch sagen, wie der USB-to-Serial-Adapter angeschlossen wird? Ich sehe auf dem SG-Ready-Controller keine Steckbrücken.
Gruß
Martin

Hallo MartyBr,

die Steckbrücken kommen mit und müssen eingelötet werden. Angeschlossen wird der Adapter an die einreihige Steckbrücke (wird als “Burn Interface” bezeichnet). Haben das Board “damals” mit 12V und nicht über den USB-to-serial Adapter versorgt. Klappte alles ohne Probleme :grinning_face:

Hallo Community,

nachdem der Controller mit seiner derzeitigen Funktionalität beschrieben ist, hier nun die evcc Seite der Geschichte. Unser evcc.yaml startet mit dem Üblichen …

# definition of site
site:
  title: Zuhause
  meters:
    grid: my_grid
    pv: my_pv
    battery: my_battery

… die loadpoints sind schon etwas interessanter …

# definition of loadpoints
loadpoints:
  - title: Garage
    ...
    priority: 10 # ensure, that Wallbox gets served first
    
  # definition of heatpump
  - title: Wärmepumpe
    charger: my_heatpump_control
    vehicle: my_heatpump
    meter: my_heatpump_power
    priority: 0 # ensure, that heatpump has the lowest priority
    enable:
      threshold: 4000 # Stiebel Eltron WPL-A 07 HK 230 Premium consumes max. 3,5kW
      delay: 30m # threshold needs to be exceed for at least 30 minutes
    disable:
      threshold: 500
      delay: 15m

… da hier definiert wird, dass unser E-Auto eine höhere Priorität als die Wärmepumpe bekommt und es wird ebenfalls definiert, dass (in unserem Fall) mindestens ein Überschuss von 4kW für 1/2h bestehen muss, bevor Betriebsmodus 3 der Wärmepumpe angeworfen wird.
Um die Einspeisung zu messen nutzen wir ein Shelly Pro 3em …

# definition of meters (see https://docs.evcc.io/docs/devices/meters)
meters:
  # Shelly Pro 3em as grid meter
  - name: my_grid
    type: template
    template: shelly-pro-3em
    usage: grid
    host: <your ip address>

  # Solarwatt PV
  - name: my_pv
    type: template
    template: solarwatt-flex
    usage: pv
    host: <your ip address>

  # Solarwatt Battery Flex
  # remark: the template as provided by evcc holds an error, therefore utilize a custom definition
  - type: custom
    Power:
      source: http
      uri: <your uri>
      headers:
      - content-type: application/json
      jq: .state|split(" ")[0]|split(".")[0]
    SoC:
      source: http
      uri: <your uri>
      headers:
      - content-type: application/json
      # jq: .state
      jq: .state | sub(" %"; "") | tonumber
    Energy:
      source: http
      uri: <your uri>
      headers:
      - content-type: application/json
      jq: .state|split(" ")[0]|split(".")[0]
      scale: 0.001
    name: my_battery

Haben der Vollständigkeit halber den Solarwatt Teil drin gelassen. Interessant ist an dieser Stelle der Wärmepumpenteil …

# definition for heatpump
  - name: my_heatpump_power
    type: custom
    power:
      source: http
      uri: http://homeassistant.local:8123/api/states/sensor.warmepumpe_summe_verbrauch
      method: GET
      jq: .state | tonumber
      headers:
        - content-type: application/json
        - Authorization: Bearer <your token>
    energy:
      source: http
      uri: http://homeassistant.local:8123/api/states/sensor.warmepumpe_energie_verbrauch
      method: GET
      jq: .state | tonumber
      headers:
        - content-type: application/json
        - Authorization: Bearer <your token>

… wir greifen, über REST, auf Sensoren unserer Home Assistant Instanz zu und ermöglichen es so die entsprechenden Werte im UI von evcc darzustellen. Notwendig hierfür ist ein sogenanntes “long lived access token”. Wie man dazu kommt ist u.a. hier beschrieben. Dank dieses Ansatzes konnten wir bisher MQTT vermeiden.
Nun kommt der interessanteste Teil:

# definition of charger (see https://docs.evcc.io/docs/devices/chargers)
chargers:
  - name: my_charger
    type: template
    template: openwb-pro
    host: <your ip address>
  
  # definition for heatpump as a smart switch
  - name: my_heatpump_control
    type: template
    template: homeassistant-switch
    baseurl: http://homeassistant.local:8123
    token: <your token>
    switchentity: input_boolean.anforderung_sg_ready_betriebszustand_3
    standbypower: -4000
    integrateddevice: true
    icon: heatpump

Unsere Wärmepumpe ist, wie schon in der Architekturübersicht gesagt, als “Smart Switch” aufgesetzt. evcc meint also es hätte es mit …


… zu tun :wink:. Wir haben sehr lange versucht ein komplettes “Fahrzeug” aufzusetzen … leider suchte evcc dann nach Parametern, die bei einer Wärmepumpe nicht zur Verfügung stehen/keinen Sinn machen. Unsere Lösung sieht nun eben so aus, dass evcc einen “Smart Switch” aktiviert, sobald aus seiner Sicht alle Randbedingungen erfüllt sind. Deaktiviert wird dieser “Smart Switch” von Home Assistant über …

# definition of vehicle
vehicles:
  - name: my_car
    ...
    
  # definition for heatpump
  - name: my_heatpump
    type: template
    template: homeassistant
    title: 'Stiebel Eltron'
    icon: heater
    uri: http://homeassistant.local:8123 # address of Home Assistant instance
    token: <your token> 
    phases: 3
    soc: sensor.heatpump_pv_optimization_soc

… einen simulierten SoC, der es uns ermöglicht im evcc UI das Aufheizen des Wassers durch die Wärmepumpe in Betriebszustand 3 zu visualisieren.
Damit wäre der evcc Anteil komplett.

Hallo Community,

nun zum letzten Teil: Automations, Scripts und Sensoren. Wie im letzten Teil beschrieben “denkt” evcc unsere Wärmepumpe wäre ein “Smart Sensor” und schaltet diesen, sofern …

  • Priorität
  • Wert und Dauer des PV-Überschuss

… stimmen, ein. Auf dieses “Einschalten” reagiert nun …

# trigger start PV-optimization for heatpump
- id: sg_ready_request_start_pv_optimization
  alias: Heatpump PV Optimization Starter (including delay)
  trigger:
    - platform: state
      entity_id: input_boolean.anforderung_sg_ready_betriebszustand_3
      to: 'on'
      for: '00:01:00'  # must be active for at least 1 min

  action:
    - service: script.heatpump_start_pv_optimization
      data: {}

… und aktiviert …

# turn on PV-Optimization
heatpump_start_pv_optimization:
  alias: Start PV Optimization for Heatpump
  sequence:
    - if:
        # if sg_ready_vorbedingung
        - condition: state
          entity_id: sensor.heatpump_pv_optimization_precondition
          state: "bereit"
      then:
        - service: timer.cancel
          data:
            entity_id: timer.heatpump_pv_optimization_timeout

        - service: switch.turn_on
          data:
            entity_id: switch.sgreadycontroller_sg_ready_betriebszustand_3
            
        - service: logbook.log
          data:
            name: Heatpump PV-Optimization
            message: "Heatpump PV-Optimization: start script called - SG Ready Betriebszustand 3 activated."
      else:
        # ensure, that switch requesting Betriebszustand 3 is turned off
        - service: input_boolean.turn_off
          data:
            entity_id: input_boolean.anforderung_sg_ready_betriebszustand_3
          
        - service: logbook.log
          data:
            name: Heatpump PV-Optimization
            message: "Heatpump PV-Optimization: start script called - SG Ready condition not met, nothing to be done here."

… das als erstes überprüft “sind alle Bedingungen zum Versetzen der Wärmepumpe in Betriebszustand 3 innerhalb von Home Assistant erfüllt” (diese Bedingung ist als eigenständiger Sensor “heatpump_pv_optimization_precondition” definiert, so dass er sehr schnell auf individuelle Bedürfnisse angepasst werden kann). Warum ist diese Abprüfung notwendig?
Home Assistant “kennt” mehr Parameter bzgl. der Wärmepumpe als evcc z.B.: befindet sich die Wärmpumpe im …

  • “Sommer Betrieb” … aus unserer Sicht macht im Sommer ein Betriebszustand 3 wenig Sinn, da genügend Solarstrom exisitert, so dass die reguläre Zeitsteuerung, ausreichend ist
  • “Programmbetrieb” … nur in diesem Zustand sollte Betriebszustand 3 aktiviert werden. Dies im “Ferienbetrieb” zu machen, macht ebenfalls weniger Sinn :wink:

Als Design Principle wählten wir KISS, “Keep It Simple and Stupid” gewählt, was an dieser Stelle bedeutet: das System reagiert, neben dem PV-Überschuss und den Prioritäten der Verbraucher, rein Zeit getrieben. Wie schon in einem unserer früheren Beiträge dargestellt bedeutet dies, dass eine Zeit am …

  • Vormittag
  • Nachmittag

… vorgegeben werden kann, ab der Betriebszustand 3 potentiell aktiviert wird.
Die Grundlegende Annahme an dieser Stelle ist, dass damit sichergestellt wird, dass für uns …

  • transparent
  • klar

… nachvollziehbar ist, welches Subsystem (Wallbox, Wärmepumpe, …), wann aktiv ist und was genau macht. Hatten kurz darüber nachgedacht, die PV-Prognose von Home Assistant an dieser Stelle mit einzubeziehen … das wurde dann aber etwas zu komplex und wir waren uns nicht sicher, ob sich diese Komplexität wirklich ausgezahlt hätte :wink:.
Aber zurück zum Script: heatpump_start_pv_optimization kommandiert nun unser SG Ready Controller Betriebszustand 3 zu aktivieren. Die Wärmepumpe reagiert entsprechend. Der interessante Teil ist nun …

# Calculate virtual SoC of heatpump
- name: "heatpump_pv_optimization_soc"
  unique_id: "heatpump.sg_ready_soc"
  icon: mdi:water-percent
  unit_of_measurement: "%"
  state: >
    {% set precondition = states('sensor.sg_ready_vorbedingungen') == 'bereit' %}
        
    {% set request_betriebszustand_1 = is_state('switch.sgreadycontroller_sg_ready_betriebszustand_1', 'on') %}
    {% set request_betriebszustand_3 = is_state('switch.sgreadycontroller_sg_ready_betriebszustand_3', 'on') %}
    {% set request_betriebszustand_4 = is_state('switch.sgreadycontroller_sg_ready_betriebszustand_4', 'on') %}

    {# ensure, that average grid feed-in is within range #}
    {% set is_grid_feed_in = is_state('sensor.heatpump_pv_optimization_avg_grid_feed_in', 'bereit') %}        
       
    {% set actual_betriebszustand = states('sensor.sgreadycontroller_sg_ready_betriebszustand') | float %}
        
    {% set betriebszustand_is_error = actual_betriebszustand < 0 %}
    {% set betriebszustand_is_0 = actual_betriebszustand > -0.5 and actual_betriebszustand < 0.5 %}
    {% set betriebszustand_is_3 = actual_betriebszustand > 2.5 and actual_betriebszustand < 3.5 %}
          
    {% if betriebszustand_is_error %}
      unknown
    {% elif precondition or (not request_betriebszustand_1 and request_betriebszustand_3 and not request_betriebszustand_4 and betriebszustand_is_0) %}
    {# value must be bigger than 0, otherwise it will be rejected by evcc #}
      1
    {% elif not request_betriebszustand_1
            and request_betriebszustand_3
            and not request_betriebszustand_4
            and is_grid_feed_in
            and betriebszustand_is_3 %}
      {# calculate real SoC #}
      {{ [ (states('sensor.stiebel_eltron_isg_actual_temperature_water') | float 
         / states('number.stiebel_eltron_isg_comfort_water_temperature_target') | float(1) * 100) | round(1), 100 ] | min }}
    {% else %}
      100
    {% endif %}

… ein Sensor, der evcc einen SoC simuliert. Letzten Endes wird hier die Zieltemperatur des warmen Wassers in Relation zur aktuellen Temperatur gesetzt :wink: … wird 100% erreicht, wird unser virtueller “Smart Switch” wieder über …

# trigger heatpump 'fully charged' after PV-optimization
- id: sg_ready_pv_optimization_finalized
  alias: Stop Heatpump PV Optimization when SoC full
  trigger:
    - platform: numeric_state
      entity_id: sensor.heatpump_pv_optimization_soc
      above: 99.9

  condition:
    - condition: state
      entity_id: input_boolean.anforderung_sg_ready_betriebszustand_3
      state: 'on'

  action:
    - service: input_boolean.turn_off
      target:
        entity_id: input_boolean.anforderung_sg_ready_betriebszustand_3

    - service: logbook.log
      data:
        name: Heatpump PV-Optimization
        message: "Heatpump PV-Optimization: SoC > 99.9% – Anforderung Betriebszustand 3 deactivated."
        entity_id: input_boolean.anforderung_sg_ready_betriebszustand_3

  mode: single

… zurückgesetzt und kann erneut aktiviert werden.
Das ganze läuft nun schon seit mehrere Wochen. Die Prioritätssteuerung von evcc funktioniert ohne Probleme, so dass das Laden unseres E-Autos Betriebszustand 3 der Wärmepumpe verhindert hat.
Das Verhalten des Gesamtsystem ist nun deutlich nachvollziehbarer, was den WAF um einiges erhöht hat :wink:
Es hat Spass gemacht, das Ganze umzusetzen. In einem der nächsten Schritte, der aber vermutlich erst später erfolgen wird, soll mehr Intelligenz in den Controller verlagert werden, so dass Home Assistant “lediglich” …

  • Precondition für Betriebsart 3
  • SoC-Berechnung
    … liefert. Alles andere soll dann im Controller laufen …

Hoffen das unser kleines Projekt euer Interesse findet und euch zum Nachbau anregt :grinning_face:

1 „Gefällt mir“