Seit Jahren versuche ich eine sinnvolle Implementierung einer über HA gesteuerten Netzladung meines PV Akkus umzusetzen. Mit der Unterstützung von Claude endlich geschafft. Hier die Details:
- Fronius Symo Gen24 10.0 Wechselrichter
(wichtig: dieser hat die Modbus Schnittstelle natürlich aktiv und den “SunSpec Model Type” auf “float” gesetzt. - BVD Akku
Hier mal vorweg die Ansicht im Dashboard:
Hier die Modbus Definition für die z.B. configuration.yaml
modbus:
- name: gen24
type: tcp
host: X.X.X.X
port: 502
sensors:
- name: "GEN24 AC Power"
slave: 1
address: 40083
input_type: holding
data_type: float32
precision: 0
unit_of_measurement: "W"
device_class: power
state_class: measurement
- name: "GEN24 AC Energy Total"
slave: 1
address: 40093
input_type: holding
data_type: float32
precision: 0
unit_of_measurement: "Wh"
device_class: energy
state_class: total_increasing
- name: "GEN24 DC Power"
slave: 1
address: 40101
input_type: holding
data_type: float32
precision: 0
unit_of_measurement: "W"
device_class: power
state_class: measurement
- name: "Battery StorCtl Mod"
slave: 1
address: 40358
input_type: holding
data_type: uint16
- name: "Battery MinRsvPct"
slave: 1
address: 40360
input_type: holding
data_type: uint16
scale: 0.01
precision: 1
unit_of_measurement: "%"
- name: "Battery ChaSt"
slave: 1
address: 40364
input_type: holding
data_type: uint16
- name: "Battery OutWRte"
slave: 1
address: 40365
input_type: holding
data_type: int16
scale: 0.01
precision: 1
unit_of_measurement: "%"
- name: "Battery InWRte"
slave: 1
address: 40366
input_type: holding
data_type: int16
scale: 0.01
precision: 1
unit_of_measurement: "%"
- name: "Battery ChaGriSet"
slave: 1
address: 40370
input_type: holding
data_type: uint16
Automations, Scripts, etc. habe ich in einem eigenen fronius.yaml. Code wie folgt:
# packages/fronius.yaml
# Fronius Symo GEN24 — battery grid charge control
#
# Confirmed register addresses (firmware 1.39.5-1, float model):
# StorCtl_Mod → address 40358 (register 40359) bitfield16: bit0=charge, bit1=discharge
# MinRsvPct → address 40360 (register 40361) uint16, scale -2 (10000=100%, 2000=20%)
# OutWRte → address 40365 (register 40366) int16, scale -2 (10000=100%, -10000=-100%)
# InWRte → address 40366 (register 40367) int16, scale -2 (10000=100%)
# ChaGriSet → address 40370 (register 40371) enum16: 0=PV only, 1=grid allowed
#
# Prerequisites (requires Technician password in GEN24 web UI):
# Communication → Modbus → "Inverter control via Modbus" → ON
# Device config → Components → Battery → "Battery charging from DNO grid" → ON
input_boolean:
grid_charging_active:
name: "Grid charging active"
icon: mdi:battery-charging
input_number:
grid_charge_target_soc:
name: "Grid charge target SOC"
min: 20
max: 100
step: 5
unit_of_measurement: "%"
icon: mdi:battery-charging-80
grid_charge_power:
name: "Grid charge power"
min: 10
max: 100
step: 5
unit_of_measurement: "%"
icon: mdi:lightning-bolt
grid_charge_normal_reserve:
name: "Normal battery reserve"
min: 0
max: 50
step: 5
initial: 20
unit_of_measurement: "%"
icon: mdi:battery-low
script:
fronius_start_grid_charge:
alias: "Fronius: Start grid charge"
description: "Force BYD battery to charge from grid up to target SOC"
icon: mdi:battery-charging
sequence:
# 1) Allow grid charging (ChaGriSet = 1)
- service: modbus.write_register
data:
hub: gen24
slave: 1
address: 40370
value: [1]
# 2) Set MinRsvPct to target SOC — forces inverter to charge up to this level
# Scale -2: value = target_soc × 100
- service: modbus.write_register
data:
hub: gen24
slave: 1
address: 40360
value:
- "{{ (states('input_number.grid_charge_target_soc') | int * 100) | int }}"
# 3) Set InWRte to charge power % (max charge rate)
# Scale -2: value = pct × 100
- service: modbus.write_register
data:
hub: gen24
slave: 1
address: 40366
value:
- "{{ (states('input_number.grid_charge_power') | int * 100) | int }}"
# 4) Set OutWRte to negative charge power % — forces full charging window
# Negative OutWRte shifts the power window into charging territory
# This is what triggers "Forced Recharge" mode at full power
- service: modbus.write_register
data:
hub: gen24
slave: 1
address: 40365
value:
- "{{ (65536 - (states('input_number.grid_charge_power') | int * 100)) | int }}"
# 5) Activate both charge and discharge limits (StorCtl_Mod = 3, bits 11)
- service: modbus.write_register
data:
hub: gen24
slave: 1
address: 40358
value: [3]
# 6) Set active flag
- service: input_boolean.turn_on
target:
entity_id: input_boolean.grid_charging_active
fronius_stop_grid_charge:
alias: "Fronius: Stop grid charge"
description: "Return battery to normal automatic mode"
icon: mdi:battery-auto
sequence:
# 1) Return StorCtl_Mod to auto (0)
- service: modbus.write_register
data:
hub: gen24
slave: 1
address: 40358
value: [0]
# 2) Reset MinRsvPct to normal reserve
# Scale -2: value = reserve × 100
- service: modbus.write_register
data:
hub: gen24
slave: 1
address: 40360
value:
- "{{ (states('input_number.grid_charge_normal_reserve') | int * 100) | int }}"
# 3) Reset OutWRte to +100%
- service: modbus.write_register
data:
hub: gen24
slave: 1
address: 40365
value: [10000]
# 4) Reset InWRte to 100%
- service: modbus.write_register
data:
hub: gen24
slave: 1
address: 40366
value: [10000]
# 5) Clear active flag
- service: input_boolean.turn_off
target:
entity_id: input_boolean.grid_charging_active
automation:
- id: fronius_auto_stop_at_target_soc
alias: "Fronius: Auto-stop grid charge at target SOC"
description: "Stop charging from grid once battery reaches target SOC"
trigger:
- platform: numeric_state
entity_id: sensor.byd_battery_box_premium_hv_ladezustand
above: input_number.grid_charge_target_soc
condition:
- condition: state
entity_id: input_boolean.grid_charging_active
state: "on"
action:
- service: script.fronius_stop_grid_charge
- service: persistent_notification.create
data:
title: "Grid charge complete"
message: >
Battery reached {{ states('sensor.byd_battery_box_premium_hv_ladezustand') | round(0) }}% —
grid charging stopped automatically.
mode: single
- id: fronius_grid_charge_safety_timeout
alias: "Fronius: Grid charge safety timeout"
description: "Failsafe — stop grid charging after 4 hours regardless of SOC"
trigger:
- platform: state
entity_id: input_boolean.grid_charging_active
to: "on"
for:
hours: 4
action:
- service: script.fronius_stop_grid_charge
- service: persistent_notification.create
data:
title: "Grid charge timeout"
message: "Grid charging stopped after 4-hour safety limit."
mode: single
Und zum Schluss den Code fürs Dashboard. Kann natürlich jeder machen wie er will ![]()
title: Fronius Battery
views:
- title: Battery
path: battery
icon: mdi:battery-charging
cards:
- type: vertical-stack
cards:
- type: custom:mushroom-template-card
primary: Akkuladung aus dem Netz
secondary: |
{% if is_state('input_boolean.grid_charging_active', 'on') %}
Charging from grid · {{ states('sensor.byd_battery_box_premium_hv_ladezustand') | round(0) }}%
{% else %}
{% set st = states('sensor.battery_chast') | int(0) %}
{% if st == 2 %}Entladen
{% elif st == 3 %}Laden von PV
{% elif st == 4 %}Voll geladen
{% elif st == 5 %}Halten
{% elif st == 6 %}Leerlauf
{% else %}Auto mode
{% endif %} · {{ states('sensor.byd_battery_box_premium_hv_ladezustand') | round(0) }}%
{% endif %}
icon: |
{% if is_state('input_boolean.grid_charging_active', 'on') %}
mdi:transmission-tower
{% else %}
mdi:battery-auto
{% endif %}
badge_icon: |
{% if is_state('input_boolean.grid_charging_active', 'on') %}
mdi:lightning-bolt
{% endif %}
badge_color: amber
tap_action:
action: none
color: |
{% if is_state('input_boolean.grid_charging_active', 'on') %}
amber
{% else %}
green
{% endif %}
features_position: bottom
- type: custom:gauge-card-pro
entity: sensor.byd_battery_box_premium_hv_ladezustand
segments:
- pos: 0
color: red
- pos: 25
color: '#FFA500'
- pos: 50
color: rgb(255, 255, 0)
- pos: 100
color: var(--green-color)
needle: true
gradient: true
titles:
primary: BYD Batterie Ladezustand (SOC)
gradient_resolution: auto
min_indicator:
type: number
value: 20
color: red
opacity: 0
- type: entities
title: Einstellungen
entities:
- entity: input_number.grid_charge_target_soc
icon: mdi:battery-charging-80
name: Ziel SOC
- entity: input_number.grid_charge_power
icon: mdi:lightning-bolt
name: Max. Ladeleistung
- entity: input_number.grid_charge_normal_reserve
icon: mdi:battery-low
name: Standard Reserve SOC
- type: horizontal-stack
cards:
- type: custom:mushroom-template-card
primary: Start
secondary: Netzladung
icon: mdi:play-circle-outline
tap_action:
action: call-service
service: script.fronius_start_grid_charge
hold_action:
action: none
color: amber
features_position: bottom
- type: custom:mushroom-template-card
primary: Stop
secondary: Automatikmodus
icon: mdi:stop-circle-outline
tap_action:
action: call-service
service: script.fronius_stop_grid_charge
hold_action:
action: none
color: green
features_position: bottom
- type: entities
title: Modbus Stati
show_header_toggle: false
entities:
- entity: sensor.battery_storctl_mod
name: StorCtl_Mod
icon: mdi:cog
- entity: sensor.battery_inwrte
name: Charge rate (InWRte)
icon: mdi:battery-charging
- entity: sensor.battery_chagriset
name: Grid charge allowed (ChaGriSet)
icon: mdi:transmission-tower
- entity: input_boolean.grid_charging_active
name: Grid charging active flag
icon: mdi:flag
Finally: Ich bin noch am Optimieren. Es ist auch noch eine Teil in EN und ein Teil in DE. Muss ich auch noch bereinigen. Aber: Es hat heute bereits tadellos funktioniert.
Grüße
C

