Marstek PV-Speicher & Home Assistant (MQTT)

Wie Sie Ihren Marstek Speicher (B2500-D und andere Modelle) über MQTT mit Home Assistant verbinden, steuern und im Energiedashboard einrichten können.


Voraussetzungen

Stromverbrauch

Sie benötigen natürlich Home Assistant, und Ihr Stromzähler bzw. der Stromverbrauch Ihrer Wohnung sollte bereits ausgelesen und in Home Assistant verfügbar sein.

Einspeisung ins Netz als kWh

Falls Ihr Stromzähler nur den Bezug, aber nicht die Einspeisung ins Netz als Datenpunkt liefert (was selten vorkommt, aber passieren kann), lässt sich dies unter Umständen über den aktuellen Verbrauch (in Watt) berechnen.

MQTT

Da der Speicher über MQTT konfiguriert wird, muss auf Ihrem Home Assistant das Mosquitto Addon laufen.

Marstek-Speicher

Hier ist ein Beispiel für den Speicher, der in diesem Leitfaden behandelt wird. Es wird erwartet, dass weitere Modelle mit dem Addon bzw. der Web-App kompatibel sind.

2025 Updated Balkonkraftwerk mit Speicher B2500, Marstek 2240Wh LiFePO4 Akku

  • 6000 Ladezyklen
  • 1600W Max. PV-Eingang
  • 800W Ausgang
  • Erweiterbar auf 8960Wh
  • IP65 wasserdicht & staubfest

Repos und Quellen

| URL | Beschreibung |
| :—————————————- | :———————————————————————————————————- |
| Community discussion on battery storage | Eine Community-Diskussion zum Thema Batteriespeicher (ersetzt den spezifischen Link zu „simon42“). |
| https://tomquist.github.io/hame-relay/b2500.html | Web-App zur Bluetooth-Konfiguration des Speichers auf MQTT. |
| https://github.com/tomquist/hm2mqtt | Addon für Home Assistant, um das MQTT-Gerät zu erstellen. Benötigt die Bluetooth-Mac Ihres Gerätes (abrufbar über die Marstek-App). |

Bei Fragen zu hm2mqtt schauen Sie bitte in die Dokumentation auf GitHub!

Energiedashboard

Um Ihre Einzel-Geräte zum Energiedashboard hinzuzufügen und deren Verbräuche zu berechnen, können Sie eine PowerCalc-Integration nutzen.

Code

Hier finden Sie alle benötigten Code-Snippets zum Kopieren.

Abschnitte wie z.B. frontend: dürfen nicht doppelt vorkommen.

Das bedeutet also, wenn Sie den unten gezeigten Abschnitt schon haben, müssen Sie diesen nicht noch einmal hinzufügen, sondern nur die Code-Zeilen darunter ggf. ergänzen.

Nach dem Einfügen können Sie eventuell noch die Entitäten-IDs an Ihre eigenen anpassen. Suchen und ersetzen können Sie mit „STRG+F“ (Windows) oder „CMD+F“ (Mac).

Templates

template:
  - sensor:
      - name: "Netzeinspeisung" # <- Nur nötig, um die Entität vom SML-Lesekopf in HA auszuwählen
        state_class: total_increasing
        device_class: energy
        icon: mdi:home-export-outline
        unit_of_measurement: kWh
        state: "{{ states('sensor.hichiirwifi_sgm_c4_4a920l_energy_supply')|float}}"
        availability: "{{ is_number(states('sensor.hichiirwifi_sgm_c4_4a920l_energy_supply')) }}"
      - name: "Netzbezug" # <- Nur nötig, um die Entität vom SML-Lesekopf in HA auszuwählen
        state_class: total_increasing
        device_class: energy
        icon: mdi:home-import-outline
        unit_of_measurement: kWh
        state: "{{ states('sensor.hichiirwifi_sgm_c4_4a920l_energy_total')|float}}"
        availability: "{{ is_number(states('sensor.hichiirwifi_sgm_c4_4a920l_energy_total')) }}"
      - name: "Wohnung Leistungsbedarf gesamt (Watt)" # <- Berechnet den Leistungsbedarf für die Wohnung in Watt, damit wir das in der Automation nutzten können
        unique_id: "WohnungLeistungsbedarfgesamtWatt"
        unit_of_measurement: W
        device_class: energy
        state_class: measurement
        state: "{{ (states('sensor.hichiirwifi_sgm_c4_4a920l_energy_power') | float + states('sensor.hame_energy_hma_1_94706cce02f5_micro_inverter_power') | float ) }}"
sensor:
  - platform: statistics # <- 5 Minuten stimmt zwar nicht mehr (auf 2 geändert), aber so muss ich nicht die ganze Automation nochmal bearbeiten 😅
    name: "Wohnung Leistungsbedarf gesamt Mittelwert 5Min (Watt)" # <- Mittel-Wert
    entity_id: sensor.wohnung_leistungsbedarf_gesamt_watt
    state_characteristic: mean
    max_age:
      minutes: 2
      # Da die Automation schon nach 3 Minuten wieder nachjustiert, muss dieser Wert kleiner sein
    sampling_size: 1200
    percentile: 90
  - platform: statistics # <- 5 Minuten stimmt zwar nicht mehr (auf 2 geändert), aber so muss ich nicht die ganze Automation nochmal bearbeiten 😅
    name: "Wohnung Leistungsbedarf gesamt Min 5Min (Watt)" # <- Min-Wert
    entity_id: sensor.wohnung_leistungsbedarf_gesamt_watt
    state_characteristic: value_min
    max_age:
      minutes: 2
      # Da die Automation schon nach 3 Minuten wieder nachjustiert, muss dieser Wert kleiner sein
    sampling_size: 1200
    percentile: 90

Automation

Hinweis zum Ersetzen: Mindestens den Gerätenamen hame_energy_hma_1_94706cce02f5 werden Sie durch Ihren eigenen ersetzen müssen. Kopieren Sie hierfür am besten den Code in einen Code-Editor und nutzen Sie Suchen & Ersetzen.

Falls Ihre Templates anders heißen, die IDs in diesem Beispiel sind:

  • sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt
  • sensor.wohnung_leistungsbedarf_gesamt_mittelwert_5min_watt
alias: Marstek B2500-D Nulleinspeisung (also so halbwegs)
description: ""
triggers:
  - entity_id:
      - sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt
    trigger: state
    id: Energy
  - trigger: numeric_state
    entity_id:
      - sensor.hame_energy_hma_1_94706cce02f5_battery_percentage
    below: 11
    alias: LowBat
    id: LowBat
conditions:
  - condition: or
    conditions:
      - alias: Energie-Bedingungen
        condition: and
        conditions:
          - condition: trigger
            id:
              - Energy
          - condition: not
            conditions:
              - condition: state
                entity_id: sensor.hame_energy_hma_1_94706cce02f5_battery_capacity
                state: unknown
            alias: Gerät ist nicht "unbekannt"
          - condition: not
            conditions:
              - condition: state
                entity_id: sensor.hame_energy_hma_1_94706cce02f5_battery_capacity
                state: unavailable
            alias: Gerät ist nicht "nicht verfügbar"
          - alias: "Nicht: Max ist bereits gesetzt und es würde mehr benötigt werden"
            condition: not
            conditions:
              - condition: and
                conditions:
                  - alias: 800W gesetzt
                    condition: numeric_state
                    entity_id: >-
                      number.hame_energy_hma_1_94706cce02f5_time_period_1_output_value
                    above: 799
                  - alias: Min-Wert ist um mind. 10% größer
                    condition: template
                    value_template: >-
                      {{(float(states('number.hame_energy_hma_1_94706cce02f5_time_period_1_output_value'))
                      * 1.10 ) <=
                      states('sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt')
                      | float}}
          - alias: >-
              Nicht: Speicherprio ist gesetzt und es würde weniger benötigt
              werden
            condition: not
            conditions:
              - condition: and
                conditions:
                  - condition: state
                    entity_id: select.hame_energy_hma_1_94706cce02f5_charging_mode
                    state: Fully Charge Then Discharge
                  - alias: Min-Wert ist um mind. 5% kleiner
                    condition: template
                    value_template: >-
                      {{
                      float(states('number.hame_energy_hma_1_94706cce02f5_time_period_1_output_value'))
                      >=
                      (states('sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt')
                      | float * 1.04 )}}
          - alias: Ist & Bedarfs-Werte vergleichen (oder)
            condition: or
            conditions:
              - condition: and
                conditions:
                  - alias: >-
                      Nur, wenn nicht innerhalb der letzten 3 Minuten getriggert
                      wurde (hierfür muss der Aktionsblock erreicht worden sein)
                    condition: template
                    value_template: >-
                      {{
                      state_attr("automation.marstek_b2500_d_nulleinspeisung_also_so_halbwegs",
                      "last_triggered") == None or ( as_timestamp(now()) -
                      as_timestamp(state_attr("automation.marstek_b2500_d_nulleinspeisung_also_so_halbwegs",
                      "last_triggered")) |int(0) ) > 180 }}
                  - alias: Min-Wert ist um mind. 10% größer
                    condition: template
                    value_template: >-
                      {{(float(states('number.hame_energy_hma_1_94706cce02f5_time_period_1_output_value'))
                      * 1.10 ) <=
                      states('sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt')
                      | float}}
                alias: >-
                  Mehr Energie wird benötigt & letzter Lauf ist mind. 3 Minuten
                  her
              - alias: >-
                  Weniger Energie wird benötigt & letzter Lauf ist mind. 15
                  Sekunden her
                condition: and
                conditions:
                  - alias: Min-Wert ist um mind. 3% kleiner
                    condition: template
                    value_template: >-
                      {{
                      float(states('number.hame_energy_hma_1_94706cce02f5_time_period_1_output_value'))
                      >=
                      (states('sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt')
                      | float * 1.02 )}}
                  - alias: >-
                      Nur, wenn nicht innerhalb der letzten 15 Sekunden
                      getriggert wurde (hierfür muss der Aktionsblock erreicht
                      worden sein)
                    condition: template
                    value_template: >-
                      {{
                      state_attr("automation.marstek_b2500_d_nulleinspeisung_also_so_halbwegs",
                      "last_triggered") == None or ( as_timestamp(now()) -
                      as_timestamp(state_attr("automation.marstek_b2500_d_nulleinspeisung_also_so_halbwegs",
                      "last_triggered")) |int(0) ) > 15 }}
          - condition: not
            conditions:
              - condition: and
                conditions:
                  - condition: state
                    entity_id: select.hame_energy_hma_1_94706cce02f5_charging_mode
                    state: Fully Charge Then Discharge
                  - condition: numeric_state
                    entity_id: sensor.hame_energy_hma_1_94706cce02f5_battery_percentage
                    below: 15
      - condition: trigger
        id:
          - LowBat
        alias: LowBat
actions:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - LowBat
        sequence:
          - action: select.select_option
            metadata: {}
            data:
              option: Fully Charge Then Discharge
            target:
              entity_id: select.hame_energy_hma_1_94706cce02f5_charging_mode
          - action: number.set_value
            metadata: {}
            data:
              value: "50"
            target:
              entity_id: number.hame_energy_hma_1_94706cce02f5_time_period_1_output_value
          - action: switch.turn_off
            metadata: {}
            data: {}
            target:
              entity_id: switch.hame_energy_hma_1_94706cce02f5_time_period_1_enabled
          - stop: Akku erschöpft
        alias: Wenn LowBat dann Energiemodus umstellen
      - conditions:
          - condition: numeric_state
            entity_id: sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt
            above: 29
            value_template: "    {{( (float(states('sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt')) * 2) + float(states('sensor.wohnung_leistungsbedarf_gesamt_mittelwert_5min_watt'))) / 3}}"
            enabled: true
          - condition: numeric_state
            entity_id: sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt
            value_template: "    {{( (float(states('sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt')) * 2) + float(states('sensor.wohnung_leistungsbedarf_gesamt_mittelwert_5min_watt'))) / 3}}"
            below: 801
        sequence:
          - alias: >-
              Vermittelten Wert aus Min (doppelt gewichtet) & Durchschnitt
              einstellen
            metadata: {}
            data:
              value: >-
                {{(
                (float(states('sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt'))
                * 2) +
                float(states('sensor.wohnung_leistungsbedarf_gesamt_mittelwert_5min_watt'))
                ) / 3}}
            action: number.set_value
            target:
              entity_id: number.hame_energy_hma_1_94706cce02f5_time_period_1_output_value
          - if:
              - condition: or
                conditions:
                  - condition: state
                    entity_id: >-
                      switch.hame_energy_hma_1_94706cce02f5_time_period_1_enabled
                    state: "off"
                  - condition: state
                    entity_id: select.hame_energy_hma_1_94706cce02f5_charging_mode
                    state: Fully Charge Then Discharge
            then:
              - action: switch.turn_on
                metadata: {}
                data: {}
                target:
                  entity_id: switch.hame_energy_hma_1_94706cce02f5_time_period_1_enabled
              - action: select.select_option
                metadata: {}
                data:
                  option: Simultaneous Charging/Discharging
                target:
                  entity_id: select.hame_energy_hma_1_94706cce02f5_charging_mode
            alias: Wenn Deaktiviert, wieder aktivieren
      - conditions:
          - condition: numeric_state
            entity_id: sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt
            value_template: "    {{( (float(states('sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt')) * 2) + float(states('sensor.wohnung_leistungsbedarf_gesamt_mittelwert_5min_watt'))) / 3}}"
            below: 30
          - condition: not
            conditions:
              - condition: state
                entity_id: select.hame_energy_hma_1_94706cce02f5_charging_mode
                state: Fully Charge Then Discharge
        sequence:
          - alias: >-
              Vermittelten Wert aus Min (doppelt gewichtet) & Durchschnitt
              einstellen
            metadata: {}
            data:
              value: "30"
            action: number.set_value
            target:
              entity_id: number.hame_energy_hma_1_94706cce02f5_time_period_1_output_value
        alias: Set Min Watt if not Set
      - conditions:
          - condition: numeric_state
            entity_id: sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt
            value_template: "    {{( (float(states('sensor.wohnung_leistungsbedarf_gesamt_min_5min_watt')) * 2) + float(states('sensor.wohnung_leistungsbedarf_gesamt_mittelwert_5min_watt'))) / 3}}"
            above: 800
          - condition: not
            conditions:
              - condition: numeric_state
                entity_id: >-
                  number.hame_energy_hma_1_94706cce02f5_time_period_1_output_value
                above: 799
        sequence:
          - metadata: {}
            data:
              value: "800"
            action: number.set_value
            target:
              entity_id: number.hame_energy_hma_1_94706cce02f5_time_period_1_output_value
          - if:
              - condition: or
                conditions:
                  - condition: state
                    entity_id: >-
                      switch.hame_energy_hma_1_94706cce02f5_time_period_1_enabled
                    state: "off"
                  - condition: state
                    entity_id: select.hame_energy_hma_1_94706cce02f5_charging_mode
                    state: Fully Charge Then Discharge
            then:
              - action: switch.turn_on
                metadata: {}
                data: {}
                target:
                  entity_id: switch.hame_energy_hma_1_94706cce02f5_time_period_1_enabled
              - action: select.select_option
                metadata: {}
                data:
                  option: Simultaneous Charging/Discharging
                target:
                  entity_id: select.hame_energy_hma_1_94706cce02f5_charging_mode
            alias: Wenn Deaktiviert, wieder aktivieren
        alias: Set Max Watt if not Set
  - alias: Graveyard
    choose: []
    enabled: true
mode: single

Screenshot der Automation

Ein Screenshot der Automation war im Originalbeitrag enthalten und kann zur Visualisierung der komplexen Struktur dienen.

Fazit: Ihr Marstek Speicher im Home Assistant-Ökosystem – mehr als nur Energie managen!

Wir haben gesehen, wie Sie Ihren Marstek Speicher – sei es ein B2500-D oder ein kompatibles Modell – dank der Power von MQTT nahtlos in Ihr Home Assistant integrieren können. Von der initialen Konfiguration über die detaillierte Steuerung bis hin zur eleganten Darstellung im Energiedashboard ist jetzt alles in Ihrer Hand.

Die Verbindung über MQTT und die Nutzung des hm2mqtt-Addons eröffnen Ihnen nicht nur die Möglichkeit, den Ladestatus und die Leistung Ihres Speichers zu überwachen, sondern auch komplexe Automatisierungen zu erstellen. Das Beispiel der Nulleinspeisungs-Automation zeigt eindrucksvoll, wie Sie mit Home Assistant nicht nur Daten auslesen, sondern aktiv und intelligent auf den Energiebedarf Ihres Zuhauses reagieren können, um den Eigenverbrauch zu maximieren und den Bezug aus dem Netz zu minimieren.

Es mag am Anfang nach viel Code und Konfiguration aussehen, aber die Investition lohnt sich: Sie gewinnen nicht nur volle Kontrolle über Ihren Batteriespeicher, sondern optimieren auch Ihre Energieflüsse im Smart Home. Die Kombination aus Marstek und Home Assistant ist ein echter Gewinn für jeden, der seine Energiedaten transparent sehen und aktiv beeinflussen möchte.

Experimentieren Sie mit den Vorlagen und passen Sie sie an Ihre individuellen Bedürfnisse an. Ihr Smart Home wird es Ihnen danken!

Leave a comment