Integration der sonnenCharger/Etrel Inch Home/Duo Wallbox in Home Assistant

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:
Wallbox Zeiteinstellung

1 „Gefällt mir“

Kennst du EVCC? Die können laut Anleitung auch Sonnen: Wallboxen | evcc - Sonne tanken ☀️🚘

EVCC ist die ganz große Lösung, bei der die Firma Sonnen zur Steuerung der Wallbox überflüssig wird. Daher muss die Box dann auch im Power Modus betrieben werden. Der Vorteil ist, dass man mit EVCC das Laden sehr viel genauer an seine Bedürfnisse anpassen kann.
Mein Ansatz ist nur eine kleine Lösung, die dem Wunsch vieler sonnenCharger Nutzer nachkommt

  1. interessante Werte aus der Wallbox auslesen zu können
  2. die Abfahrtszeit über einen längeren Zeitraum als einen Tag einstellen zu können

Seit meiner Home Assistant Einbindung benutze ich auch die viel kritisierte sonnenCharger-App nicht mehr.

Ich kenne EVCC, aber warum was eigenes basteln wenn es schon was fertiges gibt?
Meines Wissen kann EVCC doch genau das was du suchst und machst oder warum nutzt du EVCC nicht?

Hi Fridi,

Deine Integration ist prima und funktioniert hervorragend mit dem SonnenCharger. Könntest du noch etwas detaillierter erklären, wie du das mit dem einstellen der Zeit machst …

… vielen Dank

Daniel

Was genau meinst du?

Hallo Daniel,

für das Einstellen der Zeit habe ich drei Helfer erstellt:
input_datetime.zeit_auto_abfahrbereit zur Vorgabe der Abfahrtszeit
input_boolean.set_time als Variable, die mit einem custom button gesetzt wird
input_boolean.set_time_ui bestimmt ob Karten zu Zeiteinstellung angezeigt werden oder nicht (nur damit das Dashboard nicht zu voll wird)

Für den Dashboard habe ich dann folgenden Yaml-Kode geschrieben.

 - show_state: false
    show_name: false
    camera_view: auto
    type: picture-entity
    entity: input_boolean.wallbox_set_time_ui
    name: Abfahrtszeit setzen
    state_image:
      'on': /local/img/sonnenCharger - set time - arrow up 2.jpg
      'off': /local/img/sonnenCharger - set time - arrow down 2.jpg
    tap_action:
      action: toggle
    hold_action:
      action: toggle
  - type: conditional
    conditions:
      - condition: state
        entity: input_boolean.wallbox_set_time_ui
        state: 'on'
      - condition: numeric_state
        entity: sensor.charge_status_int
        below: 7
        above: 3
    card:
      type: vertical-stack
      cards:
        - type: markdown
          content: <div>Zeiten nur relevant im Smart Mode der Wallbox!</div>
        - type: entities
          entities:
            - entity: input_datetime.zeit_auto_abfahrtbereit
              name: Gewünschte Abfahrtszeit
        - type: custom:button-card
          entity: input_boolean.wallbox_set_time
          name: Klicken um Zeit zu übernehmen
          icon: mdi:clock
          show_name: true
          show_icon: false
          styles:
            grid:
              - grid-template-areas: '"n i"'
              - grid-template-columns: 60% 40%
          entity_picture: /local/img/sonnenCharger_upload_orange.jpg
          show_entity_picture: true
        - type: entity
          name: Abfahrtszeit in Wallbox
          entity: sensor.wallbox_departure_time
          icon: mdi:clock
  - type: conditional
    conditions:
      - condition: state
        entity: input_boolean.wallbox_set_time_ui
        state: 'on'
      - condition: or
        conditions:
          - condition: numeric_state
            entity: sensor.charge_status_int
            below: 4
          - condition: numeric_state
            entity: sensor.charge_status_int
            above: 6
    card:
      type: vertical-stack
      cards:
        - type: markdown
          content: >-
            <div>Das Einstellen der Abfahrtszeit ist nur möglich wenn das Auto
            an der Wallbox angeschlossen ist</div>
        - type: entity
          name: Derzeitige Abfahrtszeit in Wallbox
          entity: sensor.wallbox_departure_time
          icon: mdi:clock

Nach dem Einstellen der Zeit muss man ein paar Sekunden warten, bis die neue Zeit auch angezeigt wird, da der Modbus nur alle paar Sekunden gelesen wird.

Mittlerweile habe ich festgestellt, dass das mit der Integration für die Gesamtenergie immer noch nicht richtig funktioniert. Der erste Wert bei einem Ladevorgang ist hier immer noch zu groß. Man müsste irgendwie den ersten Wert ausschließen. Eine Lösung habe ich dafür bisher nicht.