Die Firma Sonnen verhindert den Zugriff auf ihren sonnenCharger mit einem Login, ohne ein Passwort bekannt zu geben. Allerdings ist ein Zugriff über den Modbus Port 502 möglich. Wie ich dies in Home Assistant eingebunden habe beschreibe ich hier. Gestestet wurde dies mit Home Assistant 2024.5.
Das Lesen und Schreiben von Werten erfolgt über Registeradressen, wobei ein Register 16 bit breit ist. Eine Liste der Register findetr sich bei Hersteller ETREL der Wallbox:
[https://landisgyr-evsolutions.atlassian.net/wiki/spaces/Home/pages/2236121092/Modbus+Communication+with+Inch+products].
Ich habe eine Datei modbus.yaml erzeugt und via “modbus: !include modbus.yaml” in der config.yaml aufgrufen.
Meine modbus.yaml Datei:
- name: sonnenCharger
type: tcp
host: <IP of your wallbox>
port: 502
sensors:
- name: charge_status_int
address: 0
input_type: input
data_type: int16
- name: no_of_phases
address: 1
input_type: input
data_type: int16
- name: active_power
address: 26
input_type: input
data_type: float32
device_class: power
state_class: measurement
unit_of_measurement: kW
precision: 2
- name: session_energy
address: 30
input_type: input
scan_interval: 10
data_type: float32
device_class: energy
state_class: total_increasing
unit_of_measurement: kWh
- name: session_duration
address: 32
input_type: input
data_type: int64
unit_of_measurement: s
- name: departure_time_unix
address: 36
input_type: input
data_type: int64
unit_of_measurement: s
- name: serial_number
address: 990
input_type: input
data_type: string
count: 10
- name: model
address: 1000
input_type: input
data_type: string
count: 10
- name: HW_version
address: 1010
input_type: input
data_type: string
count: 5
- name: SW_version
address: 1015
input_type: input
data_type: string
count: 5
Die Werte stehen nun als Sensoren in Home assistant bereit. Hier sind Beispiele aus meiner sensors.yaml Datei:
- platform: template
sensors:
wb_active_power:
unique_id: "wb_active_power"
value_template: >-
{% if (states('sensor.active_power') | float) > 0 %}
{{(states('sensor.active_power') | float)}}
{% else %}
{{ 0.0 }}
{% endif %}
- platform: integration
source: sensor.wb_active_power
name: i_wallbox_total_energy
method: right
round: 2
- platform: template
sensors:
wallbox_total_energy:
unique_id: "wallbox_total_energy"
friendly_name: "Wallbox gesamt geladenen Energie"
value_template: >-
{% set number = (states('sensor.i_wallbox_total_energy') | float) %}
{{number}}
device_class: energy
wallbox_session_duration:
unique_id: "wallbox_session_duration"
friendly_name: "Dauer"
value_template: >-
{% set uptime = states("sensor.session_duration") | int %}
{% set hours = (uptime % 86400) // 3600 %}
{% set minutes = (uptime % 3600) // 60 %}
{% set seconds = (uptime % 60) %}
{{ '{:02} Std {:02} Min'.format(hours, minutes) }}
wallbox_departure_time:
unique_id: "wallbox_departure_time"
friendly_name: "Abfahrtszeit in der Wallbox"
value_template: >-
{% set departure = as_datetime(as_datetime(states('sensor.departure_time_unix')) | as_local).strftime("%a. den %d.%m.%Y um %H:%M") %}
{{departure}}
Beim Integrieren muss die Methode “Rechts” gewählt werden, da in active_power “Links” immer noch der alte Wert des letzten Ladens vorhanden ist. Die anderen Methoden führen daher zu zu großen Ergebnissen.
Diese Sensoren können nun auf dem Dashboard als Karten angezeigt werden. Hier ist ein Ausschnitt aus meinem vertical-stack, wo zwei Karten nur bei Bedarf angezeigt werden:
- type: markdown
title: Wallbox
content: >-
<h3> {% if states('sensor.charge_status_int') == '1' %} <ha-alert
alert-type="info">Wallbox bereit</ha-alert> {% elif
states('sensor.charge_status_int') == '2' %} <ha-alert
alert-type="info">Warten auf Verbindung zum Auto</ha-alert> {% elif
states('sensor.charge_status_int') == '3' %} <ha-alert
alert-type="info">Warten, dass Laden startet</ha-alert> {% elif
states('sensor.charge_status_int') == '4' %} <ha-alert
alert-type="success">Auto lädt seit:
{{states('sensor.wallbox_session_duration')}}</ha-alert> {% elif
states('sensor.charge_status_int') == '5' %} <ha-alert
alert-type="info">Auto pausiert Laden</ha-alert> {% elif
states('sensor.charge_status_int') == '6' %} <ha-alert
alert-type="info">Wallbox pausiert Laden</ha-alert> {% elif
states('sensor.charge_status_int') == '7' %} <ha-alert
alert-type="info">Laden beendet</ha-alert> {% elif
states('sensor.charge_status_int') == '8' %} <ha-alert
alert-type="alert">Systemfehler</ha-alert> {% elif
states('sensor.charge_status_int') == '9' %} <ha-alert
alert-type="success">Laden wird fortgesetzt</ha-alert> {% elif
states('sensor.charge_status_int') == '10' %} <ha-alert
alert-type="alert">Nicht verfügbar</ha-alert> {% else %} <ha-alert
alert-type="alert">Ststus unbekannt</ha-alert> {% endif %} </h3>
<small>Software-Version {{states('sensor.sw_version')}}, Hardware-Version
{{states('sensor.hw_version')}}</small>
- type: conditional
conditions:
- condition: numeric_state
entity: sensor.charge_status_int
above: 3
below: 7
card:
type: vertical-stack
cards:
- type: sensor
name: Leistung
entity: sensor.active_power
graph: line
detail: 2
min: 0
max: 11.1
- type: entity
name: aktuell geladenen Energie
icon: mdi:ev-station
entity: sensor.session_energy
- type: entity
entity: sensor.wallbox_total_energy
name: gesamte geladenen Energie
icon: mdi:ev-station
unit: kWh
Man kann aber auch Werte in die Wallbox schreiben! Das ist insbesondere interessant, wenn man mit einer Photovoltaik-Anlage über mehrere Tage laden möchte. Die abfahrtszeit wir in der Box als Unix-Zeitstempel gespeichert. Meine Automation liest die gewünschte Abfahrtszeit aus dem Helfer input_datetime.departure_time ind schreibt ihn in die Box wenn der Knopf input_boolean.wallbox_set_time gedrückt wird. Der Zeitstempel wird dafür in vier 16 bit Integer-Werte zerlegt. Die Berechnung in der automation reicht dabei bis zum Jahr 2106.
Hier der Ausschnitt aus der automations.yaml Datei:
- id: '1716879434742'
alias: set departure time in wallbox
description: setting the expected departure time of the car
trigger:
- platform: state
entity_id:
- input_boolean.wallbox_set_time
condition: []
action:
- service: modbus.write_register
data:
hub: sonnenCharger
address: 4
slave: 0
value: >-
{% set dt = as_timestamp(states('input_datetime.departure_time', 0)) | round(0)%}
{% set reg1 = (dt | float / 65536) | round(0, "floor") | int%}
{% set reg2 = (dt - (reg1 * 65536)) | int%}
[0, 0, {{reg1}}, {{reg2}}]
mode: single
Das Setzen der Zeit ist nur möglich, wenn das auto an der Box angeschlossen ist. Auch macht die Zeit nur sinn, wenn im Smart Mode geladen wird. Die Modi “Smart” und “Power” werden nicht in der Wallbox gespeichert sondern an Sonnen übertragen, die dann die Ladung abhängig von der Energie in PV-Anlage und sonnenBatterie steuern.
Hier noch ein Bild von meinem Dashboard wenn das Auto lädt:
… und so kann ich die Zeit einstellen: