Kostal PIKO MP Plus in Home Assistant integrieren

Neben einem Kostal Plenticore Wechselrichter, haben wir zusätzlich auch noch den PIKO MP Plus aus selben Hause. Für den Kostal Plenticore gibt es für Home Assistant (HASS) bereits eine Integration. Für den PIKO MP Plus ist diese nicht vorhanden, nach meinem Kenntnisstand auch nicht über z.B. HACS. Hinzukommt, dass der PIKO MP Plus kein Modbus via TCP unterstützt. Lediglich Modbus via RS485 wird angeboten. Dieser ist mit dem Kostal Smart Energy Meter (KSEM) verbunden. Dort wird auch richtig gezählt und dargestellt. Um den Kostal PIKO MP Plus in Home Assistant zu integrieren, müssen wir also auf andere Möglichkeiten ausweichen. Aus dem KSEM hole ich mir via Modbus die Einspeiseleistung und den Netzbezug. Leider finde ich in der Dokumentation keine Möglichkeit mir weitere Werte – die ja definitiv vorhanden sind, weil ich sie in der Oberfläche sehe – herauszuholen, die für mich von Nutzen sind. Die korrekten Werte werden bislang auch leider nicht dem Plenticore zurückgespielt, sodass die Anzeige dort ebenfalls nicht korrekt ist. Damit habe ich folgendes Dillema: Ich sehe in Home Assistant nicht die gesamte PV Erzeugung (W) und den Ertrag (kWh). Auch der Hausverbrauch im Plenticore ist nicht korrekt, denn der PIKO MP Plus senkt diesen oder lässt das Haus sogar einspeisen, wenn der PIKO mehr produziert als verbraucht wird.

Details zum Aufbau

Folgende Komponenten werden verwendet:

  • Kostal Smart Energy Meter
  • Kostal Plenticore Plus 8.5 (2x PV + 1x Akku)
  • Kostal PIKO MP Plus 2.0-1 (1x PV)
  • BYD HVS Premium 10.2

Jede PV Einheit spiegelt eine Dachseite wieder. Wir haben ein Satteldach (2 Flächen 30° SO/NW) und ein Flachdach (SW). Zusätzlich ist ein Akku angebunden. aus dem Grund benötigen wir einen weiteren Wechselrichter. Wie eingangs erwähnt bietet der PIKO leider kein Modbus TCP. Allerdings stellt er per HTTP ein paar wenige XML Dateien bereit. Ein Blick in die Dokumentation ist sehr ernüchternd. Es wird nur eine Hand voll Werten ausgegeben. DC IN finde ich z.B. leider nicht und auch der Ertrag wird nur als Gesamtertrag ermittelt bzw. ausgegeben.

Die zur Verfügung stehenden Werte kann man sich allerdings zu nutze machen, um aggregierte & korrigierte Werte zu bekommen. Dazu sind mehrere Schritte notwendig:

  • XML Parsen und Werte auslesen
  • Sensoren anlegen, um ggf. umzurechnen, zusammenzurechnen und zu runden
  • Eingabewerte definieren für das Herunterbrechen des gesamten Ertrags in Tag, Woche, Monat und Jahr
  • Automatisierung anlegen, um die definierten Eingabewerte zu setzen

XML Parsen, Werte auslesen & erste Sensoren anlegen

In diesem Kapitel holen wir uns erstmal nützliche Werte aus dem PIKO MP Plus. Dies geschieht wie auch bei den folgenden Schritten meist in der configurations.yaml. Für die Verarbeitung bediene ich mich der Erweiterung HA-Multiscrape, welche über Github manuell oder via HACS in HASS hinzugefügt werden kann. Nach der Integration hole ich mir die Werte wie folgt:

multiscrape:
  - resource: http://<deine-piko-ip>/all.xml
    scan_interval: 15 # Kann auch grobmaschiger abgefragt werden z.B. 60s
    parser: lxml
    sensor:
      - unique_id: kostal_piko_ac_power
        name: "AC Power"
        select: "measurement[type='AC_Power']"
        attribute: "value"
        unit_of_measurement: "W"
        on_error:
          value: "default"
          default: 0.0
       - unique_id: kostal_piko_yield_total
        name: "yield"
        select: "yieldvalue"
        attribute: "value"
        unit_of_measurement: "Wh"
        state_class: total_increasing
        device_class: energy

Damit habe ich den AC Output und den Gesamtertrag. Es gibt wenige weitere Werte die ihr oben im Link in der Dokumentation findet. Für den Gesamtertrag habe ich auf den Defaultwert verzichtet, da es zwischendurch vorkam, dass der Wert für einen Intervall auf 0 gesprungen ist. Damit werden Zähler durcheinander gebracht und der Tagesertrag fälschlicherweise um den Gesamtertrag an dem Tag erhöht, da er anschließend wieder auf die korrekte Zahl springt. Daher kann man bei einem Fehlintervall den alten Stand besser beibehalten.

template:
  - sensor:
# Umrechnen Piko Total Yield in kWh
      - name: kostal_piko_yield_total_kwh 
        state: "{{ (states('sensor.kostal_piko_yield_total') | float(0) / 1000) | round(1)}}"
        unique_id: 990a5435-50fe-4442-a689-a03702755f2e
        unit_of_measurement: "kWh"
        device_class: energy
        state_class: total_increasing

# Ausgangsstrom beider Wechselrichter (PV)
      - name: kostal_all_ac_power 
        state: "{{ (states('sensor.kostal_piko_ac_power') | float(0) + states('sensor.scb_dc1_power') | float(0) + states('sensor.scb_dc2_power') | float(0)) | round(0) }}"
        unique_id: b717f61b-6166-4dfb-b311-62e841cb921a
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power

# Hausverbrauch korrigiert mit Produktion aus Piko, da sie den Hausverbrauch senkt oder aus dem Haus einspeist
      - name: kostal_all_home_power 
        state: "{{ (states('sensor.kostal_piko_ac_power') | float(0) + states('sensor.scb_home_power') | float(0)) | round(0) }}"
        unique_id: d33a380c-3c18-11ee-be56-0242ac120002
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power

# Hausverbrauch aus PV korrigiert mit Produktion aus Piko, da sie den Hausverbrauch senkt oder aus dem Haus einspeist
      - name: kostal_all_home_power_from_pv 
        state: "{{ (states('sensor.kostal_piko_ac_power') | float(0) + states('sensor.scb_home_power_from_pv') | float(0)) | round(0) }}"
        unique_id: 19a5c0a6-3c1c-11ee-be56-0242ac120002
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power

Die Definition von state_class und device_class ist entscheidend, wenn HASS wissen soll, um was für Werte es sich handelt und diese z.B. für das Energie-Dashboard verwertet werden sollen. Ansonsten tauchen sie dort nicht auf. Die unique_id lege ich fest, damit ich die Sensoren in der UI bearbeiten kann. Dazu bediene ich mich eines einfachen UUID-Generators. Damit haben wir den Kostal PIKO MP in Home Assistant erstmal integriert, soweit es geht.

Ertrag in Tag, Monat & Jahr herunterbrechen

Wir beginnen wieder mit der configuration.yaml und legen dort unsere notwendigen Eingabewerte und weitere Sensoren an.

input_number:
  piko_yield_day_start:
    name: Piko Yield Day Start
    min: 0
    max: 999999999
  piko_yield_week_start:
    name: Piko Yield Day Start
    min: 0
    max: 999999999
  piko_yield_month_start:
    name: Piko Yield Day Start
    min: 0
    max: 999999999
  piko_yield_year_start:
    name: Piko Yield Day Start
    min: 0
    max: 999999999

Mithilfe dieser Eingabewerte schreiben wir uns mittels Automatisierung für den Tag jeweils um 0:00 Uhr den aktuellen Gesamtertragwert weg. Das Gleiche machen wir zum Wochenanfang, Monatsanfang und Jahresanfang. In der automation.yaml schreiben wir daher folgendes:

- id: '1692106964290'
  alias: Messpunkt Piko Daily
  description: Startmesspunkt für Piko Yield
  trigger:
    platform: time
    at: 00:00:00
  condition: []
  action:
    service: input_number.set_value
    data_template:
      entity_id: input_number.piko_yield_day_start
      value: '{{ states.sensor.kostal_piko_yield_total_kwh.state }}'
  mode: single
- id: '1692184368163'
  alias: Messpunkt Piko Monthly
  description: Startmesspunkt für Piko Yield
  trigger:
  - platform: time
    at: 00:00:00
  condition:
  - condition: template
    value_template: '{{ now().day == 1 }}'
  action:
  - service: input_number.set_value
    data_template:
      entity_id: input_number.piko_yield_month_start
      value: '{{ states.sensor.kostal_piko_yield_total_kwh.state }}'
  mode: single
- id: '1692184498185'
  alias: Messpunkt Piko Yearly
  description: Startmesspunkt für Piko Yield
  trigger:
  - platform: time
    at: 00:00:00
  condition:
  - condition: template
    value_template: '{{ now().timetuple().tm_yday == 1 }}'
  action:
  - service: input_number.set_value
    data_template:
      entity_id: input_number.piko_yield_year_start
      value: '{{ states.sensor.kostal_piko_yield_total_kwh.state }}'
  mode: single
- id: '1692184755593'
  alias: Messpunkt Piko Weekly
  description: Startmesspunkt für Piko Yield
  trigger:
  - platform: time
    at: 00:00:00
  condition:
  - condition: time
    weekday:
    - mon
  action:
  - service: input_number.set_value
    data_template:
      entity_id: input_number.piko_yield_week_start
      value: '{{ states.sensor.kostal_piko_yield_total_kwh.state }}'
  mode: single

Zum Start führen wir die Automatisierungen alle einmalig manuell aus, damit sie einen Startwert haben. Als nächstes legen wir entsprechende Sensoren an, die dann die gewünschten Werte enthalten. Das geschieht in der configuration.yaml im bereits vorhanden Bereich ‚template:‘

template:
# Tageswert Piko Yield
      - name: kostal_piko_yield_day
        state: "{{ (states('sensor.kostal_piko_yield_total_kwh') | float(0) - states('input_number.piko_yield_day_start') | float(0)) | round(1) }}"
        unique_id: 4876b734-3b7a-11ee-be56-0242ac120002
        unit_of_measurement: "kWh"
        state_class: total_increasing
        device_class: energy

# Wochenwert Piko Yield
      - name: kostal_piko_yield_week
        state: "{{ (states('sensor.kostal_piko_yield_total_kwh') | float(0) - states('input_number.piko_yield_week_start') | float(0)) | round(1) }}"
        unique_id: cedf577e-3c22-11ee-be56-0242ac120002
        unit_of_measurement: "kWh"
        state_class: total_increasing
        device_class: energy

# Monatswert Piko Yield
      - name: kostal_piko_yield_month
        state: "{{ (states('sensor.kostal_piko_yield_total_kwh') | float(0) - states('input_number.piko_yield_month_start') | float(0)) | round(1) }}"
        unique_id: d3764f0e-3c22-11ee-be56-0242ac120002
        unit_of_measurement: "kWh"
        state_class: total_increasing
        device_class: energy

# Jahreswert Piko Yield
      - name: kostal_piko_yield_year
        state: "{{ (states('sensor.kostal_piko_yield_total_kwh') | float(0) - states('input_number.piko_yield_year_start') | float(0)) | round(1) }}"
        unique_id: d762fb12-3c22-11ee-be56-0242ac120002
        unit_of_measurement: "kWh"
        state_class: total_increasing
        device_class: energy

# Ausgangsstrom beider Wechselrichter (PV)
      - name: kostal_all_ac_power
        state: "{{ (states('sensor.kostal_piko_ac_power') | float(0) + states('sensor.scb_dc1_power') | float(0) + states('sensor.scb_dc2_power') | float(0)) | round(0) }}"
        unique_id: b717f61b-6166-4dfb-b311-62e841cb921a
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power

# Hausverbrauch korrigiert mit Produktion aus Piko, da sie den Hausverbrauch senkt oder aus dem Haus einspeist
      - name: kostal_all_home_power
        state: "{{ (states('sensor.kostal_piko_ac_power') | float(0) + states('sensor.scb_home_power') | float(0)) | round(0) }}"
        unique_id: d33a380c-3c18-11ee-be56-0242ac120002
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power

# Hausverbrauch aus PV korrigiert mit Produktion aus Piko, da sie den Hausverbrauch senkt oder aus dem Haus einspeist
      - name: kostal_all_home_power_from_pv
        state: "{{ (states('sensor.kostal_piko_ac_power') | float(0) + states('sensor.scb_home_power_from_pv') | float(0)) | round(0) }}"
        unique_id: 19a5c0a6-3c1c-11ee-be56-0242ac120002
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power

# Produktion PV aus beiden Wechselrichtern pro Tag
      - name: kostal_all_yield_day
        state: "{{ (states('sensor.kostal_piko_yield_day') | float(0) + states('sensor.scb_energy_yield_day') | float(0)) | round(1) }}"
        unique_id: 6ddbc474-3c1f-11ee-be56-0242ac120002
        unit_of_measurement: "kWh"
        state_class: total_increasing
        device_class: energy

# Produktion PV aus beiden Wechselrichtern pro Woche
      - name: kostal_all_yield_week
        state: "{{ (states('sensor.kostal_piko_yield_week') | float(0) + states('sensor.scb_energy_yield_week') | float(0)) | round(1) }}"
        unique_id: e1e4bc4c-3c22-11ee-be56-0242ac120002
        unit_of_measurement: "kWh"
        state_class: total_increasing
        device_class: energy

# Produktion PV aus beiden Wechselrichtern pro Woche
      - name: kostal_all_yield_month
        state: "{{ (states('sensor.kostal_piko_yield_month') | float(0) + states('sensor.scb_energy_yield_month') | float(0)) | round(1) }}"
        unique_id: 9f4c9cc8-3c28-11ee-be56-0242ac120002
        unit_of_measurement: "kWh"
        state_class: total_increasing
        device_class: energy

# Produktion PV aus beiden Wechselrichtern pro Woche
      - name: kostal_all_yield_year
        state: "{{ (states('sensor.kostal_piko_yield_year') | float(0) + states('sensor.scb_energy_yield_year') | float(0)) | round(1) }}"
        unique_id: a5c9e2d6-3c28-11ee-be56-0242ac120002
        unit_of_measurement: "kWh"
        state_class: total_increasing
        device_class: energy

# Produktion PV aus beiden Wechselrichtern pro Tag
      - name: kostal_all_yield_total
        state: "{{ (states('sensor.kostal_piko_yield_total_kwh') | float(0) + states('sensor.scb_energy_yield_total') | float(0)) | round(1) }}"
        unique_id: 78a054ba-3c1f-11ee-be56-0242ac120002
        unit_of_measurement: "kWh"
        state_class: total_increasing
        device_class: energy

Gerundet werden die Ertrags Werte dabei auf eine Stelle und die Leistungswerte auf volle Zahlen.

Schreibe einen Kommentar