Fronius und BYD Akku über Modbus steuern
Der Fronius-Wechselrichter kann über die integrierte Modbus-Schnittstelle ausgelesen und gesteuert werden. So kann zum Beispiel das Laden oder Entladen erzwungen werden, oder eine Lade bzw. Entladebegrenzung eingestellt werden. Warum? Um noch mehr aus der Anlage heraus zu holen.
Normalerweise funktioniert die automatische Eigenverbrauchs-Optimierung von Fronius für nahezu alle Alltagssituationen.
Ein Grund, warum ich dennoch in das Ladeverhalten eingreifen wollte, war die Tatsache, dass meine PV-Module zu Spitzenzeiten mehr DC-Leistung liefern könnten, als der Wechselrichter AC-seitig verarbeiten kann. Leider ist der Gen24 DC-seitig aber limitiert. Auch wenn die maximale Panel-Leistung des Gen24 10.0 Plus mit 15kW angegeben ist, kann der Gen24 nur ein klein wenig mehr DC Leistung verarbeiten als AC: bei insgesamt 11kW DC ist trotz Batterieladung Schluss.
Ohne Batterieladung ist bei ca. 10,3 KW DC Schluss.
Als Voraussetzung für das Steuern der PV-Anlage muss Modbus am Wechselrichter aktiviert werden, siehe: Fronius: Daten & Einstellungen übers Netzwerk (Modbus)
Für die Steuerung des Ladeverhaltens habe ich in einem Home-Assistant Lovelance-Dashboard Buttons zusammengestellt für folgende Betriebsmodus:
- Erzwungenes Laden: "Force charging"
- Erzwungenes Entladen: "Force discharge" und
- Ladeleistung auf einen definierten Wert limitieren: "Charge-limit" und "charging_power"
Der Knopf "Reset charging" setzt etwaige Einstellungen wieder auf Standard zurück:
Auf dieser Basis kann die Batterie natürlich auch über eine Automation gesteuert werden, zum Beispiel anhand der PV-Vorhersage für den jeweiligen Tag.
Voraussetzung Modbus-Setup
Für Modbus gibt es zwei verschiedene SunSpec Model Type: "int + SF" und "float":
Alle in diesem Artikel erwähnten Register beziehen sich auf den SunSpec Model Type "int + SF".
Damit sich Home Assistant auf die Modbus-Schnittstelle verbindet, habe ich folgende Zeilen in der configuration.yaml hinzugefügt.
modbus:
- type: tcp
# Put your Gen24 IP address here
host: 192.168.1.137
port: 502
name: gen24
sensors:
- name: reading_battery_settings
slave: 1
count: 24
address: 40345
scan_interval: 5
data_type: custom
structure: ">10H2h4H8h"
z.B ist die Start-Adresse für das Lesen der Batterie 40345 für "int + SF",
bei "float" müsste 40355 als Adresse verwendet werden: "address: 40355". +10 gilt für alle in diesem Artikel erwähnten Register.
Der Sensor "sensor.reading_battery_settings" liest alle relevanten Modbus-Register ein und dient als Basis für die später erwähnten Template-Sensoren:
Aus dem Sensor "reading_battery_settings", können die einzelnen Werte über ein value_template extrahiert werden:
Array Nr. |
Wert |
Einheit |
Beschreibung |
---|---|---|---|
0 |
WChaMax |
W |
Sollwert für maximale Ladung, Die Voreinstellung ist MaxChaRte. |
1 |
WChaGra |
% WChaMax/sec |
Sollwert für die maximale Laderate. Standardwert ist MaxChaRte. |
2 |
WDisChaGra |
% WChaMax/sec |
Sollwert für die maximale Entladungsrate. Standardwert ist MaxDisChaRte. |
3 |
StorCtl_Mod |
bit 0: CHARGE bit 1: DiSCHARGE |
Aktiviert den Kontrollmodus für das Halten/Entladen/Laden des Speichers. Bitfeld-Wert. |
4 |
VAChaMax |
VA |
Sollwert für maximalen Lade-VA. |
5 |
MinRsvPct |
% WChaMax |
Sollwert für die Mindestreserve für die Speicherung in Prozent des nominalen Höchstspeichers. |
6 |
ChaState |
% AhrRtg |
Currently available energy as a percent of the capacity rating. |
7 |
StorAval |
AH |
State of charge (ChaState) minus storage reserve (MinRsvPct) times capacity rating (AhrRtg). |
8 |
InBatV |
V |
Interne Batteriespannung. |
9 |
ChaSt |
1: OFF 2: EMPTY 3: DISCHAGING 4: CHARGING 5: FULL 6: HOLDING 7: TESTING |
Ladestatus des Speichergeräts. Aufzählungswert. |
10 |
OutWRte |
% WChaMax |
Prozentsatz der maximalen Entladungsrate. |
11 |
InWRte |
% WChaMax |
Prozentsatz der maximalen Ladeleistung. |
12 |
InOutWRte_WinTms |
Secs |
Zeitfenster für die Änderung der Lade-/Entladerate. |
13 |
InOutWRte_RvrtTms |
Secs |
Timeout-Zeit für die Lade-/Entladerate. |
14 |
InOutWRte_RmpTms |
Secs |
Rampenzeit für den Übergang vom aktuellen Sollwert zum neuen Sollwert. |
15 |
ChaGriSet |
0: PV (Charging from grid disabled) 1: GRID (Charging from grid enabled) |
Sollwert zum Aktivieren/Deaktivieren des Ladens vom Netz |
16 |
WChaMax_SF |
Skalierungsfaktor für die maximale Aufladung. | |
17 |
WChaDisChaGra_SF |
Skalierungsfaktor für die maximale Lade- und Entladerate. | |
18 |
VAChaMax_SF |
Skalierungsfaktor für den maximalen Lade-VA. | |
19 |
MinRsvPct_SF |
Skalierungsfaktor für den Mindestreservesatz. | |
20 |
ChaState_SF |
Skalierungsfaktor für die verfügbare Energie in Prozent. | |
21 |
StorAval_SF |
Skalierungsfaktor für den Ladezustand. | |
22 |
InBatV_SF |
Skalierungsfaktor für die Batteriespannung. | |
23 |
InOutWRte_SF |
Skalierungsfaktor für die prozentuale Lade-/Entladerate. |
Quelle / Inspiriert von: github.com/bigramonk/byd_charging und forum.iobroker.net/topic/65205/modbus-fronius-gen24
In das Ladeverhalten eingreifen: BYD Charging ändern
Das Ändern der Einstellungen erfolgt über Modbus-Register.
Relevante Modbus-Register für das Steuern des Ladeverhaltens
Für das Steuern des Akkus sind im Wesentlichen diese 4 Register relevant:
Laut Fronius Dokumentation: | Register | Wert | Beschreibung | Home Assistant Template Sensor |
---|---|---|---|---|
StorCTLMod | 40348 |
0 .. keine Begrenzung |
Begrenzungsmodus bit 0: CHARGE bit 1: DiSCHARGE |
Template Sensor Name: BYD.StorCTL_Mod
|
MinRsvPct | 40350 |
Sollwert für die maximale Entladungsrate. Standard ist MaxDisChaRte WChaMax % |
Template Sensor Name: BYD.MinRsvPct
|
|
OutWRte | 40355 | Entladeleistung in % |
Template Sensor Name: BYD.OutWRte
|
|
InWRte | 40356 | Ladeleistung in % |
Template Sensor Name: BYD.InWRte
|
Damit die Register in HA einzeln angezeigt werden können, habe ich für jeden der Register im Menü "Einstellungen", "Helfer" jeweils einen Template-Sensor erstellt: "BYD.StorCTL_Mod", "BYD.MinRsvPct", "BYD.OutWRte", "BYD.InWRte". Der Inhalt für den Template-Sensor kann aus der vorigen Tabelle entnommen werden.
Um mehrere Register in einem Ablauf zu ändern, habe ich Skripte für die einzelnen Aktionen angelegt:
Home Assistant Skripts
Ladeeinstellungen auf Standard setzen
Folgende Register setzten das Ladeverhalten auf die Standardwerte:
Register | Wert | Beschreibung | |
---|---|---|---|
StorCTLMod | 40348 | 0 | keine Begrenzung |
MinRsvPct | 40350 |
500 |
Setzt MinRsvPct auf 5,0 % WChaMax |
OutWRte | 40355 |
10000 |
setzt outwrte auf 100% |
InWRte | 40356 |
10000 |
setzt inwrte auf 100% |
Für das Setzen der Register bietet sich ein Skript an: "Einstellungen", "Automatisierungen & Szenen", "Skripte", "NEUES SKRIPT ERSTELLEN":
Inhalt:
alias: Reset charging
sequence:
- service: modbus.write_register
data:
slave: 1
address: 40348
value: 0
hub: gen24
- service: modbus.write_register
data:
address: 40355
slave: 1
value: 10000
hub: gen24
- service: modbus.write_register
data:
slave: 1
address: 40350
value: 500
hub: gen24
- service: modbus.write_register
data:
address: 40356
slave: 1
value: 10000
hub: gen24
mode: single
icon: mdi:home-battery
SoC (untere Ladegrenze) auf 30% stellen
Um etwas mehr Reservekapazität im Akku zu behalten, können die Standardwerte leicht angepasst werden, indem der Wert für MinRsvPct auf z.B. 3000 für 30% Ladereserve gesetzt wird. Der gesetzte Wert über Modbus konkurriert mit den Einstellungen in der Fronius Weboberfläche: Der höhere Wert gewinnt:
Folgende Register setzten das Ladeverhalten auf die Standardwerte mit 30% Ladereserve (SoC):
Register | Wert | Beschreibung | |
---|---|---|---|
StorCTLMod | 40348 | 0 | keine Begrenzung |
MinRsvPct | 40350 |
3000 |
Setzt MinRsvPct auf 30,0 % WChaMax |
OutWRte | 40355 |
10000 |
setzt outwrte auf 100% |
InWRte | 40356 |
10000 |
setzt inwrte auf 100% |
Für das Setzen der Register kann ein zusätzliches Skript angelegt werden: "Einstellungen", "Automatisierungen & Szenen", "Skripte", "NEUES SKRIPT ERSTELLEN":
Inhalt:
alias: Reset charging 30%
sequence:
- service: modbus.write_register
data:
slave: 1
address: 40348
value: 0
hub: gen24
- service: modbus.write_register
data:
address: 40355
slave: 1
value: 10000
hub: gen24
- service: modbus.write_register
data:
slave: 1
address: 40350
value: 3000
hub: gen24
- service: modbus.write_register
data:
address: 40356
slave: 1
value: 10000
hub: gen24
mode: single
icon: mdi:home-battery
Batterie vom Netz laden
Um die Batterie unabhängig vom aktuellen Stromverbrauch oder der aktuellen PV-Leistung zu laden, können die folgenden 3 Register wie folgt gesetzt werden. Damit die Ladeleistung über das Lovelance-Dashboard geändert werden kann, habe ich vorab einen Input-Helfer erstellt:
Eingebunden im Dashboard kann die Ladeleistung komfortabel in der Oberfläche angepasst werden:
Hier die notwendigen Register-Einstellungen für ein erzwungenes Laden:
Register | Wert | Beschreibung | |
---|---|---|---|
StorCTLMod | 40348 | 2 | 2 = Entladebegrenzung |
MinRsvPct | 40350 | 9900 | Setzt MinRsvPct auf 99,0 % WChaMax |
OutWRte | 40355 | {{ 65536 - (states('input_number.charging_power')|int(0) / states('sensor.wchamax')|int(1) * 10000)|int }} |
alias: Force charging
sequence:
- service: modbus.write_register
data:
slave: 1
address: 40348
value: 2
hub: gen24
- if:
- condition: template
value_template: >-
{{ states('sensor.reading_battery_settings').split(',')[6] |int(0) *
10** states('sensor.reading_battery_settings').split(',')[20]|int(0) <
10 }}
then:
- service: modbus.write_register
data:
address: 40355
slave: 1
value: 55536
hub: gen24
else:
- service: modbus.write_register
data:
address: 40355
slave: 1
hub: gen24
value: >-
{{ 65536 - (states('input_number.charging_power')|int(0) /
states('sensor.reading_battery_settings').split(',')[0]|int(1) *
10000) | int }}
- service: modbus.write_register
data:
slave: 1
address: 40350
value: 9900
hub: gen24
mode: single
icon: mdi:battery-charging
Ladeleistung limitieren
Für das Limitieren der Ladeleistung auf den zuvor erstellten Helfer, können folgende Register über ein weiteres Script gesetzt werden:
Register | Wert | Beschreibung | |
---|---|---|---|
StorCTLMod | 40348 | 1 | 1 = Ladebegrenzung |
InWRte | 40356 |
"{{ states('input_number.charging_power') | int(100) * 100 }}" |
alias: Charge-limit
sequence:
- service: modbus.write_register
data:
address: 40356
slave: 1
hub: gen24
value: " {{ (states('input_number.charging_power')|int(0) / states('sensor.reading_battery_settings').split(',')[0]|int(1) * 10000) | int }}"
- service: modbus.write_register
data:
slave: 1
address: 40348
value: 1
hub: gen24
mode: single
icon: mdi:battery-charging
Batterie mit einer bestimmten Leistung entladen (erzwingen)
Hier die notwendigen Register-Einstellungen für ein erzwungenes Entladen:
Register | Wert | Beschreibung | |
---|---|---|---|
StorCTLMod | 40348 | 3 | 3 = Lade und Endladebegrenzung |
OutWRte | 40355 |
{{ (states('input_number.charging_power')|int(0) / |
|
InWRte | 40356 |
{{ 65536 - (states('input_number.charging_power')|int(0) / |
alias: ForceDischarge
sequence:
- service: modbus.write_register
data:
address: 40356
slave: 1
hub: gen24
value: >-
{{ 65536 - (states('input_number.charging_power')|int(0) /
states('sensor.reading_battery_settings').split(',')[0]|int(1) * 10000)
| int }}
- service: modbus.write_register
data:
address: 40355
slave: 1
value: |-
{{ (states('input_number.charging_power')|int(0) /
states('sensor.reading_battery_settings').split(',')[0]|int(1) * 10000) | int
}}
hub: gen24
- service: modbus.write_register
data:
slave: 1
address: 40348
value: 3
hub: gen24
mode: single
icon: mdi:home-battery
Beispiele
Die folgenden Beispiele stammen aus der Fronius-Dokumentation: 42,0410,2649.pdf und wurden für die Verwendung mit den Register-Nummern ergänzt:
Nur Laden des Energiespeichers erlauben
Dieses Verhalten kann durch Limitierung der maximalen Entladeleistung auf 0% erreicht werden => resultiert in Fenster [-3300 W, 0 W]
Register | Wert | Beschreibung | |
---|---|---|---|
StorCTLMod | 40348 | 2 | schaltet Entladegrenzwert aktiv, Bit-Muster: 10 |
OutWRte | 40355 |
0 |
setze Entladelimit auf 0% von WchaMax |
InWRte | 40356 |
ist in diesem Fall nicht relevant |
Quelle: 42,0410,2649.pdf
Nur Entladen des Energiespeichers erlauben
Dieses Verhalten kann durch Limitierung der maximalen Ladeleistung auf 0% erreicht werden => resultiert in Fenster [0 W, 3300 W]
Register | Wert | Beschreibung | |
---|---|---|---|
StorCTLMod | 40348 | 1 | Bit 1 schaltet Ladegrenzwert aktiv, Bit-Muster: 01 |
OutWRte | 40355 |
ist in diesem Fall nicht relevant |
|
InWRte | 40356 |
0 |
setze Ladelimit auf 0% von WchaMax |
Weder Laden noch Entladen erlauben
Dieses Verhalten kann durch Limitierung der maximalen Ladeleistung auf 0% und Limitierung der maximalen Entladeleistung auf 0% erreicht werden => resultiert in Fenster [0 W, 0 W]
Register | Wert | Beschreibung | |
---|---|---|---|
StorCTLMod | 40348 | 3 | schalte beide Grenzwerte aktiv, Bit-Muster: 11 |
OutWRte | 40355 |
0 |
setze Entladelimit auf 0% von WchaMax |
InWRte | 40356 |
0 |
setze Ladelimit auf 0% von WchaMax |
Quelle: 42,0410,2649.pdf
Laden und Entladen mit maximal 50% der nominalen Leistung
Dieses Verhalten kann durch Limitierung der maximalen Ladeleistung auf 50% und Limitierung der maximalen Entladeleistung auf 50% erreicht werden => resultiert in Fenster [-1650 W, 1650 W]
Register | Wert | Beschreibung | |
---|---|---|---|
StorCTLMod | 40348 | 3 | schalte beide Grenzwerte aktiv, Bit-Muster: 11 |
OutWRte | 40355 |
50 |
setze Entladelimit auf 50% von WchaMax |
InWRte | 40356 |
50 |
setze Ladelimit auf 50% von WchaMax |
Quelle: 42,0410,2649.pdf
Laden im Bereich von 50% bis 75% der nominalen Leistung
Dieses Verhalten kann durch Limitierung der maximalen Ladeleistung auf 75% und Limitierung der maximalen Entladeleistung auf -50% erreicht werden => resultiert in Fenster [1650 W, 2475 W]
Register | Wert | Beschreibung | |
---|---|---|---|
StorCTLMod | 40348 | 3 | schalte beide Grenzwerte aktiv, Bit-Muster: 11 |
OutWRte | 40355 |
-50 |
setze Entladelimit auf -50% von WchaMax |
InWRte | 40356 |
75 |
setze Ladelimit auf 75% von WchaMax |
Der Batteriestatus in Fronius Solar.web wechselt zu „Erzwungene Nachladung“
Quelle: 42,0410,2649.pdf
Entladen mit 50% der nominalen Leistung
Dieses Verhalten kann durch Limitierung der maximalen Ladeleistung auf -50% und Limitierung der maximalen Entladeleistung auf 50% erreicht werden => resultiert in Fenster [-1650 W, -1650 W] 44
Register | Wert | Beschreibung | |
---|---|---|---|
StorCTLMod | 40348 | 3 | schalte beide Grenzwerte aktiv, Bit-Muster: 11 |
OutWRte | 40355 |
50 |
setze Entladelimit auf 50% von WchaMax |
InWRte | 40356 |
-50 |
setze Ladelimit auf -50% von WchaMax |
Quelle: 42,0410,2649.pdf
Laden mit 50% bis 100% der nominalen Leistung
Dieses Verhalten kann durch Limitierung der maximalen Entladeleistung auf -50% erreicht werden => resultiert in Fenster [1650 W, 3300 W]
Register | Wert | Beschreibung | |
---|---|---|---|
StorCTLMod | 40348 | 3 | schalte beide Grenzwerte aktiv, Bit-Muster: 11 |
OutWRte | 40355 |
-50 |
setze Entladelimit auf -50% von WchaMax |
InWRte | 40356 |
ist in diesem Fall nicht relevant |
Der Batteriestatus in Fronius Solar.web wechselt zu „Erzwungene Nachladung“
Quelle: 42,0410,2649.pdf
Einsatz in der Praxis: Home Assistant - Automatisierung
Um im Winter eine Restkapazität von 30 % im Akku zu behalten und damit im Notfall den PV-Point nutzen zu können und zudem möglichst keine Akkukapazität zu verschwenden, habe ich mir folgende Automatisierung überlegt:
Aktion | Beschreibung |
Beim Erreichen von 30 % Akkufüllstand -> Skript: SoC (untere Ladegrenze) auf 30% stellen |
An Tagen, an dem der Akku nicht vollständig geladen wird, soll dieser auch nur bis 30 % entladen werden. |
Akku voll geladen -> Skript: Ladeeinstellungen auf Standard setzen |
Sollte der Akku voll geladen werden, soll auch die komplette Kapazität des Akkus zur Verfügung stehen, entsprechend soll das Ladelimit beim Erreichen eines Füllstands von 100 % auf den Standardwert von 5 % gesetzt werden. |
PV-Vorhersage in der Nacht größer 20kW -> Skript: Ladeeinstellungen auf Standard setzen |
Damit die eventuell gesetzte 30 % Ladereserve an sonnigen Tagen nicht verschenkt wird, könnte das Limit anhand der PV-Vorhersage in der Nacht auf den Standardwert von 5 % gesetzt werden: Die 30 % Ladereserve könnten dadurch noch konsumiert werden, bevor die PV-Anlage Strom produziert und den Akku wieder befüllt. |
Die Automatisierung als YAML-Code:
alias: Batterie Management
description: ""
trigger:
- platform: numeric_state
entity_id:
- sensor.byd_battery_box_premium_hv_ladezustand
above: 99
id: voll
- platform: numeric_state
entity_id:
- sensor.byd_battery_box_premium_hv_ladezustand
above: 30
id: 30p
- platform: time
at: "03:00:00"
id: Nacht
condition: []
action:
- if:
- condition: trigger
id:
- voll
then:
- service: script.reset_byd_charging
metadata: {}
data: {}
- if:
- condition: trigger
id:
- 30p
then:
- service: script.reset_charging_25
data: {}
- if:
- condition: trigger
id:
- Nacht
- condition: numeric_state
entity_id: sensor.pv_remaining_today
above: 20
then:
- service: script.reset_byd_charging
metadata: {}
data: {}
mode: single
Der Sensor für die PV-Vorhersage stammt dabei von der Integration Forecast.Solar.
Details zu den Automatisierungen, siehe: Home Assistant Automatisierung - Möglichkeiten & Basics
Quellen
- Inspiriert von: github.com/bigramonk/byd_charging
- Modbus Register: forum.iobroker.net/topic/65205/modbus-fronius-gen24
- Fronius-Dokumentation: www.fronius.com/~/downloads/Solar%20Energy/Operating%20Instructions/42,0410,2649.pdf
{{percentage}} % positiv
DANKE für deine Bewertung!
Fragen / Kommentare
(sortiert nach Bewertung / Datum) [alle Kommentare(neueste zuerst)]
Hallo Bernhard, vielen Dank für den tollen Artikel! Ich habe eine ganz ähnliche Situation, also die Module liefern mehr Spitzenleistung als der WR (Fronius Gen24) verarbeiten kann. Dazu kommt, dass ich weniger Leistung ins Netz liefern darf, als der WR max. produzieren kann. Deshalb möchte ich den WR bei erwartetem Überschuss (Wetter-API) automatisch so konfigurieren, dass die Batterie möglichst geleert wird, es sei denn, der WR läuft in die Limitierung und müsste die Leistung drosseln. In dem Fall soll die überschüssige Leistung in die Batterie geladen werden. Dieses Verhalten lässt sich erreichen, indem in der GUI unter "Battery Management -> Time-dependent battery control" die "Min. discharge power" auf einen positiven Wert eingestellt wird, ansonsten aber keine max. charge/discharge power konfiguriert wird. Das Problem scheint nun zu sein, dass dieser Wert nicht per API (Solar API oder Mosbus) konfigurierbar ist, sondern lediglich per GUI. Per Modbus scheint lediglich die max. charge/discharge power (positiv oder negativ) konfigurierbar zu sein, über welche der gewünschten Effekt aber nicht erreichbar ist. Die Alternative wäre, Werte fortlaufend anzupassen, aber auch das ist nur heuristisch möglich, weil es ja per API gar nicht ohne Weiteres erkennbar ist, ob die Leistung aktuell gedrosselt wird bzw. wie hoch die Leistung ohne Drosselung wäre. Liege ich mit meinen Annahmen richtig, oder übersehe ich etwas? Liebe Grüße Markus
Hallo Markus, was über Modbus möglich ist, ist die Batterie zum Entladen mit einer bestimmten Entladeleistung zu zwingen. Ich hatte dazu in Home Assistant bereits ein Script und dieses hier hinzugefügt: Batterie mit einer bestimmten Leistung entladen (erzwingen). Ich schätze, der Wechselrichter müsste eine eingestellte Einspeisebegrenzung respektieren und dann das Entladen aussetzen? Habe das aber so noch nicht getestet.
Beitrag erstellt von Bernhard
Hallo Bernhard, danke für die Rückmeldung! Sollte in der Nachricht ein Link enthalten sein? Der scheint verlorengegangen zu sein. Wenn man die Batterie zum Entladen zwingt, aber möchte, dass sie im Falle eines Stromüberschusses (z.B. aufgrund eines beschränkten Netzzuganges) dann doch lädt, dann muss man offenbar die Batterie per Skript laufend überwachend und beim Feststellen eines Überschusses von Entladen auf Laden umstellen. Schön wäre, wenn WR/Batterie das selbst regeln würden. Wenn man per Battery Management eine "min. discharge power" konfiguriert, kann genau dieses Verhalten erreicht werden. Aber wenn ich dich recht verstehe, und so wie ich die Modbus API bisher verstanden habe, ist dieses Verhalten per Modbus nicht konfigurierbar und offenbar auch nicht per offizieller Solar API. Per undokumnetierter Web API lässt sich das Verhalten aber offenbar konfigurieren, [siehe z.B. hier](https://github.com/home-assistant/core/issues/92279) [oder hier](https://github.com/evcc-io/evcc/blob/master/templates/definition/meter/fronius-solarapi-v1.yaml). Aber bei Nutzung einer undokumentierten API ist's halt mit der Zukunftssicherheit in der Regel nicht weit her. :-)
Beitrag erstellt von Markus
Hallo Markus, nein es sollte kein Link vorhanden sein: Ich habe die Seite um die Information ergänzt: Überschrift auf dieser Seite: "Batterie mit einer bestimmten Leistung entladen (erzwingen)"
Beitrag erstellt von Bernhard
Alles klar, danke! :-)
Beitrag erstellt von Markus
Hallo Markus und Bernhard! Ich bin nicht sicher, ob ich die beiden Links oben und deren Aussage richtig verstehe - ich bin da eher Neuling. Ich habe genau das oben beschriebene händisch gemacht: Ich habe mir in Home Assistant über Templates mit der Modbus-Schnittstelle ein Regelmodell geschrieben, das - unter der Rahmenbedingung, dass ich einspeisebegrenzt bin - die Batterie wetterabhängig (Prognose) nach einer Soll-Ladekurve über den Tag lädt. Zusätzlich wird in der Nacht abgeschätzt, wie viel Strom bis Sonnenaufgang noch gebraucht wird: Überschuss wird in der Nacht eingespeist. Hauptzweck ist aber, dass ich die Batterie über den Tag langsam lade und nur wenn ich die Einspeisebegrenzung erreiche, wird mehr in die Batterie geladen als geplant um nichts zu verlieren. (Ich mache das eben "händisch" - bei 4kW Einspeisebegrenzung habe ich einen Wert definiert - z.B. 3.900 W. Ich regle nun die Ladung der Batterie so, dass die Einspeisung diesen Zielwert erreichet.) Das funktioniert recht gut. Ich habe aber ein Problem: Ich finde in allen Modbusdaten die aktuelle Solarproduktion, die Leistung von/in der/die Batterie und die Leistung von/ins Netz nicht (der letzte ist der Wichtigste - auf den regle ich ja). Ich nehme zurzeit die Werte aus dem Fronius-API aber die liegt nur im 10 Sekundentakt vor. Funktioniert zwar - aber der Regler mit diesem 10 Sekundentakt ist dadurch träge. Das merkt man vor Allem, wenn sich ein starker Verbraucher ein- bzw. ausschaltet. Ich würde das gerne im 2-5 Sekundentakt laufen lassen - aber das macht natürlich nur Sinn, wenn ich die Messwerte gleichschnell bekomme. Wo finde ich die beim Modbus? Meinem Verständnis nach liefert die der - in meinem Fall - Fronius Smart Meter. Der hängt ja auch am Modbus, aber ich habe noch nicht herausgefunden, wie ich da rankomme. Habt ihr eine Idee oder das schon gelöst? Viele Grüße, Helmut P.S.: Bei Interesse kann ich den Ansatz natürlich gerne teilen.
Beitrag erstellt von Lobotschobi
Entschuldigung - ich habe die Werte doch nun gefunden: den Zugriff auf den Smart Meter für die Einspeiseleistung und die anderen im MPPT-Block. Ich werde sie mir aber noch genauer ansehen, die Auswirkung auf meinen Regler und dann noch kurz darüber informieren. Viele Grüße, Helmut
Beitrag erstellt von Lobotschobi
super, danke: wollts mir auch ansehen, bin aber noch nicht dazugekommen..
Beitrag erstellt von Bernhard
So, hier kurz ein Überblick über meinen Ansatz die Batterieladung Tag und Nacht zu managen. (Ich möchte betonen, dass es sicher schönere Möglichkeiten gibt, das zu implementieren – vielleicht überlege ich mir das noch – vielleicht gibt es auch Ideen. Es ist über einige Wochen gewachsen (ich musste erst lernen, wie man in Home Assistant gewisse Funktionalitäten, Automationen und Variablen umsetzt) und funktioniert jedenfalls recht gut. Bei meiner Recherche über Modelle, die das erledigen, bin ich leider nicht fündig geworden.) Zusammengefasst: Randbedingungen: • Einspeisebegrenzung 4 kW (Anlage: 10 kWp) • Strombezugsvertrag – Stundentarif • Stromliefervertrag: Fixtarif Nacht: Ich berechne, wie viel Energie für meinen Haushalt bis Sonnenaufgang in der Batterie sein soll. Das hängt vom Verbrauch (Sommer weniger / Winter mehr), von der Prognose des Folgetages und vom Stromtarif für den zugekauften Strom ab: Bei Überschuss speise ich die gespeicherte Energie ein, bei Bedarf lade ich zu den günstigen Nachtstunden den Speicher gezielt auf. Tag: Beginnend mit der geplanten Restladung aus „Nacht“ bei Sonnenaufgang wird eine Plan-Ladekurve berechnet. Das ist eine halber Cosinus (verkehrt: -cos(alpha*t-offsetSonnenaufgang), die bei Sonnenaufgang bei der geplanten Restladung beginnt und bei Sonnenuntergang 100% Batterieladung erreicht. Die Aufgabe der Regler Nacht und Tag ist nun den Speicher gemäß dieser Kurve zu verwalten aber die Einspeisebegrenzung zu berücksichtigen (wenn mehr Leistung von der PV-Anlage da ist, wird schneller als die Plan-Ladekurve geladen und bei Bewölkung mit dem Laden wieder gewartet (sprich: mehr eingespeist), bis die Plan-Ladekurve wieder erreicht ist. Aus folgenden beiden Gründen hat es jetzt etwas gedauert (vielleicht hat da jemand einen Kommentar / Lösung dazu): 1. Modbus-Problem: Ich wollte zuerst die Modbusdaten nicht über Sunspec sondern mit dem Modbus-Modul laden (Sunspec kann den Smart Meter nicht auslesen (zumindest habe ich das nicht herausgefunden), daher wollte ich dann alles gleich mit dem Modbus-Modul von Home Assistant einlesen). Dabei bin ich auf das Problem gestoßen, dass des MPPT-Register zu lange ist (Home Assistant begrenzt den String mit 256 Zeichen). Daher musste ich es auf 4 Teile teilen. Im 1. Teil steht der – leider – dynamische Skalierungsfaktor (SF) für die 4 MPPT-Stränge (in diesem Fall für Power - Strang 1, Strang 2, Batterie laden, Batterie entladen). Das war aber nicht synchron: Strang 1 war richtig (in dem Block wurde der Skalierungsfaktor mit eingelesen, der da am Anfang steht). Jetzt ist es aber passiert, dass der SF für die 3 MPPTs aus den anderen 3 Blöcken dann ein Problem bereitet hat, wenn er sich gerade geändert hat. Die MPPT2/3/4 hatten dann genau einen Peak nach oben oder unten – je nachdem. Der Peak war genau Faktor 10 – also war der SF hier gerade noch falsch – ich weiß nicht warum. Das hat meinen Regler natürlich gestört. Ich habe dazu keine Lösung gefunden. Ich habe das Einlesen des MPPT-Blockes dann auf Sunspec umgestellt – und jetzt funktioniert es. 2. Timing: Das ist wohl eher Regelungstechnik und Automation (da habe ich wohl während des Studiums zu wenig aufgepasst ;-) ) Ich lese die Modbusdaten jetzt im 2-Sekundentakt (1-Sekundentakt habe ich mich noch nicht getraut ;-) )) ein und berechne aus allen relevanten Daten die soll-Ladung der Batterie (die ist der Stellwert, der sich aus dem tageszeitabhängigen Zielwert der cos-Kurve und der Einspeisebegrenzung ergibt). Die Ausgabe des Stellwertes für die Batterieladung über Modbus passiert in einer Automation mit einem Takt von zurzeit 6 Sekunden (macht nur eine Sicherheitsabfrage, schaut ob der Regler grundsätzlich aktiviert ist und schreibt das Register - so wie von Bernhard erklärt). Je langsamer ich das mache, desto träger wird der Regler beim Erreichen der Einspeisegrenze und ich verliere Energie, weil der Wechselrichter dann nicht die volle Leistung von den Paneelen abholt, bis der Zielwert wieder erreicht ist. Wenn das zu schnell passiert, beginnt der Wert zu schwingen. Dazu muss ich einfach die Messwerte noch besser verstehen (Glättung / Totzeit) um das ideale Timing für das Reglerverhalten zu finden (viel habe ich da im Internet leider nicht gefunden). So, und bevor ich hier mehr Details poste, warte ich gerne auf Kommentare und ob da überhaupt Interesse besteht. Viele Grüße, Helmut
Beitrag erstellt von Lobotschobi
Hallo Lobotschobi, Leider bin ich nicht ansatzweise so fit wie du im HA.... dein Ansatz klingt aber sehe gut! Ich würde gerne meine Batterie auch PV prognosebasiert (Solcast) und Strompreisabhängig (Tibber) verwalten. Leider bin ich hierzu noch nicht wirklich fündig geworden. Deine Steuerung geht ja an der ein oder anderen Stelle deutlich weiter. Viele Grüße skinflint
Beitrag erstellt von anonym
Über SunSpec sollte der Fronius Smart Meter mit IP x.x.x.x port 502 Slave 200 erreichbar sein. So ist es zumindest bei mir. LG
Beitrag erstellt von anonym
Hallo, auch von mir erstmal danke für die tolle und gut verständliche Anleitung. Bei mir scheint nach Anpassung der Startadresse auf 40355 (nach Excel Gen24_Primo_Symo_Inverter_Register_Map_Float_storage.xlsx) auch das Auslesen der Werte zu klappen. Leider funktioniert das Schreiben bzw. Ausführen der Skripte nicht. Sobald ich auf dem Dashboard auf "Ausführen" egal welchem Skript klicke, ändert sich "nichts", also die gewünschte Umsetzung kommt nicht am Wechselrichter an und auch die angezeigten Werte ändern sich nicht. Was mir aufgefallen ist, ist alle Werte auf dem Dashboard beim Draufklicken als Aktualisierungsdatum immer den Zeitpunkt des letzten HA Restarts anzeigen. Ist das normal oder gibt es evtl. ein Kommunikationsproblem ? Hat jemand eine Idee wie ich hier weiter debuggen kann ? Danke und Gruß Philipp
Hallo Philipp, meinst du mit dem Anpassen der Startadresse die Modbus-Konfiguration in der configuration.yaml-Datei von Home Assistant?: modbus: - type: tcp ... sensors: - name: reading_battery_settings slave: 1 count: 24 address: 40345 ... Sollte dein Setup mit 40355 anstelle von 40345 funktionieren, schätze ich müssen für das Ausführen und Schreiben wahrscheinlich auch angepasste Adressen verwendet werden? Eventuell hat das was mit den Komponenten in der Gerätekonfiguration zu tun? Wie schaut dein Setup dazu aus? Weicht das von meinem Setup ab? Ich habe im Menü Gerätekonfiguration / Komponenten an erster Stelle den PV Generator, dann als Primärzähler den Fronius Smart Meter (RTU, Modbus Adresse: 1) und am Ende die Batterie: BYD Premium HVS/M Menü Kommunikation / Modbus: Modbus RTU-Schnittstelle 0: Master, Modbus RTU-Schnittstelle 1: Master und Slave als modbus TCP Port: 502, SunSpec: int+SF und Zähleradresse: 200.
Beitrag erstellt von Bernhard
Hallo Bernhard, danke für die schnelle Rückmeldung. Meine Konfig war analog deiner, außer der Zähleradresse, da hatte ich 240, und als Sunspec: float. Habe dann auf deine Settings umgestellt, jetzt geht es. Hast du eine Idee, warum es mit float und der anderen Zähleradresse Probleme geben könnte ? Ich brauche diese Einstellungen für meine Bosch Wärmepumpe, die kommuniziert auch über Modbus mit dem Wechselrichter und verlangt diese Einstellungen (können auch m.W. nach nicht angepasst werden bei Bosch :-( Gruß Philipp
Beitrag erstellt von Philipp
Kurzes update: nach Korrektur der Write Adressen geht es bei mir auch mit float werten. Nur die Einstellungen der Lade/Entladebegrenzung will nicht richtig.
Beitrag erstellt von anonym
Hallo Philipp und Bernhard, Ich habe das erst jetzt mit dem float und int+sf verstanden bzw. beachtet. Gibt es eigentlich einen Grund (Vorteil) das mit int+sf zu implementieren? Wie in meinem post weiter oben beschrieben habe ich Probleme mit dem Timing des dynamischen SF (scale factor). Mit der float-Variante wäre das auf einen Schlag weg oder übersehe ich einen Nachteil? Gruß, Helmut
Beitrag erstellt von Lobotschobi
Hallo, vielen Dank für die Anleitung! Fast alles hat wie beschrieben funktioniert. Ich habe jedoch das Problem, dass beim Aktivieren des Scripts "FastCharging" mein Akku mit voller Leistung geladen wird. Wenn ich einen Wert über input_number setze und dann das Script "Limit Charging" ausführe, passiert leider nichts. Hat vielleicht jemand eine Idee, woran das liegen könnte? Viele Grüße! Andre
Hi ihr, bisher habe ich nur ein kleines Problemchen beim Einrichten. Bei mir ist "float" eingestellt. Wo kann ich denn bei den Template-Sensoren die Register-Werte um +10 ändern? Wie komme ich an diese Werte ran? Was ist denn genau der Unterschied zwischen "float" und "int+SF"? Sonst könnte ich ja das auch einfach umstellen oder? LG Michael
Die Werte können im Template frei gewählt werden. Also für die Template-Sensoren um 10 höhere Werte als angegeben verwenden. Oder alternativ: einfach umstellen und die angegebenen Werte verwenden.
Beitrag erstellt von Bernhard
Hallo Bernhard, Vielen Dank für den tollen Artikel und deine Mühen, was du hier umgesetzt hast, ist schon wirklich Klasse. Ich bin in HA noch ziemlich neu und mich würde mal dein Dashboard interessieren, wie du die Akkussteuerung anzeigen lässt bzw. wie du das realisiert hast. Hättest du da eventuell einen Code. Liebe Grüße, Stefan
Hallo! Danke für das coole Tutorial, leider bin ich mit meinen minimalen Fähigkeiten nicht in der Lage es in HA umzusetzen. Jetzt habe ich mit hilfe von KIs ein Python Script geschrieb, welches mir das erzwungene Laden vom Speicher übers Netz ermöglicht. Das funktioniert Grundsätzlich auch, aber die Ladeleistung beträgt nie mehr als 500 W, egal was ich einstelle. Kannst du mir vielleicht einen Tipp geben was ich falsch konfiguriert habe? Das sind meine Einstellungen für die Register: # Setze die Register für die erzwungene Ladung client.write_register(40360, 1) # ChaGriSet: Ladung aus dem Netz erlaubt client.write_register(40348, 2) # StorCtl_Mod: Speicherbetrieb aktiv client.write_register(40355, to_twos_complement(-60)) # OutWRt: Ausgangsleistung auf -60 # (--> da kommt sonst eine Fehlermeldung wenn man nur '-60' schreibt. client.write_register(40356, 10000) # InWRte: Eingangsladung client.write_register(40350, 9800) # MinRsvPct Ich würde mich über jede Hilfe freuen, wenn nicht ist es natürlich auch ok! Danke und LG Alex
Hallo Alex, ich würde das hier beschriebene Template für Register 40355 so ummünzen: Für 500 Watt und 10240 Batteriekapazität: 65536 - (500 / 10240) * 10000 = 65048 also: client.write_register(40355, 65048) -> für 1000 Watt dann entsprechend: 64560 Und ich vermute, dass du die Register 40356 und 40360 für das erzwungene Laden nicht benötigst. Register 440348 steht bei mir auch auf 2 und 40350 ist auf 9900 (Setzt MinRsvPct auf 99,0 % WChaMax)
Beitrag erstellt von Bernhard
Hallo Bernhard, Vielen Dank für die super Anleitung. Ich war schon lange auf der Suche, wie ich dies realisieren könnte - Danke dafür!!!
Hallo Bernhard, meine Hochachtung für Deine Arbeit und Mühe. Genau solch eine Steuerung suchte ich bereits seit geraumer Zeit. Ich habe 2 Gen24 10.0, einen mit 3 x BYD 10.2 HVS und den anderen mit 2 x BYD 22.1 HVM, jeweils paralell geschaltet Ich habe zunächst einen mit Deiner Anleitung integriert. Ich habe mich mit strickt an den Vorgaben gehalten. Erhalte aber, wenn ich ein Skript "ForceDischarge" ausführe, eine Fehlermeldung. In den Step Details wird folgende angezeigt. Fehler: 'H' format requires 0 <= number <= 65535 Ich bin leider nicht so der Freak und komme nicht weiter. Wenn ich beide einbinde, selbstverständlich haben diese unterschiedliche IP, muss ich in der modbus.yaml diese unterschiedlich bezeichnen? Vielen Dank im voraus für Deine Mühe. Gruß Steffen
Hallo Bernhard, ich habe gerade ein ganz anderes Szenario in der Verbindung Fronius / ByD Batterie im Kopf. Ich wechsle zu Tibber und hab mir überlegt wenn im Winter die PV-Anlage nicht genügend Strom erzeugt um die Batterie zu befüllen, könnte ich die Batterie doch nachts günstig aufladen, die Speicherverluste muss ich natürlich berücksichtigen. Ich steuere daheim alles über Homematic und habe auch die Möglichkeit http / https Requests abzuschicken. Wäre es möglich ein entsprechendes Skript hierzu zu erstellen? Gruß Michael
All real registers +1 except 40345, means: 40349 StorCtl_Mod, 40356 OutWRte 40357 InWRte From fronius doc: 40349 40349 1 RW 0x03 0x06 0x10 StorCtl_Mod 40356 40356 1 RW 0x03 0x06 0x10 OutWRte 40357 40357 1 RW 0x03 0x06 0x10 InWRte Fault comes from HA 40345 declaration i guess. Wbr,
Danke für die super Anleitung ich möchte gerne das Register ChaGriSet auslesen was muss ich dazu in den Template Sensor für einen Code schreiben (bin leider nicht der Programmierer), bei den andren konnte ich es mir durch die Beispielcodes zusammenreimen. Ich hätte diesen Ansatz getroffen: {% set ChaGriSet_mod= states('sensor.reading_battery_settings').split(',')[15] | int%} {{ "NETZ AUS" if ChaGriSet_mod == 0 else "NETZ EIN" if ChaGriSet_mod == 1 else else "Fehler" }} Ich bekomme jedoch folgende Anzeige in der Vorschau: Dieses Template überwacht keine Ereignisse und wird nicht automatisch aktualisiert. Danke für deine Unterstützung
Hallo, auf Anhieb sehe ich 2mal else: am Ende der vorletzten und zu Beginn der letzten Zeile. Ansonsten kannst dich mal schrittweise nähern indem du mal nur {{ChaGriSet_mod}} ausgibts und die Ausgabe nach und nach erweiterst.
Beitrag erstellt von Bernhard
Servus, vielen lieben Dank für die rasche Rückmeldung! Du hattest natürlich recht mit dem else richtig schaut das Yaml so aus: {% set ChaGriSet_mod= states('sensor.reading_battery_settings').split(',')[15] | int%} {{ "Netzladen erlaubt" if ChaGriSet_mod == 0 else "Netzladen nicht erlaubt" if ChaGriSet_mod == 1 else "FEHLER" }} Schönen Tag noch, sonnige Grüße aus Österreich
Beitrag erstellt von anonym