Bosch Wärmepumpe in Home Assistant integrieren und steuern dieser mit Leistungsüberschuss der PV-Anlage

Hallo zusammen,

ich möchte hier meine Erfahrungen und Lösungen teilen, wie ich meine Bosch Wärmepumpe Compress 5800i AW 12 ORE-T zusammen mit einer PV-Anlage in Home Assistant (HA) integriert und ein intelligentes Energiemanagement umgesetzt habe.


Ausgangslage

Seit etwa einem Jahr habe ich die Bosch Wärmepumpe und eine PV-Anlage installiert. Die PV-Anlage und die Tesla Powerwall ließen sich problemlos in HA integrieren (z.B. mit der „SMA Solar“ und der “Tesla Powerwall” Integration). Die Wärmepumpe von Bosch war allerdings schwieriger: Bosch stellt keine offizielle Schnittstelle für die über 150 Entitäten der Wärmepumpe zur Verfügung.


Lösung: EMS-Bus-Gateway von BBQKees Electronics

Nach längerer Recherche bin ich auf das EMS-Bus-Gateway von BBQKees Electronics gestoßen. Dieses Gateway bietet eine umfangreiche Knowledge Base und lässt sich gut über Matter in HA integrieren. So habe ich endlich Zugriff auf die Wärmepumpen-Daten bekommen.


Dashboard

Mein erstes Ziel war ein Dashboard mit den wichtigsten Wärmepumpen-Daten. Dabei hat mir die Webseite bosch-buderus-wp.github.io sehr geholfen.

Hier mein Dashboard:


Energiemanagement – Motivation

Bosch bietet einen kostenpflichtigen Energiemanager an, der die Wärmepumpe abhängig vom PV-Überschuss steuert:

Viel PV-Strom-Überschuss → Wärmepumpe läuft intensiver
Kein PV-Überschuss → Wärmepumpe im Normalmodus

Ich wollte das in Home Assistant selbst umsetzen: Ein umfassendes System, das PV-Überschuss, Hausverbrauch und Powerwall-Ladestatus intelligent auswertet und steuert. Dabei sollten auch Temperaturbedingungen berücksichtigt werden. Das System sollte flexibel über Schalter und Zahlen steuerbar sein und automatisch die Wärmepumpe je nach Restüberschuss regeln.


Bestandteile und Funktionen meines Energy Manager Packages

1. Helpers / Controls

  • input_boolean.energy_manager_enabled
    Manuelle Aktivierung des Energy Managers (Standard: an).

  • input_boolean.energy_manager_force_on / force_off
    Erzwingen oder Deaktivieren unabhängig vom Hauptschalter.

  • input_boolean.energy_manager_temp_ok
    Zeigt an, ob die Temperaturbedingungen passen (wird über Automationen gesetzt).

  • input_number.pw_max_charge
    Max. Ladeleistung der Powerwall (kW), z.B. 4,6 kW.

  • input_number.energy_manager_temp_start / energy_manager_temp_stop
    Temperaturhysterese für Aktivierung des Managers (z.B. 14°C Start, 17°C Stop).


2. Filter Sensoren (Glättung)

Zur Vermeidung von Schwankungen werden Rohdaten geglättet:

  • sensor.pv_power_smoothed – geglättete PV-Leistung (Lowpass-Filter)

  • sensor.home_load_smoothed – geglätteter Hausverbrauch (gleitender Durchschnitt)

  • sensor.powerwall_battery_power_smoothed – geglättete Powerwall-Leistung (Lowpass)


3. Template Sensors (Kernlogik)

Berechnung wichtiger Steuergrößen:

  • energy_surplus
    PV-Leistung minus Hausverbrauch (positiv = Überschuss).

  • pw_max_charge
    Maximal erlaubte Powerwall-Ladeleistung (aus input_number).

  • pw_current_charge
    Aktuelle Ladeleistung der Powerwall (negative Werte = Laden).

  • to_battery_power
    Wie viel vom Überschuss maximal in die Powerwall geladen werden kann.

  • available_for_heatpump
    Verbleibender Überschuss für die Wärmepumpe nach Powerwall-Ladung.

  • energy_manager_active
    Status, ob der Energy Manager aktiv ist (abhängig von Schaltern und Temperatur).


4. Automationen

  • Temperatur Hysterese
    Setzt energy_manager_temp_ok je nach Außentemperatur (Start/Stop).

  • Wärmepumpe Überschusssteuerung

    • Bei genügend Überschuss und Powerwall SOC ≥ 95 % wird das Thermostat auf 25°C gesetzt (Heizbetrieb).

    • Bei wenig Überschuss wird auf 21°C zurückgestellt.

    • Benachrichtigungen informieren über Start/Stop.

  • Powerwall Priorisierung (Variante A)
    Versucht bei Überschuss und SOC < 95 % die Powerwall bevorzugt zu laden.
    (Hier ist ein Platzhalter für einen Service-Aufruf, der je nach Integration ergänzt werden muss.)


Package Struktur

```yaml
# config/packages/energy_manager.yaml

# --- Helpers / Controls ---
input_boolean:
  energy_manager_enabled:
    name: "Energy Manager aktiv"
    initial: on
  energy_manager_force_on:
    name: "Energy Manager erzwingen"
    initial: off
  energy_manager_force_off:
    name: "Energy Manager deaktivieren"
    initial: off
  energy_manager_temp_ok:
    name: "Energy Manager: Temp OK"
    initial: on

input_number:
  pw_max_charge:
    name: "Powerwall max Ladeleistung (kW)"
    initial: 4.6
    min: 0
    max: 11.0
    step: 0.1
    unit_of_measurement: kW

  energy_manager_temp_start:
    name: "EM Temp Start (°C)"
    initial: 14
    min: -40
    max: 40
    step: 0.5

  energy_manager_temp_stop:
    name: "EM Temp Stop (°C)"
    initial: 17
    min: -40
    max: 40
    step: 0.5

# --- Filter Sensoren (Glättung) ---
# Diese Sensoren glätten kurzzeitige Fluktuationen. Die erzeugten entity_ids lauten:
# sensor.pv_power_smoothed, sensor.home_load_smoothed, sensor.powerwall_battery_power_smoothed
sensor:
  - platform: filter
    name: "PV Power (smoothed)"
    entity_id: sensor.my_home_solar_energie       # <-- deine PV entity
    filters:
      - filter: lowpass
        time_constant: 5
        precision: 0.1

  - platform: filter
    name: "Home Load (smoothed)"
    entity_id: sensor.my_home_last_leistung       # <-- dein Hausverbrauch entity 
    filters:
      - filter: time_simple_moving_average
        window_size: 5
        precision: 0.1

  - platform: filter
    name: "Powerwall Battery Power (smoothed)"
    entity_id: sensor.my_home_batterie_leistung   # <-- Powerwall Leistung entity
    filters:
      - filter: lowpass
        time_constant: 10
        precision: 0.1

# --- Template Sensors (Kernlogik) ---
# Erzeugt u.a. sensor.energy_surplus, sensor.to_battery_power, sensor.available_for_heatpump
template:
  - sensor:
      - name: "energy_surplus"
        unit_of_measurement: "kW"
        state: >
          {% set pv = states('sensor.pv_power_smoothed')|float(0) %}
          {% set load = states('sensor.home_load_smoothed')|float(0) %}
          {{ (pv - load) | round(2) }}

      - name: "pw_max_charge"
        unit_of_measurement: "kW"
        state: >
          {{ states('input_number.pw_max_charge') | float(4.6) }}

      - name: "pw_current_charge"
        unit_of_measurement: "kW"
        state: >
          {% set p = states('sensor.powerwall_battery_power_smoothed')|float(0) %}
          {# Annahme: negative Werte = Laden. Falls bei dir positive Werte Laden anzeigen, ändere p < 0 in p > 0 und entferne das negative Vorzeichen unten. #}
          {% if p < 0 %}
            {{ (-p) | round(2) }}
          {% else %}
            0
          {% endif %}

      - name: "to_battery_power"
        unit_of_measurement: "kW"
        state: >
          {% set surplus = states('sensor.energy_surplus')|float(0) %}
          {% set max_in = states('sensor.pw_max_charge')|float(4.6) %}
          {% set current = states('sensor.pw_current_charge')|float(0) %}
          {% set remaining = (max_in - current) if (max_in - current) > 0 else 0 %}
          {% if surplus > 0 %}
            {{ [surplus, remaining] | min | round(2) }}
          {% else %}
            0
          {% endif %}

      - name: "available_for_heatpump"
        unit_of_measurement: "kW"
        state: >
          {% set surplus = states('sensor.energy_surplus')|float(0) %}
          {% set to_batt = states('sensor.to_battery_power')|float(0) %}
          {% if surplus > 0 %}
            {{ (surplus - to_batt) | round(2) if (surplus - to_batt) > 0 else 0 }}
          {% else %}
            0
          {% endif %}

      - name: "energy_manager_active"
        state: >
          {% set force_on = is_state('input_boolean.energy_manager_force_on','on') %}
          {% set force_off = is_state('input_boolean.energy_manager_force_off','on') %}
          {% if force_off %}
            off
          {% elif force_on %}
            on
          {% else %}
            {% set manual = is_state('input_boolean.energy_manager_enabled','on') %}
            {% set temp_ok = is_state('input_boolean.energy_manager_temp_ok','on') %}
            {{ 'on' if (manual and temp_ok) else 'off' }}
          {% endif %}
        attributes:
          manual_enabled: "{{ states('input_boolean.energy_manager_enabled') }}"
          temp_ok: "{{ states('input_boolean.energy_manager_temp_ok') }}"

# --- Automationen ---
automation:
  # Temperatur Hysterese: setzt input_boolean.energy_manager_temp_ok
  - alias: EM Temp OK einschalten
    description: ""
    mode: single
    trigger:
      - platform: state
        entity_id: sensor.boiler_air_inlet_temperature_tl2
    condition:
      - condition: template
        value_template: >
          {{ states('sensor.boiler_air_inlet_temperature_tl2') | float < states('input_number.energy_manager_temp_start') | float }}
    action:
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean.energy_manager_temp_ok

  - alias: EM Temp OK ausschalten
    description: ""
    mode: single
    trigger:
      - platform: state
        entity_id: sensor.boiler_air_inlet_temperature_tl2
    condition:
      - condition: template
        value_template: >
          {{ states('sensor.boiler_air_inlet_temperature_tl2') | float > states('input_number.energy_manager_temp_stop') | float }}
    action:
      - service: input_boolean.turn_off
        target:
          entity_id: input_boolean.energy_manager_temp_ok

  # Wärmepumpe: nutzt restlichen Überschuss (setzt Number auf 25 zum Start, 21 zum Stop)
  - alias: "EM: Wärmepumpe nur bei Restüberschuss"
    description: "Setzt thermostat setpoint auf 25°C wenn genug Restüberschuss und Powerwall SOC >= 95%, sonst 21°C"
    trigger:
      - platform: state
        entity_id: sensor.available_for_heatpump
    condition:
      - condition: state
        entity_id: sensor.energy_manager_active
        state: 'on'
      - condition: numeric_state
        entity_id: sensor.my_home_ladung  # Powerwall SOC
        above: 95
    action:
      - choose:
          - conditions:
              - condition: numeric_state
                entity_id: sensor.available_for_heatpump
                above: 0.5
            sequence:
              - service: number.set_value
                data:
                  entity_id: number.thermostat_hc1_manual_temperature
                  value: 25
              - service: notify.persistent_notification
                data:
                  title: "EM: WP Start"
                  message: "WP Setpoint => 25°C (available_for_heatpump={{ states('sensor.available_for_heatpump') }})"
              - delay:
                  minutes: 10
          - conditions:
              - condition: numeric_state
                entity_id: sensor.available_for_heatpump
                below: 0.2
            sequence:
              - service: number.set_value
                data:
                  entity_id: number.thermostat_hc1_manual_temperature
                  value: 21
              - service: notify.persistent_notification
                data:
                  title: "EM: WP Stop"
                  message: "WP Setpoint => 21°C (available_for_heatpump={{ states('sensor.available_for_heatpump') }})"

  # Variante A: Powerwall direkt priorisieren (Device Action erforderlich)
  - alias: "EM: Powerwall zuerst (Device Action Variante)"
    description: "Versucht, Powerwall Priorität zu geben wenn Überschuss & SOC < Ziel"
    trigger:
      - platform: numeric_state
        entity_id: sensor.energy_surplus
        above: 0.6
    condition:
      - condition: template
        value_template: "{{ is_state('sensor.energy_manager_active','on') }}"
      - condition: numeric_state
        entity_id: sensor.my_home_ladung    # <-- Powerwall SOC
        below: 95
    action:
      - service: notify.persistent_notification
        data:
          title: "EM: Powerwall Priorität"
          message: "Hier noch die Möglichkeit die Battery-Priorität zu aktivieren, was bei mir die Powerwall übernimmt"
      # ---- WICHTIG: Ersetze den folgenden Platzhalter mit der Device Action / dem Service, den deine Powerwall Integration unterstützt.
      # Beispiel (nur als Hinweis):
      # - service: powerwall.set_backup_reserve
      #   data:
      #     entity_id: <dein powerwall device>
      #     backup_reserve_percent: 5
      # Wenn deine Integration keine direkte Device Action anbietet, verwende Variante B (Verbrauchssteuerung), die bereits oben steht.
      - wait_for_trigger:
          - platform: numeric_state
            entity_id: sensor.my_home_ladung
            above: 90
            for:
              minutes: 1
      - service: notify.persistent_notification
        data:
          title: "EM: Powerwall - Ladeziel erreicht"
          message: "Bitte restore Reserve / Normalbetrieb manuell prüfen"
```

Funktionsweise im Überblick

  1. Datenaufnahme & Glättung: Rohdaten von PV, Hausverbrauch und Batterie werden geglättet.

  2. Überschussberechnung & Verteilung: Überschuss wird ermittelt und dynamisch auf Powerwall-Ladung und Wärmepumpe verteilt.

  3. Temperaturabhängige Aktivierung: Energy Manager arbeitet nur bei passenden Temperaturen.

  4. Automatische Steuerung: Wärmepumpe läuft nur bei Restüberschuss; Powerwall wird bei niedrigem SOC bevorzugt geladen.

  5. Manuelle Steuerung: Über Input Booleans kann der Manager ein-/ausgeschaltet oder erzwungen werden.


Visualisierung im Dashboard

Im Hauptdashboard zeige ich aktuell nur den Betriebsmodus der Wärmepumpe mit einer custom:button-card an:

Betriebsmodus WP

Wichtig: Wenn du das so in einem Editor oder Forum einfügst, entferne die äußeren Anführungszeichen hier, damit die Backticks korrekt erkannt werden.

Also in deinem Beitrag einfach so einfügen (ohne die erklärenden Zeilen):

type: custom:button-card
name: null
show_icon: false
show_state: true
state_display: |
  [[[
    const val = states['number.thermostat_hc1_selected_room_temperature']?.state;
    if (val === '21.0') return 'Normalbetrieb';
    if (val === '25.0') return 'Extra aufheizen';
    return 'Status unbekannt';
  ]]]
styles:
  card:
    - padding: 12px
    - font-size: 16px
    - text-align: center
    - color: white
    - background-color: |
        [[[
          const val = states['number.thermostat_hc1_selected_room_temperature']?.state;
          if (val === '21.0') return 'green';
          if (val === '25.0') return 'orange';
          return 'gray';
        ]]]

Zusätzlich habe ich ein rudimentäres Dashboard mit allen relevanten Entitäten zur Steuerung der Wärmepumpe erstellt (rein zur Übersicht und prüfen der Daten die alles steuern):


Fazit und Ausblick

Das System läuft bei mir seit kurzem und der Winter steht noch bevor. Ich hoffe auf viel Sonne und werde hier berichten, wenn ich weitere Optimierungen vornehme.


Ich freue mich auf Feedback, Fragen oder Anregungen!

Viele Grüße

René

4 „Gefällt mir“

Hi, Ich finde deine Projekt sehr interessant, ich plane für unser Haus gerade ein sehr ähnliches Projekt. Meine aktuelle Konfiguration ist folgende: 8kW Solar Leistung auf dem Dach und 1000l Pufferspeicher für Warmwasser welche auch per Heizstab erwärmt werden können. Dazu eine ältere Ölheizung die ich gerne noch beibehalten würde und die ebenfalls im HomeAssistant eingebunden ist

Ich bin gerade dabei ein Bosch compress 7001i aw 13 Wärmepumpe zu besorgen. Diese müsste ebenfalls über das gleiche EMS-Bus System steuerbar sein.

Ich habe allerdings paar Fragestellungen die mir noch nicht ganz klar sind:

Wird die EMS Bus Gateway Box direkt an die Wärmepumpe angeschlossen, oder brauche ich noch zusätzliche Hardware von Bosch die dazwischen geschaltet wird? Und welches Gateway Modell verwendest du genau?

Welche konkreten Steuerparameter können an die Wärmepumpe übergeben werden? (Also nur vordefinierte Betriebsmodi von Bosch selber? Optimal für mich wäre es, wenn die Leistung und Vorlauftemperatur selber stufenlos eingestellt werden kann)

Ich verwende das Gateway E32 V2 KIT (Ethernet + WiFi Edition V2 KIT), das kommt mit allem, was man braucht, der Box und in Kabeln

Bei meiner Wärmepumpe habe ich das Gateway direkt über die Service Buchse (Klinkenstecker) angeschlossen, möglich wäre dies aber auch noch über Klemmen, die es gibt.

Damit die Wärmepumpe bei überschüssige Energie aktiv wird, setze ich einfach die gewünschte Zimmertemperatur hoch (bei mir von 21° auf 25° ), dadurch geht die Wärmepumpe in den Heizmodus. Ist keine überschüssige Energie von der Solaranlage mehr vorhanden, wird die gewünschte Zimmertemperatur wieder runtergesetzt, wodurch die Wärmepumpe ausgeschaltet wird.

Grundsätzlich ist es der Effekt, dass ich tagsüber bei überschüssiger Solar Energie her aufheizen und sich die Temperatur über Nacht wieder abbaut.

Was ich noch nicht probiert habe, ist direkt auf die Vorlauftemperatur einzuwirken, wäre vielleicht ein ganz guter Ansatz.

Wenn du auch weitere Erfahrungen gesammelt hast, bin ich gespannt auf deine Ergebnisse.

So, nachdem alles ein bisschen gelaufen ist, habe ich ein paar Punkte in der Automatisierung angepasst.

Im folgenden findet Ihr die neuen Automatisierungen, die Steuerung der Powerwall habe ich jetzt komplett eliminiert, weil sie in meinem Fall nicht notwendig ist.


# --- Automationen ---
automation:
  # Temperatur Hysterese: setzt input_boolean.energy_manager_temp_ok
  - alias: EM Temp OK einschalten
    description: ""
    mode: single
    trigger:
      - platform: state
        entity_id: sensor.boiler_air_inlet_temperature_tl2
    condition:
      - condition: template
        value_template: >
          {{ states('sensor.boiler_air_inlet_temperature_tl2') | float < states('input_number.energy_manager_temp_start') | float }}
    action:
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean.energy_manager_temp_ok

  - alias: EM Temp OK ausschalten
    description: ""
    mode: single
    trigger:
      - platform: state
        entity_id: sensor.boiler_air_inlet_temperature_tl2
    condition:
      - condition: template
        value_template: >
          {{ states('sensor.boiler_air_inlet_temperature_tl2') | float > states('input_number.energy_manager_temp_stop') | float }}
    action:
      - service: input_boolean.turn_off
        target:
          entity_id: input_boolean.energy_manager_temp_ok

  # Wärmepumpe einschalten (setze auf 25°C)
  - alias: "EM: Wärmepumpe einschalten bei Überschuss"
    description: "Setzt thermostat setpoint auf 25°C wenn genug Restüberschuss und Powerwall SOC >= 50%"
    mode: single
    trigger:
      - platform: numeric_state
        entity_id: sensor.available_for_heatpump
        above: 0.5
        for: "00:00:30"
    condition:
      - condition: state
        entity_id: sensor.energy_manager_active
        state: 'on'
      - condition: numeric_state
        entity_id: sensor.my_home_ladung  # Powerwall SOC
        above: 50
      - condition: numeric_state
        entity_id: sensor.available_for_heatpump
        above: 0.5
    action:
      - service: number.set_value
        data:
          entity_id: number.thermostat_hc1_manual_temperature
          value: 25
      - service: notify.persistent_notification
        data:
          title: "EM: WP Start"
          message: "WP Setpoint => 25°C (available_for_heatpump={{ states('sensor.available_for_heatpump') }})"

  # Wärmepumpe zurücksetzen (setze auf 21°C) - unabhängig vom SOC
  - alias: "EM: Wärmepumpe zurücksetzen bei geringem Überschuss"
    description: "Setzt thermostat setpoint auf 21°C wenn Restüberschuss unter 0.2 kW, unabhängig vom SOC"
    mode: single
    trigger:
      - platform: numeric_state
        entity_id: sensor.available_for_heatpump
        below: 0.2
        for: "00:00:30"
    condition:
      - condition: state
        entity_id: sensor.energy_manager_active
        state: 'on'
      - condition: numeric_state
        entity_id: sensor.available_for_heatpump
        below: 0.2
    action:
      - service: number.set_value
        data:
          entity_id: number.thermostat_hc1_manual_temperature
          value: 21
      - service: notify.persistent_notification
        data:
          title: "EM: WP Stop"
          message: "WP Setpoint => 21°C (available_for_heatpump={{ states('sensor.available_for_heatpump') }})"

  # Start-Check: beim HA-Start Setpoint sicherstellen
  - alias: "EM: Start-Check Setpoint"
    description: "Stellt beim Home Assistant Start den richtigen Setpoint basierend auf aktuellen Bedingungen sicher"
    mode: single
    trigger:
      - platform: homeassistant
        event: start
    condition:
      - condition: state
        entity_id: sensor.energy_manager_active
        state: 'on'
    action:
      - choose:
          - conditions:
              - condition: numeric_state
                entity_id: sensor.available_for_heatpump
                above: 0.5
              - condition: numeric_state
                entity_id: sensor.my_home_ladung
                above: 50
            sequence:
              - service: number.set_value
                data:
                  entity_id: number.thermostat_hc1_manual_temperature
                  value: 25
              - service: notify.persistent_notification
                data:
                  title: "EM: WP Start (Start-Check)"
                  message: "WP Setpoint => 25°C (Start-Check: available_for_heatpump={{ states('sensor.available_for_heatpump') }})"
          - conditions:
              - condition: numeric_state
                entity_id: sensor.available_for_heatpump
                below: 0.2
            sequence:
              - service: number.set_value
                data:
                  entity_id: number.thermostat_hc1_manual_temperature
                  value: 21
              - service: notify.persistent_notification
                data:
                  title: "EM: WP Stop (Start-Check)"
                  message: "WP Setpoint => 21°C (Start-Check: available_for_heatpump={{ states('sensor.available_for_heatpump') }})"

Moin, bei mir sind jetzt noch paar offene Fragen aufgekommen: Kann denn somit die aufgenommene Leistung der Wärmepumpe über die Temperatur gesteuert werden, oder zieht sie bei PV Überschuss beliebig Strom, also unter Umständen sogar meistens mehr als die PV liefert?

Oder bekommt die Wärmepumpe die aktuelle überschüssige Energieleistung als Wert übergeben und zieht dann automatisch nicht mehr als diesen Wert?

Und wenn die Leistung doch indirekt selber reguliert werden kann, wie viele Temperaturparameter werden übergeben? Es gibt ja den selbst definierten Soll Wert (du wechselst zwischen 21 °C und 25 °C, Zeitgleich müsste es ja aber auch einen Ist Wert von der Wärmepumpe geben. Ich würde mir eine Lösung dabei so vorstellen, das man Soll auf 21 °C setzt und den Ist auf 20 °C, nach meiner Überlegung nach müsste die Wärmepumpe dann hoffentlich weniger Leistung ziehen weil die Differenz nur gering ist, und bei Soll 30°C und Ist 20°C müsste die Wärmepumpe dann mehr Leistung ziehen, jetzt die Frage, ist das so? Oder funktioniert die Wärmepumpe nur in einem ON/OFF Modus?

Als alternatives Szenario wäre dann noch das mit der Vorlauftemperatur, also falls du damit auch noch experimentieren wirst wäre es dann auch interessant zu wissen ob da ein geregelter Betrieb der Leistungsaufnahme bei geringen Temperaturdifferenzen möglich ist, oder ebenfalls nur ein ON/OFF Betrieb.

Und sehr großen Dank für deine Antworten, das hilft mir bei der Planung meines Systems sehr weiter.

Ich kann nur von meiner eigenen Konstellation mit PV‑Anlage, Wärmepumpe und Powerwall berichten.

Wenn ich bei mir die gewünschte Soll‑Temperatur erhöhe und die übrigen Rahmenbedingungen erfüllt sind (niedrige Außentemperatur und Raumtemperatur unter der Soll‑Temperatur), beginnt die Wärmepumpe sofort zu heizen.

Meine Automation „EM: Wärmepumpe einschalten bei Überschuss“ greift jedoch nur, wenn überschüssige Energie > 0,5 kWh vorhanden ist — dieser Wert reicht bei mir für den Betrieb der Wärmepumpe, basierend auf längeren Beobachtungen des Verbrauchs. Fällt der Überschuss auf unter 0,2 kWh, wird die Wärmepumpe wieder “abgeschaltet”.

Die Powerwall wird bei mir zuerst geladen; erst wenn danach noch Überschuss übrig ist, wird dieser beispielsweise für die Wärmepumpe verwendet.

Zum Setzen des Soll‑Wertes: Je höher du die Zieltemperatur (Soll-Wert) wählst, desto mehr Energie wird zum Aufheizen benötigt, denn eine Wärmepumpe arbeitet solange, bis die Soll‑Temperatur erreicht ist. Also sie verbraucht nicht in der gleichen Zeit mehr sondern läuft über einen längeren Zeitraum um die Soll-Temperatur zu erreichen. Bei mir erfolgt das Aufheizen sehr linear (Ausnahme: Boost‑Modus).

Im Bild oben: Oben der Sollwert und unten die Verbrauchte Energie

Ich hoffe, das hilft dir weiter — ich optimiere meine Steuerung ebenfalls noch und bin auf mehr Sonne angewiesen, die aktuell leider knapp ist.

Hi René,
tolle Vorarbeit!
Ich habe eine 7800i seit über einem Jahr am laufen und habe auch schon länger die gleichen Gedanken wie du, allerdings noch nicht umgesetzt: der Bosch Energiemanager muss doch leicht nachgebaut werden können!
Ich habe auch das BBQKees Gateway gefunden aber noch nicht bestellt:

  1. warum ist dieser die einzige Alternative am Markt?
  2. geht es auch mit dem Bosch Smart Home Controller? Oder stehen da weniger Werte zur Verfügung?
  3. und warum ist dieser Bosch Support so grottig :roll_eyes: (hier brauche ich keine Antwort :upside_down_face: )

Hinweis für die Automation:

Kompressorstarts haben Auswirkung auf die Lebensdauer. Ich habe deine Implementierung noch nicht im Detail durchgesehen, aber ein Limit der Starts pro Tag würde ich auf jeden Fall empfehlen.

Hallo Sven,

Ich selber habe auch lange nach Möglichkeiten gesucht, um an die Daten der Bosch Wärmepumpe zu kommen und leider war dies die einzigste Alternative, die ich gefunden habe.

Bosch ist hier wirklich etwas knauserig und gibt einem keinen Zugang zu seinen Daten nicht über eine AP oder einen anderen Weg, obwohl die Daten ja auch teilweise in der zugehörigen App zur Verfügung stehen.

Du kannst so etwas natürlich auch fertig von Bosch kaufen, das so genannte Bosch Energiemanagementsystemdas glaube ich weit über 1000 € kostet. Dieses Energie Management System soll die Wärmepumpe dann auch in Abhängigkeit von zum Beispiel Solarstrom Steuern. Ein Bekannter von mir hat sich das gegönnt und ist sehr enttäuscht, denn die versprochener Einsparung ist praktisch nicht vorhanden.

Ich selber bin immer noch dabei, das Ganze weiter zu optimieren. Das Problem dabei ist nur, dass man immer Sonnentage braucht, um die Automation und Werte wirklich testen und prüfen zu können.

Wenn du noch weitere Fragen hast, kannst du dich gerne mal an mich wenden.

Viele Grüße

Rene

Interessantes Projekt - Danke

Es scheint übrigens so, als ob Bosch und Buderus in der Steuerung sehr, sehr ähnlich sind, so dass sich jeweils auch immer eine Suche nach Tips für den jeweils anderen Hersteller lohnt (auch hier im Forum).

Es hängt natürlich immer auch von den individuellen Gegebenheiten ab, aber bei unserer 9,4 kWp Ost/West-Anlage kommt in Okt-Feb so wenig, dass der Speicher eigentlich immer alles aufnehmen kann und nie voll wird. Da macht das PV-regeln der WP relativ wenig Sinn - wäre eher ein Thema ohne Speicher.

Interessant finde ich, dass in dem Projekt auch über die Raumtemparatur geregelt wird. Die habe ich bei mir auch benutzt, um der WP das zu häufige abschalten und Neuanlaufen abzugewöhnen.

1 „Gefällt mir“

Ich habe noch einmal das komplette Package überarbeitet, da, wie ich herausgefunden habe, das heraufsetzen der Soll-Temperatur nicht der optimale und effektivste Weg ist.

Vielmehr macht es Sinn, die Vorlauftemperatur zu beeinflussen und die Wassertemperatur vom Boiler.

Wichtig sind hierbei die neuen Input-Parameter, die ich für die Steuerung verwende. Die Parameter steuern das Verhalten des Energiemanagers bezüglich Vorlauftemperaturregelung und DHW-Ladung:

1. energy_manager_temp_start (°C)

Beschreibung:
Temperatur-Schwelle (z.B. Lufttemperatur am Wärmepumpen-Lufteinlass), unterhalb der der Energiemanager aktiv wird bzw. die Steuerung erlaubt. Wird z.B. genutzt, um bei zu kalter Umgebung die Steuerung zu pausieren (z.B. um Schäden oder ineffizienten Betrieb zu vermeiden).
Einstellung:

  • Höher setzen, wenn du möchtest, dass der Manager nur bei milderen Temperaturen aktiv ist.

  • Niedriger setzen, wenn du auch bei kälteren Bedingungen managen willst (Vorsicht Komfort/Schutz).

2. energy_manager_temp_stop (°C)

Beschreibung:
Temperatur-Schwelle, oberhalb der der Energiemanager die Steuerung deaktiviert (z.B. weil es warm genug ist und keine Heizleistung nötig).
Einstellung:

  • Höher setzen, wenn du früher abschalten willst.

  • Niedriger setzen, wenn du länger managen willst.

3. em_flow_temp_min (°C)

Beschreibung:
Minimal zulässige Vorlauftemperatur, die der Energiemanager setzen darf (untere Grenze für die Regelung).
Einstellung:

  • So niedrig wie möglich für maximale Effizienz, aber komfortabel.

  • Nicht zu niedrig, damit Heizkörper/Durchfluss nicht zu kalt werden.

4. em_flow_temp_max (°C)

Beschreibung:
Maximal zulässige Vorlauftemperatur, die der Energiemanager setzen darf (obere Grenze).
Einstellung:

  • Höher setzen, wenn bei sehr kalten Tagen mehr Leistung nötig ist.

  • Nicht zu hoch, um Effizienzverlust zu vermeiden.

5. em_flow_temp_step_k (°C)

Beschreibung:
Maximale Änderung der Vorlauftemperatur pro Regelintervall (z.B. Minute), zur Vermeidung von abrupten Sprüngen und Kurzzyklen.
Einstellung:

  • Kleinere Werte = sanftere Regelung, weniger Verschleiß, evtl. längere Reaktionszeit.

  • Größere Werte = schnellere Anpassung, evtl. mehr Kurzzyklen.

6. em_min_runtime (Minuten)

Beschreibung:
Mindestlaufzeit des Kompressors nach Start, um Kurzzyklen zu vermeiden. Während dieser Laufzeit darf die Vorlauftemperatur nicht abgesenkt werden.
Einstellung:

  • Höher setzen für mehr Schutz und längere Laufzeiten.

  • Niedriger setzen, wenn schnelle Reaktion wichtiger ist.

7. em_pv_threshold_start (kW)

Beschreibung:
PV-Leistungsüberschuss-Schwelle, ab der die Wärmepumpe bzw. DHW-Ladung gestartet wird.
Einstellung:

  • Höher setzen, um nur bei signifikantem Überschuss zu starten.

  • Niedriger setzen, um auch kleine Überschüsse zu nutzen.

8. em_pv_threshold_stop (kW)

Beschreibung:
PV-Leistungsüberschuss-Schwelle, unter der die Wärmepumpe bzw. DHW-Ladung gestoppt wird.
Einstellung:

  • Abstand zum Startwert sorgt für Stabilität (Hysterese).

  • Zu nah an Startwert kann zu häufigem An/Aus führen.

9. em_dhw_max_temp (°C)

Beschreibung:
Maximal erlaubte Warmwassertemperatur beim Laden des Boilers, um Komfort und Legionellenschutz zu gewährleisten.
Einstellung:

  • Nicht zu niedrig, da sonst Warmwasser nicht ausreichend heiß.

  • Höher für Legionellenschutz, aber Energieverbrauch steigt.

10. em_dhw_min_temp (°C)

Beschreibung:
Mindesttemperatur im Boiler, unter der der Aux-Heater als Notfall zugelassen wird (Fallback).
Einstellung:

  • Höher setzen, wenn du Komfort priorisierst.

  • Niedriger setzen, wenn Aux-Heater möglichst selten laufen soll.

11. em_dhw_charge_min_duration (Minuten)

Beschreibung:
Minimale Dauer einer DHW-Ladung, um häufiges Start/Stop zu vermeiden.
Einstellung:

  • Höher setzen für längere Ladezyklen, weniger Verschleiß.

  • Niedriger setzen für schnellere Reaktion auf Bedarf.

Folgende zusätzliche Regeln/Schutzmaßnahmen habe ich aufgenommen:

  • Mindestlaufzeit / Mindestruhezeit für Kompressor: Verhindere Kurzzyklen (z. B. mind. 10–20 min Laufzeit).

  • Begrenze Änderungsgeschwindigkeit der Vorlauftemperatur (Rampen), z. B. max X K pro Stunde.

  • Aux‑Heater unterdrücken oder nur nach definierten Bedingungen erlauben (z. B. Dauerbetrieb bei sehr tiefen Außentemp. + hohe DHW-Anforderung).

  • Max/Min‑Temperaturgrenzen beachten (dhw Comfort stop temp, Single charge temp, Heat limit).

  • Priorisierungslogik: DHW hat bei Bedarf Priorität, aber wenn PV‑Überschuss vorhanden ist, lade DHW bevorzugt; falls keine PV, nutze Mindesttemperaturen zur Vermeidung von Komfortverlust.

  • Hysteresen und Schwellwerte für PV‑Überschuss: Vermeide getriggerte Hin- und Her‑Schaltungen bei kleinen Fluktuationen (z. B. nur handeln wenn PV > X W über Y Minuten).

  • Berücksichtige Außentemperatur: Bei sehr tiefen Außentemp. kann die WP schlechter wirken — ggf. andere Strategie oder größere Vorsicht beim Vermeiden von Aux.

  • Log & Alarme: Überwache Aux‑Heater‑Energie, Kompressorstarts, Boiler‑Temp, Netzbezug. Alarme bei Abweichungen.

Dann habe ich noch ein Safe Mode + Reset‑Skript mit aufgenommen, um im Fall von irgendwelchen Problemen alles wieder auf die Standardwerte zurückzusetzen.

  • Safe Mode (Input Boolean) pausiert alle Automationen des EM:

    • Vorteil: Keine Änderung an Sollwerten; verhindert weitere Aktionen, während ein Fehler analysiert.

    • Danach kann man mit dem Reset‑Skript schrittweise Werte zurücksetzen.

Daraus ergeben sich folgende neuen Automatisierungen:

  1. EM Temp OK Status aktualisieren
  • Bestimmt, ob die Außentemperatur/Einlasstemperatur für den Energiemanager innerhalb des erlaubten Betriebsbereichs liegt (Temp OK Flag).
  1. EM: Vorlauftemperatur regeln
  • Stufenlose Regelung der Soll-Vorlauftemperatur (number.boiler_selected_flow_temperature) abhängig vom verfügbaren PV‑/Batterie‑Surplus, mit Ramping und Mindestlaufzeit.
  1. EM: DHW Ladung steuern
  • Startet oder stoppt das DHW‑Laden (Einmal‑Schaltung des Boilers) abhängig von PV‑Überschuss und Boiler‑Temperatur, inklusive Mindestladezeit.
  1. EM: Aux-Heater Steuerung
  • Verhindert bzw. erlaubt den Einsatz des Hilfsheizregisters (Aux-Heater) basierend auf dem Helper em_allow_aux, Boiler-Temperatur und DHW‑Ladestatus.
  1. EM: Force smoothed zero on startup
  • Verhindert bei HA‑Start kurzzeitig falsche Auswertungen durch nicht initialisierte Rohsensoren, indem ein Force‑Zero‑Flag gesetzt wird, bis Sensoren valide Werte liefern.

Das neue Package sieht dann wie folgt aus (mit den für meine Gesamtanalge gesetzten Input-Werten):

# config/packages/energy_manager.yaml

# --- Helpers / Controls ---
input_boolean:
  energy_manager_enabled:
    name: "Energy Manager aktiv"
    initial: on
  energy_manager_temp_ok:
    name: "Energy Manager: Temp OK"
    initial: on
  energy_manager_force_zero:
    name: "Energy Manager: Force smoothed zero"
    initial: off
    icon: mdi:power-off
  em_allow_aux:
    name: "EM: Aux-Heater erlauben"
    initial: off
  em_dhw_charging:
    name: "EM DHW Ladung aktiv"
    initial: off
  em_safe_mode:
    name: "EM Safe Mode"
    initial: off
    icon: mdi:shield-alert

input_number:
  pw_max_charge:
    name: "Powerwall max Ladeleistung (kW)"
    initial: 4.6
    min: 0
    max: 11.0
    step: 0.1
    unit_of_measurement: kW

  energy_manager_temp_start:
    name: "EM Temp Start (°C)"
    initial: 14
    min: -40
    max: 40
    step: 0.5

  energy_manager_temp_stop:
    name: "EM Temp Stop (°C)"
    initial: 17
    min: -40
    max: 40
    step: 0.5

  em_flow_temp_min:
    name: "EM Vorlauf Minimum (°C)"
    initial: 35
    min: 20
    max: 45
    step: 0.5

  em_flow_temp_max:
    name: "EM Vorlauf Maximum (°C)"
    initial: 50
    min: 40
    max: 60
    step: 0.5

  em_flow_temp_step_k:
    name: "EM Vorlauf Änderung pro Intervall (°C)"
    initial: 0.5
    min: 0.1
    max: 2
    step: 0.1

  em_min_runtime:
    name: "EM Kompressor Mindestlaufzeit (Minuten)"
    initial: 15
    min: 5
    max: 60
    step: 1

  em_pv_threshold_start:
    name: "EM PV Überschuss Startschwelle (kW)"
    initial: 3
    min: 0
    max: 5
    step: 0.1

  em_pv_threshold_stop:
    name: "EM PV Überschuss Stoppschwelle (kW)"
    initial: 1
    min: 0
    max: 5
    step: 0.1

  em_dhw_max_temp:
    name: "EM DHW Max Temperatur (°C)"
    initial: 55
    min: 45
    max: 70
    step: 0.5

  em_dhw_min_temp:
    name: "EM DHW Min Temperatur (°C)"
    initial: 45
    min: 35
    max: 55
    step: 0.5

  em_dhw_charge_min_duration:
    name: "EM DHW Mindestladezeit (Minuten)"
    initial: 20
    min: 5
    max: 60
    step: 1

# --- Scripts ---
script:
  em_heatpump_force_stop:
    alias: "EM: WP sofort Stop (force)"
    sequence:
      - service: notify.persistent_notification
        data:
          title: "EM: WP Stop (force)"
          message: "Das alte Force-Stop-Skript ist deaktiviert. Verwende Safe Mode und/oder em_reset_to_defaults."
    mode: single

  em_reset_to_defaults:
    alias: "EM: Reset auf Standardwerte"
    sequence:
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean.em_safe_mode
      - delay: "00:00:01"

      # Input Booleans
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean.energy_manager_enabled
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean.energy_manager_temp_ok
      - service: input_boolean.turn_off
        target:
          entity_id: input_boolean.energy_manager_force_zero
      - service: input_boolean.turn_off
        target:
          entity_id: input_boolean.em_allow_aux
      - service: input_boolean.turn_off
        target:
          entity_id: input_boolean.em_dhw_charging

      # Input Numbers zurücksetzen
      - service: input_number.set_value
        data:
          entity_id: input_number.pw_max_charge
          value: 4.6
      - service: input_number.set_value
        data:
          entity_id: input_number.energy_manager_temp_start
          value: 14
      - service: input_number.set_value
        data:
          entity_id: input_number.energy_manager_temp_stop
          value: 17
      - service: input_number.set_value
        data:
          entity_id: input_number.em_flow_temp_min
          value: 35
      - service: input_number.set_value
        data:
          entity_id: input_number.em_flow_temp_max
          value: 50
      - service: input_number.set_value
        data:
          entity_id: input_number.em_flow_temp_step_k
          value: 0.5
      - service: input_number.set_value
        data:
          entity_id: input_number.em_min_runtime
          value: 15
      - service: input_number.set_value
        data:
          entity_id: input_number.em_pv_threshold_start
          value: 3
      - service: input_number.set_value
        data:
          entity_id: input_number.em_pv_threshold_stop
          value: 1
      - service: input_number.set_value
        data:
          entity_id: input_number.em_dhw_max_temp
          value: 55
      - service: input_number.set_value
        data:
          entity_id: input_number.em_dhw_min_temp
          value: 45
      - service: input_number.set_value
        data:
          entity_id: input_number.em_dhw_charge_min_duration
          value: 20

      # Setze die Soll-Vorlauftemperatur auf ein sicheres Minimum (em_flow_temp_min)
      - service: number.set_value
        data:
          entity_id: number.boiler_selected_flow_temperature
          value: "{{ states('input_number.em_flow_temp_min') | float(35) }}"

      # Schalte WP/DHW-Schalter in sicheren Zustand
      - service: switch.turn_off
        target:
          entity_id:
            - switch.boiler_dhw_one_time_charging
            - switch.boiler_aux_heater_only

      - delay: "00:00:01"
      - service: notify.persistent_notification
        data:
          title: "EM: Reset auf Standardwerte"
          message: "Alle EM-Helper wurden auf Default gesetzt und Safe Mode aktiviert. Prüfe Logs und beobachte Sensoren."
    mode: single

# --- Filter Sensoren (Glättung) ---
sensor:
  - platform: filter
    name: "em_pv_power_smoothed"
    entity_id: sensor.my_home_solar_energie
    filters:
      - filter: lowpass
        time_constant: 2
        precision: 2

  - platform: filter
    name: "em_home_load_smoothed"
    entity_id: sensor.my_home_last_leistung
    filters:
      - filter: time_simple_moving_average
        window_size: 3
        precision: 2

  - platform: filter
    name: "em_powerwall_battery_power_smoothed"
    entity_id: sensor.my_home_batterie_leistung
    filters:
      - filter: lowpass
        time_constant: 6
        precision: 2

# --- Template Sensors (Kernlogik & korrigierte Werte) ---
template:
  - sensor:
      - name: "em_pv_power_corrected"
        unit_of_measurement: "kW"
        state: >
          {% set force = is_state('input_boolean.energy_manager_force_zero', 'on') %}
          {% set raw = states('sensor.my_home_solar_energie') | float(0) %}
          {% set sm = states('sensor.em_pv_power_smoothed') | float(0) %}
          {% if force or raw < 0.02 %}
            0
          {% else %}
            {{ sm | round(2) }}
          {% endif %}

      - name: "em_home_load_corrected"
        unit_of_measurement: "kW"
        state: >
          {% set force = is_state('input_boolean.energy_manager_force_zero', 'on') %}
          {% set raw = states('sensor.my_home_last_leistung') | float(0) %}
          {% set sm = states('sensor.em_home_load_smoothed') | float(0) %}
          {% if force or raw < 0.02 %}
            0
          {% else %}
            {{ sm | round(2) }}
          {% endif %}

      - name: "em_powerwall_charge_corrected"
        unit_of_measurement: "kW"
        state: >
          {% set force = is_state('input_boolean.energy_manager_force_zero', 'on') %}
          {% set raw = states('sensor.my_home_batterie_leistung') | float(0) %}
          {% set sm = states('sensor.em_powerwall_battery_power_smoothed') | float(0) %}
          {% if force or (raw | abs) < 0.02 %}
            0
          {% else %}
            {{ sm | round(2) }}
          {% endif %}

      - name: "em_energy_surplus"
        unit_of_measurement: "kW"
        state: >
          {{ (states('sensor.em_pv_power_corrected') | float(0) - states('sensor.em_home_load_corrected') | float(0)) | round(2) }}

      - name: "em_pw_max_charge"
        unit_of_measurement: "kW"
        state: >
          {{ states('input_number.pw_max_charge') | float(4.6) }}

      - name: "em_pw_current_charge"
        unit_of_measurement: "kW"
        state: >
          {{ (states('sensor.em_powerwall_charge_corrected') | float(0)) | abs | round(2) }}

      - name: "em_available_for_heatpump"
        unit_of_measurement: "kW"
        state: >
          {% set surplus = states('sensor.em_energy_surplus') | float(0) %}
          {% set pw_curr = states('sensor.em_pw_current_charge') | float(0) %}
          {% set threshold = 0.02 %}
          {% if surplus > 0 %}
            {% set used = pw_curr if pw_curr > threshold else 0 %}
            {{ [surplus - used, 0] | max | round(2) }}
          {% else %}
            0
          {% endif %}
        attributes:
          note: "Surplus minus current battery charge (threshold 0.02 kW)"

      - name: "em_target_flow_temp"
        unit_of_measurement: "°C"
        state: >
          {% set min_t = states('input_number.em_flow_temp_min') | float %}
          {% set max_t = states('input_number.em_flow_temp_max') | float %}
          {% set avail = states('sensor.em_available_for_heatpump') | float %}
          {% set max_power = 6 %}  # Max WP Leistung in kW, anpassen falls bekannt
          {% set ratio = (avail / max_power) | max(0) | min(1) %}
          {% set target = min_t + (max_t - min_t) * ratio %}
          {{ target | round(1) }}

      - name: "em_current_flow_temp"
        unit_of_measurement: "°C"
        state: "{{ states('sensor.boiler_current_flow_temperature') | float(0) }}"

      - name: "em_dhw_boiler_temp"
        unit_of_measurement: "°C"
        state: "{{ states('sensor.boiler_heat_carrier_forward_tc1') | float(0) }}"

      - name: "em_dhw_charge_state"
        state: >
          {{ states('input_boolean.em_dhw_charging') if states('input_boolean.em_dhw_charging') else 'off' }}

# --- Automationen (alle in einem Block) ---
automation:
  - alias: "EM Temp OK Status aktualisieren"
    description: "Setzt input_boolean.energy_manager_temp_ok basierend auf Temperatur mit Debounce 60s"
    mode: single
    trigger:
      - platform: state
        entity_id: sensor.boiler_air_inlet_temperature_tl2
    condition: []
    action:
      - choose:
          - conditions:
              - condition: template
                value_template: >
                  {{ states('sensor.boiler_air_inlet_temperature_tl2') | float < states('input_number.energy_manager_temp_start') | float }}
            sequence:
              - delay: "00:01:00"
              - condition: template
                value_template: >
                  {{ states('sensor.boiler_air_inlet_temperature_tl2') | float < states('input_number.energy_manager_temp_start') | float }}
              - service: input_boolean.turn_on
                target:
                  entity_id: input_boolean.energy_manager_temp_ok
          - conditions:
              - condition: template
                value_template: >
                  {{ states('sensor.boiler_air_inlet_temperature_tl2') | float > states('input_number.energy_manager_temp_stop') | float }}
            sequence:
              - delay: "00:01:00"
              - condition: template
                value_template: >
                  {{ states('sensor.boiler_air_inlet_temperature_tl2') | float > states('input_number.energy_manager_temp_stop') | float }}
              - service: input_boolean.turn_off
                target:
                  entity_id: input_boolean.energy_manager_temp_ok

  - alias: "EM: Vorlauftemperatur regeln"
    description: "Regelt Selected flow temperature stufenlos mit Ramping und Mindestlaufzeit"
    trigger:
      - platform: state
        entity_id:
          - sensor.em_available_for_heatpump
          - sensor.em_current_flow_temp
          - input_boolean.energy_manager_enabled
          - input_boolean.energy_manager_temp_ok
    condition:
      - condition: state
        entity_id: input_boolean.energy_manager_enabled
        state: 'on'
      - condition: state
        entity_id: input_boolean.energy_manager_temp_ok
        state: 'on'
      - condition: state
        entity_id: input_boolean.em_safe_mode
        state: 'off'
    action:
      - variables:
          target_temp_raw: "{{ states('sensor.em_target_flow_temp') | float }}"
          current_temp: "{{ states('sensor.em_current_flow_temp') | float }}"
          step: "{{ states('input_number.em_flow_temp_step_k') | float }}"
          last_change: "{{ state_attr('number.boiler_selected_flow_temperature', 'last_changed') }}"
          min_runtime: "{{ states('input_number.em_min_runtime') | int }}"
          time_since_change: >
            {% if last_change is none %}
              9999
            {% else %}
              ((as_timestamp(now()) - as_timestamp(last_change)) / 60)
            {% endif %}
      - choose:
          - conditions:
              # Mindestlaufzeit beachten: Nur absenken wenn Laufzeit überschritten
              - condition: template
                value_template: >
                  {{ target_temp_raw < current_temp and time_since_change < min_runtime }}
            sequence:
              - service: notify.persistent_notification
                data:
                  title: "EM: Vorlaufregelung"
                  message: "Mindestlaufzeit nicht erreicht, kein Absenken von {{ current_temp }}°C auf {{ target_temp_raw }}°C"

          - conditions:
              # Ramping begrenzen (erhöhen)
              - condition: template
                value_template: >
                  {{ (target_temp_raw - current_temp) > step }}
            sequence:
              - service: number.set_value
                data:
                  entity_id: number.boiler_selected_flow_temperature
                  value: "{{ (current_temp + step) | round(1) }}"
              - service: notify.persistent_notification
                data:
                  title: "EM: Vorlaufregelung"
                  message: "Vorlauftemperatur erhöht von {{ current_temp }}°C auf {{ (current_temp + step) | round(1) }}°C"

          - conditions:
              # Ramping begrenzen (absenken)
              - condition: template
                value_template: >
                  {{ (current_temp - target_temp_raw) > step }}
            sequence:
              - service: number.set_value
                data:
                  entity_id: number.boiler_selected_flow_temperature
                  value: "{{ (current_temp - step) | round(1) }}"
              - service: notify.persistent_notification
                data:
                  title: "EM: Vorlaufregelung"
                  message: "Vorlauftemperatur abgesenkt von {{ current_temp }}°C auf {{ (current_temp - step) | round(1) }}°C"
        default:
          - service: number.set_value
            data:
              entity_id: number.boiler_selected_flow_temperature
              value: "{{ target_temp_raw | round(1) }}"
          - service: notify.persistent_notification
            data:
              title: "EM: Vorlaufregelung"
              message: "Vorlauftemperatur auf Ziel {{ target_temp_raw | round(1) }}°C gesetzt"

  - alias: "EM: DHW Ladung steuern"
    description: "Steuert DHW Charging basierend auf PV Überschuss und Boiler Temperatur"
    trigger:
      - platform: state
        entity_id:
          - sensor.em_available_for_heatpump
          - sensor.em_dhw_boiler_temp
          - input_boolean.energy_manager_enabled
          - input_boolean.energy_manager_temp_ok
          - input_boolean.em_dhw_charging
    condition:
      - condition: state
        entity_id: input_boolean.energy_manager_enabled
        state: 'on'
      - condition: state
        entity_id: input_boolean.energy_manager_temp_ok
        state: 'on'
      - condition: state
        entity_id: input_boolean.em_safe_mode
        state: 'off'
    action:
      - variables:
          pv_avail: "{{ states('sensor.em_available_for_heatpump') | float }}"
          boiler_temp: "{{ states('sensor.boiler_heat_carrier_forward_tc1') | float }}"
          dhw_charging: "{{ is_state('input_boolean.em_dhw_charging', 'on') }}"
          max_temp: "{{ states('input_number.em_dhw_max_temp') | float }}"
          min_temp: "{{ states('input_number.em_dhw_min_temp') | float }}"
          min_duration: "{{ states('input_number.em_dhw_charge_min_duration') | int }}"
          last_on: "{{ state_attr('input_boolean.em_dhw_charging', 'last_changed') }}"
          time_on_min: >
            {% if last_on is none %}
              9999
            {% else %}
              ((as_timestamp(now()) - as_timestamp(last_on)) / 60)
            {% endif %}
      - choose:
          # Start DHW Charging wenn PV Überschuss und Boiler Temp < max_temp
          - conditions:
              - condition: template
                value_template: >
                  {{ pv_avail > states('input_number.em_pv_threshold_start') | float }}
              - condition: template
                value_template: >
                  {{ boiler_temp < max_temp }}
              - condition: template
                value_template: >
                  {{ not dhw_charging or (dhw_charging and time_on_min > min_duration) }}
            sequence:
              - service: input_boolean.turn_on
                target:
                  entity_id: input_boolean.em_dhw_charging
              - service: switch.turn_on
                target:
                  entity_id: switch.boiler_dhw_one_time_charging
              - service: notify.persistent_notification
                data:
                  title: "EM: DHW Ladung"
                  message: "DHW Charging gestartet (Boiler {{ boiler_temp }}°C, PV Überschuss {{ pv_avail }} kW)"

          # Stop DHW Charging wenn Boiler Temp >= max_temp oder PV zu niedrig und Mindestladezeit erfüllt
          - conditions:
              - condition: template
                value_template: >
                  {{ (boiler_temp >= max_temp) or (pv_avail < states('input_number.em_pv_threshold_stop') | float) }}
              - condition: template
                value_template: >
                  {{ dhw_charging and time_on_min > min_duration }}
            sequence:
              - service: input_boolean.turn_off
                target:
                  entity_id: input_boolean.em_dhw_charging
              - service: switch.turn_off
                target:
                  entity_id: switch.boiler_dhw_one_time_charging
              - service: notify.persistent_notification
                data:
                  title: "EM: DHW Ladung"
                  message: "DHW Charging gestoppt (Boiler {{ boiler_temp }}°C, PV Überschuss {{ pv_avail }} kW)"

  - alias: "EM: Aux-Heater Steuerung"
    description: "Blockiert Aux-Heater wenn nicht erlaubt oder Boiler Temp ausreichend"
    trigger:
      - platform: state
        entity_id:
          - input_boolean.em_allow_aux
          - sensor.boiler_heat_carrier_forward_tc1
          - input_boolean.em_dhw_charging
    condition:
      - condition: state
        entity_id: input_boolean.em_safe_mode
        state: 'off'
    action:
      - variables:
          allow_aux: "{{ is_state('input_boolean.em_allow_aux', 'on') }}"
          boiler_temp: "{{ states('sensor.boiler_heat_carrier_forward_tc1') | float }}"
          min_temp: "{{ states('input_number.em_dhw_min_temp') | float }}"
          dhw_charging: "{{ is_state('input_boolean.em_dhw_charging', 'on') }}"
      - choose:
          - conditions:
              - condition: template
                value_template: "{{ not allow_aux and boiler_temp > min_temp and dhw_charging }}"
            sequence:
              - service: switch.turn_off
                target:
                  entity_id: switch.boiler_aux_heater_only
              - service: notify.persistent_notification
                data:
                  title: "EM: Aux-Heater"
                  message: "Aux-Heater deaktiviert wegen Energiemanager"

          - conditions:
              - condition: template
                value_template: "{{ allow_aux }}"
            sequence:
              - service: switch.turn_on
                target:
                  entity_id: switch.boiler_aux_heater_only
              - service: notify.persistent_notification
                data:
                  title: "EM: Aux-Heater"
                  message: "Aux-Heater erlaubt durch Energiemanager"

  - alias: "EM: Force smoothed zero on startup"
    description: "Setzt beim HA-Start kurzzeitig das Force-Zero-Flag, bis Rohsensoren initialisiert sind"
    mode: single
    trigger:
      - platform: homeassistant
        event: start
    action:
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean.energy_manager_force_zero
      - wait_for_trigger:
          - platform: template
            value_template: >
              {% set s1 = states('sensor.my_home_solar_energie') %}
              {% set s2 = states('sensor.my_home_last_leistung') %}
              {% set s3 = states('sensor.my_home_batterie_leistung') %}
              {{ [s1, s2, s3] | select('match', '^(?!unknown$|^unavailable$|^$).+') | list | count > 0 }}
        timeout: "00:00:20"
      - delay: "00:00:02"
      - service: homeassistant.update_entity
        target:
          entity_id:
            - sensor.em_pv_power_smoothed
            - sensor.em_home_load_smoothed
            - sensor.em_powerwall_battery_power_smoothed
            - sensor.em_pv_power_corrected
            - sensor.em_home_load_corrected
            - sensor.em_powerwall_charge_corrected
            - sensor.em_energy_surplus
            - sensor.em_available_for_heatpump
            - sensor.em_pw_current_charge
            - sensor.em_pw_max_charge
            - sensor.em_target_flow_temp
            - sensor.em_current_flow_temp
            - sensor.boiler_heat_carrier_forward_tc1
      - delay: "00:00:01"
      - service: input_boolean.turn_off
        target:
          entity_id: input_boolean.energy_manager_force_zero

Das Dashboard für die Überwachung aller Parameter inklusive Button für das aktivieren und deaktivieren Bestimmter Automatisierungen sieht jetzt so aus:

Jetzt beginnt wieder die Testphase :face_with_peeking_eye:

Hallo,

ich bin Anfänger in Sachen Home Assistant und habe mal folgende einfache Frage.

Das o.g. Projekt finde ich sehr spannend aber soweit bin ich noch nicht. PV-Anlage und WP (Bosch Compress 5800i) und Wallbox sind vorhanden. Aber bevor ich anfange zu steuern, möchte ich erst mal nur monitoren, um mir einen Überblick zu verschaffen.

Ich weiss nicht wie und wo ich die aktuelle elektrische Leistungsaufnahme der Inneneinheit (3-phasig) und der Ausseneinheit (2-phasig) abgreifen kann ohne ein weiteres Smartmeter oder externe Stromzähler in die Zuleitungen zu installieren.

Jetzt bin ich auch auf das BBQKees Electronics Gateway gestoßen, das ja eine Fülle von Daten liefert und auch mit der Bosch WP kompatibel ist. Aber liefert dieser riesige Datensatz wirklich meine beiden gewünschten Daten (elektrische Leistungsaufnahme von Innen- und Außeneinheit)??

BBQKees konnte mir keine eindeutige Antwort geben und sämtliche im Netz kursierende Beispiele von Datensätzen geben keinen eindeutigen Hinweis.

Ist denn in deinem Dashboard “WP Gesamt (3,00 kW)” die elektrische Leistungsaufnahme? Dann scheint es ja doch möglich zu sein??

Vielen Dank!

Hier sind einige Screenshots, die Du mit

übersetzen musst …

Wie ich ohne MyEnergyManager den PV-Überschuß nutzen kann, hat sich mir bisher noch nicht erschlossen. Für einen extra Hub nochmal 119,95 (brutto) sehe ich nicht ein.

Leider erschliesst sich aus der Entitätenliste nicht, wie die einzelnen Parameter in Abhängigkeit sind.

Ich suche weiter …

1 „Gefällt mir“

Die Abhängigkeiten sind ganz einfach, wenn man die Bedienungsanleitung zum Steuergerät BC 400 an der WLW 176 liest und die Fronius genauso.

  • PV Eingang auf “an” festlegen.

  • Heizkreistemperatur auf 0° K festlegen

  • und erhöhten Warmwasserbedarf auf “ja”.

  • In der Fronius Lastmanagement Einstellung - Regel festlegen

  • Leistungsüberschuss - Schwellwerte: Einspeisung 2000 W und Bezug 200 W

  • Mindestlaufzeit je Einschaltvorgang an oder aus

  • minimale Einschaltdauer festlegen und …

  • maximale Laufzeit pro Tag

Alle genutzten Entitäten

Steuerung (schreibbar):

Entität Beschreibung
select.thermostat_dhw_operating_mode DHW-Betriebsmodus: off, eco+, eco, comfort, auto
number.boiler_pv_compressor_max_power Max. Kompressorleistung im PV-Betrieb (aktuell 3 kW)

Trigger (gelesen):

Entität Beschreibung
binary_sensor.boiler_input_4_state Fronius schaltet PV-Eingang 4: on/off
sensor.boiler_dhw_current_intern_temperature WW-Temperatur intern (oberer Messpunkt)

Logging (geschrieben):

Entität Beschreibung
input_text.wp_pv_log Protokoll aller PV/WW-Ereignisse

Beobachtung (nur lesen):

Entität Beschreibung
binary_sensor.boiler_dhw_charging WP heizt gerade Warmwasser: on/off
sensor.solarnet_leistung_netzeinspeisung Aktuelle Netzeinspeisung in Watt
sensor.byd_battery_box_premium_hv_ladezustand Batterieladezustand in %
sensor.boiler_dhw_current_extern_temperature WW-Temperatur extern (unterer Messpunkt)
binary_sensor.boiler_input_4_state Fronius PV-Eingang Status

Quellen:

Buderus Bedienungsanleitung BC400 2025/06 - Seite: 15

claude.ai für die Automation

Sollte Interesse an der YAML bestehen bitte PN.

Was die Automation genau macht


Tagsüber – Fronius schaltet ein

Wenn Fronius meldet dass genug PV-Überschuss da ist, schaltet er Eingang 4 der Wärmepumpe auf Ein. Die Automation wartet 2 Minuten zur Bestätigung und setzt dann den Warmwasser-Betriebsmodus auf comfort – die WP heizt das Warmwasser auf 60°C auf. Alles wird ins Log geschrieben.


Tagsüber – Fronius schaltet aus

Wenn der Überschuss wegbricht, schaltet Fronius Eingang 4 auf Aus. Nach 2 Minuten setzt die Automation den Warmwasser-Betriebsmodus auf off – die WP heizt kein Warmwasser mehr. Alles wird ins Log geschrieben.


Abends um 22:00 Uhr

Sicherheits-Reset: Die Automation setzt den Warmwasser-Betriebsmodus auf off – egal was vorher war. Verhindert dass die WP nachts unnötig mit teurem Strom heizt.


Nachts zwischen 04:00 und 05:30 Uhr – alle 15 Minuten

Die Automation prüft die Warmwassertemperatur:

  • Unter 50°C → Betriebsmodus auf eco+ → WP heizt auf 55°C nach → du hast um 07:00 Uhr warmes Wasser zum Duschen

  • Über 50°C → Betriebsmodus auf off → WW ist noch warm genug, kein unnötiger Stromverbrauch


Was die Automation nicht macht

  • Sie steuert nicht die Heizung oder Vorlauftemperatur

  • Sie überwacht nicht die Batterieladung

  • Sie entscheidet nicht wann Fronius schaltet – das macht Fronius alleine

Ich finde das Projekt sehr interessant und versuche es bei mir umzusetzen. Leider klappt es nicht so wie erwartet. Vielleicht haben meine ems Parameter andere Bezeichnungen oder ….. Kannst Du mir das Steuerungs Dashboard etc. zugänglich machen damit ich nochmal schaue wo ich im Code was ändern muß.

Aktuell sind alle Parameter im Zustand “unavailable”.

Auf diese Seite findest Du das dashboard. Du nutzt schon Fronius Gen 24 und Buderus WLW 176?

Oder meinst Du die Automation?

Durch die Liste der ganzen Entitäten muss man sich leider einmal durcharbeiten. Am besten ist es sich die Werte anzusehen die Dir gerade geliefert werden anzusehen und langsam ein Verständnis für alles aufzubauen.

Wenn Du Fragen zu konkreten Entitäten hast, versuche ich Dir gerne weiterzuhelfen.

Das Thema ist wie gesagt nicht einfach, Gib Dir etwas Zeit es zu verstehen und auch um herauszufinden was bei Dir welche Werte sind.

Bei mir läuft das Ganze mittlerweile sehr zuverlässig.

1 „Gefällt mir“

Ich meinte das andere Dashboard: WP Automatisierung mit den Bereichen Betriebsmodus, Status, Vorgaben etc. Ist im Post vom Nov. 2025 abgebildet. Ist das von Dir oder von Reluca? Die Automation ist ja im Gesamtpackage enthalten. Das Dashboard aus dem Link: https://bosch-buderus-wp.github.io/docs/smarthome/ha habe ich schon einbaut. Zeigt auch alle Werte. Ich wundere mich wieso alle Parameter aus dem Package bei mir unavailable sind. Sieht aus als würde das Package gar nicht laufen.

Hast Du @Reluca ˋs YAML ind die configuration eingefügt?

Diesen hier? Bosch Wärmepumpe in Home Assistant integrieren und steuern dieser mit Leistungsüberschuss der PV-Anlage - #10 von Reluca

Leider habe ich da keinen Plan.

Ja, und da fehlt mir auch der Durchblick bzw. das Dashboard das vielleicht etwas dazu beiträgt.

Irgendwie schreiben wir aneinander vorbei. Die Sensoren im Dashboard müssen doch erst erstellt werden. Sind die denn in Deiner Configuration YAML?

Erst dann kannst Du die doch im Dashboard anzeigen.

Ich habe keinen Plan, was YAML betrifft und bin jetzt auch noch ratlos. Tut mir Leid :disappointed_face: