Einen ESP habe ich bisher noch nicht programmiert, wie macht man das? Kannst du mich da durchführen?
Bei heidelbridge ist das etwas komplizierter da es noch kein fertiges Image gibt.
Für den Anfang kannst du auch wbec nehmen, DAV gibt es fertige Images.
Ich hab Heidelbridge jetzt auch mal im Testaufbau umgesetzt. Im Grunde funktioniert es gut, allerdings bekomme ich alle x Sekunden (je nach eingestellter Abfragezeit in EVCC) eine Fehlermeldung mit heatbeat: EOF.
Ich werde das mal beobachten, evtl. steige ich auf das Wireshark um. Kann man das auch ohne Token im EVCC einbinden?
Die Fehlermeldung bekomme ich seit dem letzten EVCC-update tatsächlich auch.
Da ich bis jetzt aber keine Fehlfunktion feststellen konnte, lasse ich es so laufen.
Hallo zusammen,
ich stand vor dem gleichen Problem und es läuft bei mir soweit stabil mit
- HA,
- 2 mal energy control WBen und dem
- Waveshare rs485 to eth (b).
ich bin leider kein ha profi aber vllt. hilft meine lösung dem ein oder anderen. Das Ergebnis sieht in etwa so aus:
- Modbus-Verbindung für zwei Wallboxen (Unit-ID 1 und 2) via TCP-Gateway
- Automatische Deaktivierung des Standby-Modus beim Start sowie alle 5 Minuten
- Regelmäßiger Watchdog-Refresh (alle 15 Sekunden)
- Zentrale Leistungsbegrenzung über input_number.total_charge_power_kw (0–11 kW) samt
- VNB-Sperrsignal (wichtig für §14 EnWG, Modul 3…)
- Python-Skript heidelberg_power_manager verteilt den zur Verfügung stehenden Strom dynamisch, schreibt Register 261/262 und pre-armed die Boxen
- Textsensoren für Ladezustand, Sperre, Remote-Lock und Watchdog-Rücklesung
- Lovelace-Dashboard mit Status, zentraler Steuerung und Verlauf beider Wallboxen
- Skripte zur schnellen Umschaltung des Modbus-Loglevels (Debug/Normal)
Hier meine Waveshare-Settings. Die Timing-Werte weiter unten sind durchaus kritisch:
configuration.yaml anpassen
-
homeassistant: packages: !include_dir_named packages lovelace: dashboards: heidelberg-wallbox: mode: yaml filename: lovelace_heidelberg.yaml title: Heidelberg Wallbox icon: mdi:ev-station show_in_sidebar: true
Für die Inbetriebnahme zusätzlich sicherstellen, dass der Modbus-Logger aktiviert ist:
logger:
default: info
logs:
homeassistant.components.modbus: debug
Modbus-Verbindungsdaten anpassen
In packages/heidelberg.yaml im Abschnitt modbus Host/Port ggf. auf eure Umgebung ändern.
Python Scripts aktivieren
In configuration.yaml muss der Eintrag python_script: vorhanden sein (erledigt in dieser Repo-Version).
Funktion der Automationen & Skripte
wb*_disable_standby_on_start/..._periodic: Setzen Register 258 auf 4 (Standby deaktiviert)wb*_set_currents_on_start: Setzt Maximal- und Failsafe-Strom (Register 261/262) auf 16 A und ruft anschließend das Python-Skriptheidelberg_distribute_total_power: reagiert auf Leistungs-Slider, VNB-Lock, Ladezustände und Remote-Unlock-Schalter und startet das Python-Skriptheidelberg_power_manager.py: berechnet die Stromverteilung (inkl. Pre-Arm), berücksichtigt gesperrte Boxen und schreibt Register 261/262set_modbus_logging_debug/set_modbus_logging_normal: Umschalten der Modbus-Loglevel
Lovelace-Dashboard
Nach dem Neustart erscheint links der Eintrag „Heidelberg Wallbox“. Die Ansicht enthält:
- eine zentrale Karten für Leistungsvorgabe und VNB-Sperrsignal
- Statuskarten mit Klartext-Ladezustand, Sperr-/Watchdog-Rückmeldung, Leistung, Energie beider Wallboxen
- Bedienkarten für Remote-Unlock (als Switch)
- Verlaufsgrafiken (Zustände, Leistung/Stromwerte)
Modbus-Logging bei Bedarf
Über Einstellungen → Automatisierungen & Szenen → Skripte stehen zwei Hilfsskripte bereit:
Logger: Modbus Debug– schaltethomeassistant.components.modbusund sämtlichepymodbus-Logger auf DEBUGLogger: Modbus Normal– stellt sie wieder auf INFO
Logs lassen sich dann über SSH/Terminal analysieren, z. B.:
ha core logs --follow | grep -Ei 'modbus|pymodbus'
Hier das Skript python_scripts/heidelberg_power_manager.py:
# Heidelberg Energy Control load distribution logic
PHASES = 3
VOLTAGE = 230
MIN_CURRENT = 6.0
MAX_CURRENT = 16.0
VNB_LOCK_LIMIT_KW = 4.14
DUAL_THRESHOLD_KW = 8.28
PRIORITY_BOX = 1 # 1 = WB1, 2 = WB2
def get_float(entity_id, default=0.0):
state = hass.states.get(entity_id)
if state is None:
return default
try:
return float(state.state)
except (TypeError, ValueError):
return default
def is_on(entity_id):
state = hass.states.get(entity_id)
return state is not None and state.state == "on"
def wants_charging(code_entity_id):
state = hass.states.get(code_entity_id)
if state is None:
return False
try:
code = int(state.state)
except (TypeError, ValueError):
return False
return code in (5, 6, 7)
def get_state_code(entity_id):
state = hass.states.get(entity_id)
if state is None:
return -1
try:
return int(state.state)
except (TypeError, ValueError):
return -1
def is_available(code):
return code not in (10,)
def clamp_current(value):
if value <= 0:
return 0.0
return max(MIN_CURRENT, min(MAX_CURRENT, value))
def write_modbus_current(unit, register, current):
value = int(round(max(current, 0.0) * 10.0))
hass.services.call(
"modbus",
"write_register",
{
"hub": "heidelberg_bus",
"unit": unit,
"address": register,
"value": value,
},
False,
)
def apply_unit_current(unit, current):
applied = clamp_current(current)
write_modbus_current(unit, 261, applied)
write_modbus_current(unit, 262, applied)
return applied
def effective_power_kw():
slider_kw = get_float("input_number.total_charge_power_kw", 0.0)
power_kw = max(slider_kw, 0.0)
if is_on("input_boolean.vnb_lock"):
power_kw = min(power_kw, VNB_LOCK_LIMIT_KW)
return power_kw
def apply_currents():
power_kw = effective_power_kw()
power_w = power_kw * 1000.0
wb1_request = wants_charging("sensor.wb1_charging_state_code")
wb2_request = wants_charging("sensor.wb2_charging_state_code")
wb1_code = get_state_code("sensor.wb1_charging_state_code")
wb2_code = get_state_code("sensor.wb2_charging_state_code")
wb1_available = is_available(wb1_code)
wb2_available = is_available(wb2_code)
wb1_current = 0.0
wb2_current = 0.0
if power_w <= 0:
pass
elif wb1_available and not wb2_available:
single_current = power_w / (PHASES * VOLTAGE)
wb1_current = max(single_current, MIN_CURRENT)
elif wb2_available and not wb1_available:
single_current = power_w / (PHASES * VOLTAGE)
wb2_current = max(single_current, MIN_CURRENT)
elif wb1_request and not wb2_request:
if wb1_available:
available_current = power_w / (PHASES * VOLTAGE)
wb1_current = max(available_current, MIN_CURRENT)
elif wb2_request and not wb1_request:
if wb2_available:
available_current = power_w / (PHASES * VOLTAGE)
wb2_current = max(available_current, MIN_CURRENT)
else:
single_current = power_w / (PHASES * VOLTAGE)
shared_current = power_w / (PHASES * VOLTAGE * 2)
if not wb1_available and not wb2_available:
pass
elif not wb1_available and wb2_available:
wb2_current = max(single_current, MIN_CURRENT)
elif not wb2_available and wb1_available:
wb1_current = max(single_current, MIN_CURRENT)
elif power_kw < DUAL_THRESHOLD_KW:
selected_current = max(single_current, MIN_CURRENT)
priority = PRIORITY_BOX if wb1_available and wb2_available else (1 if wb1_available else 2)
if priority == 2:
wb2_current = selected_current
else:
wb1_current = selected_current
else:
shared = max(shared_current, MIN_CURRENT)
wb1_current = shared
wb2_current = shared
wb1_applied = apply_unit_current(1, wb1_current)
wb2_applied = apply_unit_current(2, wb2_current)
logger.info(
"Heidelberg power manager -> P_eff=%.2f kW, WB1=%.1f A, WB2=%.1f A",
power_kw,
wb1_applied,
wb2_applied,
)
apply_currents()
Hier mein packages/heidelberg.yaml:
modbus:
- name: heidelberg_bus
type: tcp
host: 192.168.10.40
port: 502
message_wait_milliseconds: 1000
delay: 2
timeout: 5
retries: 2
close_comm_on_error: true
sensors:
- <<: &charging_state_sensor
address: 5
input_type: input
data_type: uint16
scan_interval: 10
name: wb1_charging_state_code
unique_id: wb1_charging_state_code
slave: 1
- <<: *charging_state_sensor
name: wb2_charging_state_code
unique_id: wb2_charging_state_code
slave: 2
- <<: &external_unlock_sensor
address: 13
input_type: input
data_type: uint16
scan_interval: 10
name: wb1_external_unlock_state
unique_id: wb1_external_unlock_state
slave: 1
- <<: *external_unlock_sensor
name: wb2_external_unlock_state
unique_id: wb2_external_unlock_state
slave: 2
- <<: &total_power_sensor
address: 14
input_type: input
data_type: uint16
unit_of_measurement: "W"
scan_interval: 15
name: wb1_total_power
unique_id: wb1_total_power
slave: 1
- <<: *total_power_sensor
name: wb2_total_power
unique_id: wb2_total_power
slave: 2
- <<: &energy_poweron_sensor
address: 15
input_type: input
data_type: uint32
unit_of_measurement: "Wh"
scan_interval: 30
name: wb1_energy_since_poweron
unique_id: wb1_energy_since_poweron
slave: 1
- <<: *energy_poweron_sensor
name: wb2_energy_since_poweron
unique_id: wb2_energy_since_poweron
slave: 2
- <<: &energy_install_sensor
address: 17
input_type: input
data_type: uint32
unit_of_measurement: "Wh"
scan_interval: 60
name: wb1_energy_since_install
unique_id: wb1_energy_since_install
slave: 1
- <<: *energy_install_sensor
name: wb2_energy_since_install
unique_id: wb2_energy_since_install
slave: 2
- <<: &temp_sensor
address: 9
input_type: input
data_type: uint16
scale: 0.1
unit_of_measurement: "°C"
scan_interval: 50
name: wb1_temp_pcb
unique_id: wb1_temp_pcb
slave: 1
- <<: *temp_sensor
name: wb2_temp_pcb
unique_id: wb2_temp_pcb
slave: 2
- <<: &remote_unlock_state_sensor
address: 259
input_type: holding
data_type: uint16
scan_interval: 10
name: wb1_remote_unlock_state
unique_id: wb1_remote_unlock_state
slave: 1
- <<: *remote_unlock_state_sensor
name: wb2_remote_unlock_state
unique_id: wb2_remote_unlock_state
slave: 2
- <<: &standby_state_sensor
address: 258
input_type: holding
data_type: uint16
scan_interval: 10
name: wb1_standby_state
unique_id: wb1_standby_state
slave: 1
- <<: *standby_state_sensor
name: wb2_standby_state
unique_id: wb2_standby_state
slave: 2
- <<: &watchdog_state_sensor
address: 257
input_type: holding
data_type: uint16
scale: 0.001
precision: 3
unit_of_measurement: "s"
scan_interval: 30
name: wb1_watchdog_timeout_ms_state
unique_id: wb1_watchdog_timeout_ms_state
slave: 1
- <<: *watchdog_state_sensor
name: wb2_watchdog_timeout_ms_state
unique_id: wb2_watchdog_timeout_ms_state
slave: 2
- <<: &max_current_state_sensor
address: 261
input_type: holding
data_type: uint16
scale: 0.1
precision: 1
unit_of_measurement: "A"
scan_interval: 30
name: wb1_max_current_setpoint_state
unique_id: wb1_max_current_setpoint_state
slave: 1
- <<: *max_current_state_sensor
name: wb2_max_current_setpoint_state
unique_id: wb2_max_current_setpoint_state
slave: 2
- <<: &failsafe_current_state_sensor
address: 262
input_type: holding
data_type: uint16
scale: 0.1
precision: 1
unit_of_measurement: "A"
scan_interval: 30
name: wb1_failsafe_current_state
unique_id: wb1_failsafe_current_state
slave: 1
- <<: *failsafe_current_state_sensor
name: wb2_failsafe_current_state
unique_id: wb2_failsafe_current_state
slave: 2
switches:
# Standby-Schalter nicht im UI benötig – Steuerung erfolgt automatisch
- <<: &remote_unlock_switch_base
address: 259
command_on: 1
command_off: 0
verify:
input_type: holding
address: 259
name: wb1_remote_unlock
unique_id: wb1_remote_unlock_sw
slave: 1
- <<: *remote_unlock_switch_base
name: wb2_remote_unlock
unique_id: wb2_remote_unlock_sw
slave: 2
input_number:
total_charge_power_kw:
name: Gesamt-Ladeleistung verfügbar
min: 0
max: 11
step: 0.1
unit_of_measurement: kW
mode: slider
initial: 11
input_boolean:
vnb_lock:
name: VNB-Sperrsignal aktiv
icon: mdi:transmission-tower-off
initial: false
template:
- sensor:
- &charging_state_template
name: WB1 Charging State
unique_id: wb1_charging_state
icon: mdi:ev-station
state: >-
{% set raw = states('sensor.wb1_charging_state_code') %}
{% if raw in ['unknown', 'unavailable', 'none'] %}
Unbekannt
{% else %}
{% set code = raw | int(-1) %}
{% set state_map = {
1: 'Initialisierung',
2: 'A1 – Kein Fahrzeug angeschlossen, Wallbox gesperrt',
3: 'A2 – Kein Fahrzeug angeschlossen, Wallbox freigegeben',
4: 'B1 – Fahrzeug angeschlossen ohne Ladeanforderung, Wallbox gesperrt',
5: 'B2 – Fahrzeug angeschlossen ohne Ladeanforderung, Wallbox freigegeben',
6: 'C1 – Ladeanforderung aktiv, Wallbox gesperrt',
7: 'C2 – Ladeanforderung aktiv, Wallbox freigegeben',
8: 'Derating aktiv',
9: 'Fehlerzustand',
10: 'Wallbox gesperrt oder nicht bereit',
11: 'Unbekannter Fehlerzustand'
} %}
{{ state_map.get(code, 'Unbekannt') }}
{% endif %}
attributes:
raw_state: "{{ states('sensor.wb1_charging_state_code') }}"
iec_state: >-
{% set code = states('sensor.wb1_charging_state_code') | int(-1) %}
{% set iec_map = {
2: 'A1',
3: 'A2',
4: 'B1',
5: 'B2',
6: 'C1',
7: 'C2',
8: 'Derating',
9: 'E',
10: 'F',
11: '---'
} %}
{{ iec_map.get(code, '---') }}
car_state: >-
{% set code = states('sensor.wb1_charging_state_code') | int(-1) %}
{% set car_map = {
2: 'Kein Fahrzeug angeschlossen',
3: 'Kein Fahrzeug angeschlossen',
4: 'Fahrzeug angeschlossen, keine Ladeanforderung',
5: 'Fahrzeug angeschlossen, keine Ladeanforderung',
6: 'Fahrzeug angeschlossen, Ladeanforderung aktiv',
7: 'Fahrzeug angeschlossen, lädt',
8: 'Derating aktiv',
9: 'Fehlerzustand',
10: 'Wallbox gesperrt oder nicht bereit',
11: 'Fehlerzustand'
} %}
{{ car_map.get(code, 'Unbekannt') }}
wallbox_state: >-
{% set code = states('sensor.wb1_charging_state_code') | int(-1) %}
{% set wb_map = {
2: 'Wallbox sperrt',
3: 'Wallbox freigegeben',
4: 'Wallbox sperrt',
5: 'Wallbox freigegeben',
6: 'Wallbox sperrt',
7: 'Wallbox freigegeben',
8: 'Wallbox reduziert Leistung (Derating)',
9: 'Wallbox Fehler',
10: 'Wallbox gesperrt oder nicht bereit',
11: 'Wallbox Fehler'
} %}
{{ wb_map.get(code, 'Unbekannt') }}
- <<: *charging_state_template
name: WB2 Charging State
unique_id: wb2_charging_state
state: >-
{% set raw = states('sensor.wb2_charging_state_code') %}
{% if raw in ['unknown', 'unavailable', 'none'] %}
Unbekannt
{% else %}
{% set code = raw | int(-1) %}
{% set state_map = {
1: 'Initialisierung',
2: 'A1 – Kein Fahrzeug angeschlossen, Wallbox gesperrt',
3: 'A2 – Kein Fahrzeug angeschlossen, Wallbox freigegeben',
4: 'B1 – Fahrzeug angeschlossen ohne Ladeanforderung, Wallbox gesperrt',
5: 'B2 – Fahrzeug angeschlossen ohne Ladeanforderung, Wallbox freigegeben',
6: 'C1 – Ladeanforderung aktiv, Wallbox gesperrt',
7: 'C2 – Ladeanforderung aktiv, Wallbox freigegeben',
8: 'Derating aktiv',
9: 'Fehlerzustand',
10: 'Wallbox gesperrt oder nicht bereit',
11: 'Unbekannter Fehlerzustand'
} %}
{{ state_map.get(code, 'Unbekannt') }}
{% endif %}
attributes:
raw_state: "{{ states('sensor.wb2_charging_state_code') }}"
iec_state: >-
{% set code = states('sensor.wb2_charging_state_code') | int(-1) %}
{% set iec_map = {
2: 'A1',
3: 'A2',
4: 'B1',
5: 'B2',
6: 'C1',
7: 'C2',
8: 'Derating',
9: 'E',
10: 'F',
11: '---'
} %}
{{ iec_map.get(code, '---') }}
car_state: >-
{% set code = states('sensor.wb2_charging_state_code') | int(-1) %}
{% set car_map = {
2: 'Kein Fahrzeug angeschlossen',
3: 'Kein Fahrzeug angeschlossen',
4: 'Fahrzeug angeschlossen, keine Ladeanforderung',
5: 'Fahrzeug angeschlossen, keine Ladeanforderung',
6: 'Fahrzeug angeschlossen, Ladeanforderung aktiv',
7: 'Fahrzeug angeschlossen, lädt',
8: 'Derating aktiv',
9: 'Fehlerzustand',
10: 'Wallbox gesperrt oder nicht bereit',
11: 'Fehlerzustand'
} %}
{{ car_map.get(code, 'Unbekannt') }}
wallbox_state: >-
{% set code = states('sensor.wb2_charging_state_code') | int(-1) %}
{% set wb_map = {
2: 'Wallbox sperrt',
3: 'Wallbox freigegeben',
4: 'Wallbox sperrt',
5: 'Wallbox freigegeben',
6: 'Wallbox sperrt',
7: 'Wallbox freigegeben',
8: 'Wallbox reduziert Leistung (Derating)',
9: 'Wallbox Fehler',
10: 'Wallbox gesperrt oder nicht bereit',
11: 'Wallbox Fehler'
} %}
{{ wb_map.get(code, 'Unbekannt') }}
- &external_unlock_template
name: WB1 Externe Sperre
unique_id: wb1_external_unlock_state_text
icon: >-
{% set code = states('sensor.wb1_external_unlock_state') | int(0) %}
{% if code == 1 %}
mdi:lock-open-variant
{% else %}
mdi:lock
{% endif %}
state: >-
{% set raw = states('sensor.wb1_external_unlock_state') %}
{% if raw in ['unknown', 'unavailable', 'none'] %}
Unbekannt
{% else %}
{% set code = raw | int(0) %}
{% if code == 1 %}
Freigegeben
{% elif code == 0 %}
Gesperrt
{% else %}
Unbekannt ({{ code }})
{% endif %}
{% endif %}
attributes:
raw_state: "{{ states('sensor.wb1_external_unlock_state') }}"
- <<: *external_unlock_template
name: WB2 Externe Sperre
unique_id: wb2_external_unlock_state_text
icon: >-
{% set code = states('sensor.wb2_external_unlock_state') | int(0) %}
{% if code == 1 %}
mdi:lock-open-variant
{% else %}
mdi:lock
{% endif %}
state: >-
{% set raw = states('sensor.wb2_external_unlock_state') %}
{% if raw in ['unknown', 'unavailable', 'none'] %}
Unbekannt
{% else %}
{% set code = raw | int(0) %}
{% if code == 1 %}
Freigegeben
{% elif code == 0 %}
Gesperrt
{% else %}
Unbekannt ({{ code }})
{% endif %}
{% endif %}
attributes:
raw_state: "{{ states('sensor.wb2_external_unlock_state') }}"
- &remote_unlock_template
name: WB1 Remote Unlock
unique_id: wb1_remote_unlock_state_text
icon: >-
{% set code = states('sensor.wb1_remote_unlock_state') | int(1) %}
{% if code == 1 %}
mdi:lock-open-variant
{% else %}
mdi:lock
{% endif %}
state: >-
{% set raw = states('sensor.wb1_remote_unlock_state') %}
{% if raw in ['unknown', 'unavailable', 'none'] %}
Unbekannt
{% else %}
{% set code = raw | int(1) %}
{% if code == 1 %}
Remote frei
{% elif code == 0 %}
Remote gesperrt
{% else %}
Unbekannter Wert ({{ code }})
{% endif %}
{% endif %}
attributes:
raw_state: "{{ states('sensor.wb1_remote_unlock_state') }}"
- <<: *remote_unlock_template
name: WB2 Remote Unlock
unique_id: wb2_remote_unlock_state_text
icon: >-
{% set code = states('sensor.wb2_remote_unlock_state') | int(1) %}
{% if code == 1 %}
mdi:lock-open-variant
{% else %}
mdi:lock
{% endif %}
state: >-
{% set raw = states('sensor.wb2_remote_unlock_state') %}
{% if raw in ['unknown', 'unavailable', 'none'] %}
Unbekannt
{% else %}
{% set code = raw | int(1) %}
{% if code == 1 %}
Remote frei
{% elif code == 0 %}
Remote gesperrt
{% else %}
Unbekannter Wert ({{ code }})
{% endif %}
{% endif %}
attributes:
raw_state: "{{ states('sensor.wb2_remote_unlock_state') }}"
- &standby_state_template
name: WB1 Standby Zustand
unique_id: wb1_standby_state_text
icon: >-
{% set code = states('sensor.wb1_standby_state') | int(-1) %}
{% if code == 4 %}
mdi:power-plug
{% elif code == 0 %}
mdi:power-plug-off
{% else %}
mdi:help-circle
{% endif %}
state: >-
{% set raw = states('sensor.wb1_standby_state') %}
{% if raw in ['unknown', 'unavailable', 'none'] %}
Unbekannt
{% else %}
{% set code = raw | int(-1) %}
{% if code == 4 %}
Standby deaktiviert
{% elif code == 0 %}
Standby aktiviert
{% else %}
Unbekannter Wert ({{ code }})
{% endif %}
{% endif %}
attributes:
raw_state: "{{ states('sensor.wb1_standby_state') }}"
- <<: *standby_state_template
name: WB2 Standby Zustand
unique_id: wb2_standby_state_text
icon: >-
{% set code = states('sensor.wb2_standby_state') | int(-1) %}
{% if code == 4 %}
mdi:power-plug
{% elif code == 0 %}
mdi:power-plug-off
{% else %}
mdi:help-circle
{% endif %}
state: >-
{% set raw = states('sensor.wb2_standby_state') %}
{% if raw in ['unknown', 'unavailable', 'none'] %}
Unbekannt
{% else %}
{% set code = raw | int(-1) %}
{% if code == 4 %}
Standby deaktiviert
{% elif code == 0 %}
Standby aktiviert
{% else %}
Unbekannter Wert ({{ code }})
{% endif %}
{% endif %}
attributes:
raw_state: "{{ states('sensor.wb2_standby_state') }}"
script:
wb1_remote_unlock_toggle:
alias: "WB1 Remote Unlock umschalten"
sequence:
- variables:
prefix: "wb1"
unit: 1
- service: modbus.write_register
data:
hub: heidelberg_bus
unit: "{{ unit | int }}"
address: 259
value: >-
{% if states('sensor.' ~ prefix ~ '_remote_unlock_state') | int(1) == 1 %}
0
{% else %}
1
{% endif %}
wb2_remote_unlock_toggle:
alias: "WB2 Remote Unlock umschalten"
sequence:
- variables:
prefix: "wb2"
unit: 2
- service: modbus.write_register
data:
hub: heidelberg_bus
unit: "{{ unit | int }}"
address: 259
value: >-
{% if states('sensor.' ~ prefix ~ '_remote_unlock_state') | int(1) == 1 %}
0
{% else %}
1
{% endif %}
set_modbus_logging_debug:
alias: "Logger: Modbus Debug"
sequence:
- service: logger.set_level
data:
homeassistant.components.modbus: debug
pymodbus: debug
pymodbus.client: debug
pymodbus.client.base: debug
pymodbus.transaction: debug
pymodbus.framer.rtu_framer: debug
set_modbus_logging_normal:
alias: "Logger: Modbus Normal"
sequence:
- service: logger.set_level
data:
homeassistant.components.modbus: info
pymodbus: info
pymodbus.client: info
pymodbus.client.base: info
pymodbus.transaction: info
pymodbus.framer.rtu_framer: info
automation:
- alias: wb1_disable_standby_on_start
description: "Deaktiviert Standby bei Systemstart"
trigger:
- platform: homeassistant
event: start
action:
- service: modbus.write_register
data:
hub: heidelberg_bus
unit: 1
address: 258
value: 4
mode: single
- alias: wb2_disable_standby_on_start
description: "Deaktiviert Standby bei Systemstart"
trigger:
- platform: homeassistant
event: start
action:
- service: modbus.write_register
data:
hub: heidelberg_bus
unit: 2
address: 258
value: 4
mode: single
- alias: wb1_disable_standby_periodic
description: "Hält Standby von WB1 dauerhaft deaktiviert"
trigger:
- platform: time_pattern
minutes: "/5"
action:
- service: modbus.write_register
data:
hub: heidelberg_bus
unit: 1
address: 258
value: 4
mode: single
- alias: wb2_disable_standby_periodic
description: "Hält Standby von WB2 dauerhaft deaktiviert"
trigger:
- platform: time_pattern
minutes: "/5"
action:
- service: modbus.write_register
data:
hub: heidelberg_bus
unit: 2
address: 258
value: 4
mode: single
- alias: wb1_set_currents_on_start
description: "Setzt Maximal- und Failsafe-Strom von WB1 beim Start auf 16 A"
trigger:
- platform: homeassistant
event: start
action:
- service: modbus.write_register
data:
hub: heidelberg_bus
unit: 1
address: 261
value: 160
- service: modbus.write_register
data:
hub: heidelberg_bus
unit: 1
address: 262
value: 160
- service: python_script.heidelberg_power_manager
mode: single
- alias: wb2_set_currents_on_start
description: "Setzt Maximal- und Failsafe-Strom von WB2 beim Start auf 16 A"
trigger:
- platform: homeassistant
event: start
action:
- service: modbus.write_register
data:
hub: heidelberg_bus
unit: 2
address: 261
value: 160
- service: modbus.write_register
data:
hub: heidelberg_bus
unit: 2
address: 262
value: 160
- service: python_script.heidelberg_power_manager
mode: single
- alias: vnb_lock_follow_shelly_input
description: "Spiegelt den negierten Zustand des Shelly-Eingangs auf die VNB-Sperre"
trigger:
- platform: state
entity_id: binary_sensor.shellypro1_30c6f787af0c_input_0
- platform: time_pattern
minutes: "/1"
action:
- service: >-
{% if is_state('binary_sensor.shellypro1_30c6f787af0c_input_0', 'on') %}
input_boolean.turn_off
{% else %}
input_boolean.turn_on
{% endif %}
target:
entity_id: input_boolean.vnb_lock
mode: restart
- alias: heidelberg_distribute_total_power
description: "Berechnet und verteilt die Gesamtleistung auf beide Wallboxen"
trigger:
- platform: homeassistant
event: start
- platform: state
entity_id:
- input_number.total_charge_power_kw
- input_boolean.vnb_lock
- sensor.wb1_charging_state_code
- sensor.wb2_charging_state_code
- switch.wb1_remote_unlock
- switch.wb2_remote_unlock
action:
- service: python_script.heidelberg_power_manager
mode: restart
- &watchdog_keepalive_base
alias: wb1_watchdog_keepalive
description: "Sendet alle 15 Sekunden den Watchdog-Wert an die Wallbox WB1"
trigger:
- platform: time_pattern
seconds: "/15"
action:
- service: modbus.write_register
data:
hub: heidelberg_bus
unit: 1
address: 257
value: 15000
mode: restart
- <<: *watchdog_keepalive_base
alias: wb2_watchdog_keepalive
description: "Sendet alle 15 Sekunden den Watchdog-Wert an die Wallbox WB2"
action:
- service: modbus.write_register
data:
hub: heidelberg_bus
unit: 2
address: 257
value: 15000
Hier meine lovelace_heidelberg.yaml
title: Heidelberg Wallbox
views:
- title: Heidelberg WB
path: heidelberg-wb
icon: mdi:ev-station
badges:
- entity: sensor.wb1_charging_state
- entity: sensor.wb1_total_power
- entity: sensor.wb2_charging_state
- entity: sensor.wb2_total_power
cards:
- type: entities
title: Gesamtsteuerung
show_header_toggle: false
entities:
- entity: input_number.total_charge_power_kw
name: verfügbare Ladeleistung (kW)
- entity: input_boolean.vnb_lock
name: VNB-Sperrsignal aktiv
- type: entities
title: WB1 Status
show_header_toggle: false
entities:
- entity: sensor.wb1_charging_state
name: Ladezustand (IEC 61851)
- entity: sensor.wb1_external_unlock_state_text
name: Externer Sperreingang
- entity: sensor.wb1_remote_unlock_state_text
name: Remote Unlock Status
- entity: sensor.wb1_standby_state_text
name: Standby-Zustand
- entity: sensor.wb1_watchdog_timeout_ms_state
name: Watchdog Timeout (Rücklesung)
- entity: sensor.wb1_max_current_setpoint_state
name: Maximalstrom Soll (Rücklesung)
- entity: sensor.wb1_failsafe_current_state
name: Failsafe-Strom (Rücklesung)
- entity: sensor.wb1_total_power
name: Aktuelle Ladeleistung
- entity: sensor.wb1_energy_since_poweron
name: Energie seit Einschalten
- entity: sensor.wb1_energy_since_install
name: Energie seit Installation
- entity: sensor.wb1_temp_pcb
name: Leiterplattentemperatur
- type: entities
title: WB2 Status
show_header_toggle: false
entities:
- entity: sensor.wb2_charging_state
name: Ladezustand (IEC 61851)
- entity: sensor.wb2_externe_sperre
name: Externer Sperreingang
- entity: sensor.wb2_remote_unlock
name: Remote Unlock Status
- entity: sensor.wb2_standby_zustand
name: Standby-Zustand
- entity: sensor.wb2_watchdog_timeout_ms_state
name: Watchdog Timeout (Rücklesung)
- entity: sensor.wb2_max_current_setpoint_state
name: Maximalstrom Soll (Rücklesung)
- entity: sensor.wb2_failsafe_current_state
name: Failsafe-Strom (Rücklesung)
- entity: sensor.wb2_total_power
name: Aktuelle Ladeleistung
- entity: sensor.wb2_energy_since_poweron
name: Energie seit Einschalten
- entity: sensor.wb2_energy_since_install
name: Energie seit Installation
- entity: sensor.wb2_temp_pcb
name: Leiterplattentemperatur
- type: entities
title: Bedienelemente WB1
show_header_toggle: false
entities:
- entity: switch.wb1_remote_unlock_2
name: Remote Unlock
- type: entities
title: Bedienelemente WB2
show_header_toggle: false
entities:
- entity: switch.wb2_remote_unlock
name: Remote Unlock
- type: history-graph
title: Zustände WB1
hours_to_show: 24
entities:
- sensor.wb1_charging_state
- sensor.wb1_external_unlock_state_text
- sensor.wb1_remote_unlock_state_text
- sensor.wb1_standby_state_text
- type: history-graph
title: Zustände WB2
hours_to_show: 24
entities:
- sensor.wb2_charging_state
- sensor.wb2_externe_sperre
- sensor.wb2_remote_unlock
- sensor.wb2_standby_zustand
- type: history-graph
title: Leistung / Stromwerte
hours_to_show: 24
entities:
- sensor.wb1_total_power
- sensor.wb1_max_current_setpoint_state
- sensor.wb1_failsafe_current_state
- sensor.wb2_total_power
- sensor.wb2_max_current_setpoint_state
- sensor.wb2_failsafe_current_state
Settings wb1: (s6 schwer zu erkennen, ist genauso wie bei wb2)
Settings WB2:
Ach ja, in der heidelberg.yaml(Zeile 670-686) gibt es eine entität vnb_lock_follow_shelly_input: Hier wird ein Input eines Shelly Pro1 Relais minütlich auf die Eintität vnb_lockkopiert. Das ist in jedem Fall an Eure Verhältnisse anzupassen…
Hallo!
Ich bekomme es ebenfalls nicht hin, habe aber die gleiche Hardware im Einsatz. Ich würde gern deine Waveshare Einstellungen übernehmen. Frage: Was ist die Destination Ip? Ist das dein Home Assistant oder ist der Wert völlig irrelevant?
Irrelevant. HA pollt den waveshare-Server.



