Skip to content

Instantly share code, notes, and snippets.

@JavanXD
Last active December 4, 2025 22:38
Show Gist options
  • Select an option

  • Save JavanXD/a3e8911e69f3a27a81eeeb80414bb6ab to your computer and use it in GitHub Desktop.

Select an option

Save JavanXD/a3e8911e69f3a27a81eeeb80414bb6ab to your computer and use it in GitHub Desktop.
SchwörerHaus WGT BIC VentCube Fresh Home Assistant Integration via modbus
# Helpful information:
# https://github.com/Excodibur/ioBroker.schwoerer-ventcube/blob/master/src/lib/schwoerer/parameters.ts
# https://github.com/fgoettel/wgt/blob/main/wgt/lueftungsanlage.py
# https://knx-user-forum.de/forum/öffentlicher-bereich/knx-eib-forum/diy-do-it-yourself/1822296-modbus-schwörer-heizung?p=1906252#post1906252
##################
# MODBUS SENSORS #
##################
modbus:
- name: BIC_VentCube
delay: 2
timeout: 3
type: tcp
host: !secret wgt_ip
port: 502
sensors:
- name: VentCube Betriebsart
slave: 1
unique_id: ventcube_betriebsart
address: 100
# Translated with template sensor
# Translated with input_select Automation
- name: VentCube Manuelle Luftstufe
slave: 1
unique_id: ventcube_manuelle_luftstufe
address: 101
# Translated with input_select Automation
- name: VentCube Aktuelle Luftstufe
slave: 1
unique_id: ventcube_aktuelle_luftstufe
address: 102
- name: VentCube Status Stoßlüftung
slave: 1
unique_id: ventcube_status_stosslueftung
address: 111
# Translated with template sensor
- name: VentCube Restlaufzeit Stoßlüftung
slave: 1
unique_id: ventcube_restlaufzeit_stosslueftung
address: 112
unit_of_measurement: min
device_class: duration
min_value: 0
max_value: 60
- name: VentCube Status Wärmepumpe
slave: 1
unique_id: ventcube_status_waermepumpe
address: 114
# Translated with template sensor
- name: VentCube Status Nachheizregister
slave: 1
unique_id: ventcube_status_nachheizregister
address: 116
# Translated with template sensor
- name: VentCube Status Gebläse Zuluft
slave: 1
unique_id: ventcube_status_geblaese_zuluft
address: 117
# Translated with template sensor
- name: VentCube Status Gebläse Abluft
slave: 1
unique_id: ventcube_status_geblaese_abluft
address: 118
# Translated with template sensor
- name: VentCube Bypass Zustand
slave: 1
unique_id: ventcube_bypass_zustand
address: 123
# Translated with template sensor
- name: VentCube Zustand Außenklappe
slave: 1
unique_id: ventcube_zustand_aussenklappe
address: 131
# Translated with template sensor
- name: VentCube Status Vorheizregister
slave: 1
unique_id: ventcube_status_vorheizregister
address: 133
# Translated with template sensor
- name: VentCube aktuelle Luftleistung Zuluft
slave: 1
unique_id: ventcube_aktuelle_luftleistung_zuluft
address: 142
state_class: measurement
unit_of_measurement: "%"
min_value: 0
max_value: 100
scale: 1
precision: 0
- name: VentCube aktuelle Luftleistung Abluft
unique_id: ventcube_aktuelle_luftleistung_abluft
slave: 1
address: 143
state_class: measurement
unit_of_measurement: "%"
min_value: 0
max_value: 100
scale: 1
precision: 0
- name: VentCube aktuelle Drehzahl Zuluft
unique_id: ventcube_aktuelle_drehzahl_zuluft
slave: 1
address: 144
state_class: measurement
unit_of_measurement: "rpm"
min_value: 0
max_value: 10000
precision: 0
- name: VentCube aktuelle Drehzahl Abluft
unique_id: ventcube_aktuelle_drehzahl_abluft
slave: 1
address: 145
state_class: measurement
unit_of_measurement: "rpm"
min_value: 0
max_value: 10000
precision: 0
- name: VentCube T2 Temperatur nach Vorheizregister
slave: 1
unique_id: ventcube_t2_temperatur_nach_vorheizregister
unit_of_measurement: °C
device_class: temperature
address: 201
scale: 0.1
precision: 1
- name: VentCube T3 Temperatur vor Nacherwärmung
slave: 1
unique_id: ventcube_t3_temperatur_vor_nacherwaermung
unit_of_measurement: °C
device_class: temperature
address: 202
scale: 0.1
precision: 1
- name: VentCube T4 Temperatur nach Nacherwärmung
slave: 1
unique_id: ventcube_t4_temperatur_nach_nacherwaermung
unit_of_measurement: °C
device_class: temperature
address: 203
scale: 0.1
precision: 1
- name: VentCube T5 Temperatur Abluft
slave: 1
unique_id: ventcube_t5_temperatur_abluft
unit_of_measurement: °C
device_class: temperature
address: 204
scale: 0.1
precision: 1
- name: VentCube T6 Temperatur im Wärmetauscher
slave: 1
unique_id: ventcube_t6_temperatur_im_waermetauscher
unit_of_measurement: °C
device_class: temperature
address: 205
scale: 0.1
precision: 1
- name: VentCube T10 Temperatur Außen
slave: 1
unique_id: ventcube_t10_temperatur_aussen
unit_of_measurement: °C
device_class: temperature
address: 209
scale: 0.1
precision: 1
- name: VentCube Heiz- Kühlfunktion
slave: 1
unique_id: ventcube_heiz_kuehlfunktion
address: 230
# Translated with template sensor
# Translated with input_select Automation
- name: VentCube Wärmepumpe Heizen
slave: 1
unique_id: ventcube_wp_heizen
address: 231
- name: VentCube Wärmepumpe Kühlen
slave: 1
unique_id: ventcube_wp_kuehlen
address: 232
- name: VentCube Druckwächter aktiv
slave: 1
unique_id: ventcube_druckwachter_aktiv
address: 242
# Translated with template sensor (binary_sensor)
- name: VentCube EVU Sperre aktiv
slave: 1
unique_id: ventcube_evu_sperre_aktiv
address: 243
# Translated with template sensor (binary_sensor)
- name: VentCube Wartungstür offen
slave: 1
unique_id: ventcube_wartungstur_offen
address: 244
# Translated with template sensor (binary_sensor)
- name: VentCube Gerätefilter verschmutzt
slave: 1
unique_id: ventcube_geratefilter_verschmutzt
address: 245
# Translated with template sensor (binary_sensor)
- name: VentCube Vorgelagerter Filter verschmutzt
slave: 1
unique_id: ventcube_vorgelagerter_filter_verschmutzt
address: 246
# Translated with template sensor (binary_sensor)
- name: VentCube Zuluft zu kalt
slave: 1
unique_id: ventcube_zuluft_zu_kalt
address: 254
# Translated with template sensor (binary_sensor)
- name: VentCube Restlaufzeit Gerätefilter
slave: 1
unique_id: ventcube_restlaufzeit_geratefilter
address: 265
unit_of_measurement: d
min_value: 0
max_value: 255
device_class: duration
- name: VentCube Temperatur Wohnzimmer IST
slave: 1
unique_id: ventcube_temperatur_wohnzimmer_ist
unit_of_measurement: °C
device_class: temperature
address: 360
scale: 0.1
precision: 1
min_value: 0
max_value: 100
switches:
- name: VentCube Freigabe WP auf Heizen
slave: 1
address: 231
command_on: 0x1 # Freigabe
command_off: 0x0 # Gesperrt
write_type: holdings
verify:
input_type: holding
state_on: 0x1
state_off: 0x0
delay: 5
unique_id: ventcube_set_waermepumpe_heizen
- name: VentCube Freigabe WP auf Kühlen
slave: 1
address: 232
command_on: 0x1 # Freigabe
command_off: 0x0 # Gesperrt
write_type: holdings
verify:
input_type: holding
state_on: 0x1
state_off: 0x0
delay: 5
unique_id: ventcube_set_waermepumpe_kuehlen
climates:
- name: "VentCube Soll-Temperatur"
unique_id: ventcube_soll_temperatur
slave: 1
address: 400
max_temp: 30
min_temp: 10
offset: 0
precision: 0
scale: 0.1
target_temp_register: 400
target_temp_write_registers: true
temp_step: 1
temperature_unit: °C
- name: "VentCube Basis-Temperatur"
unique_id: ventcube_basis_temperatur
slave: 1
address: 420
max_temp: 30
min_temp: 18
offset: 0
precision: 0
scale: 0.1
target_temp_register: 420
target_temp_write_registers: true
temp_step: 1
temperature_unit: °C
#####################################################
# Select Options which require separate Automations #
#####################################################
input_select:
ventcube_manuelle_luftstufe:
name: VentCube Manuelle Luftstufe
options:
- "0 - Aus"
- "1 - Stufe 1"
- "2 - Stufe 2"
- "3 - Stufe 3"
- "4 - Stufe 4"
- "5 - Automatik"
- "6 - Linearbetrieb"
icon: mdi:fan
ventcube_betriebsart:
name: VentCube Betriebsart
options:
- "0 - Aus"
- "1 - Handbetrieb"
- "2 - Winterbetrieb"
- "3 - Sommerbetrieb"
- "4 - Sommer Abluft"
icon: mdi:fan
ventcube_heiz_kuehlfunktion:
name: VentCube Heiz- Kühlfunktion
options:
- "0 - Aus"
- "1 - Heizen"
- "2 - Kühlen"
- "3 - Auto T-Außen"
- "4 - Auto Digitaler Eingang"
icon: mdi:fan
####################
# TEMPLATE SENSORS #
####################
sensor:
- platform: template
sensors:
ventcube_betriebsart_text:
unique_id: ventcube_betriebsart_text
friendly_name: "VentCube Betriebsart"
value_template: >
{% set mapper = {
'0': 'Aus',
'1': 'Handbetrieb',
'2': 'Winterbetrieb',
'3': 'Sommerbetrieb',
'4': 'Sommer Abluft'} %}
{% set state = states.sensor.ventcube_betriebsart.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
ventcube_bypass_zustand_text:
unique_id: ventcube_bypass_zustand_text
friendly_name: "VentCube Zustand Bypass"
value_template: >
{% set mapper = {
'0': 'Geschlossen',
'1': 'Offen (Kühlen)',
'2': 'Offen (Heizen)'} %}
{% set state = states.sensor.ventcube_bypass_zustand.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
ventcube_zustand_aussenklappe_text:
unique_id: ventcube_zustand_aussenklappe_text
friendly_name: "VentCube Zustand Außenklappe"
value_template: >
{% set mapper = {
'0': 'Geschlossen',
'1': 'Offen'} %}
{% set state = states.sensor.ventcube_zustand_aussenklappe.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
ventcube_status_waermepumpe_text:
unique_id: ventcube_status_waermepumpe_text
friendly_name: "VentCube Status Wärmepumpe"
value_template: >
{% set mapper = {
'0': 'Aus',
'5': 'WP Heizen',
'49': 'WP Kühlen'} %}
{% set state = states.sensor.ventcube_status_waermepumpe.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
ventcube_heiz_kuehlfunktion_text:
unique_id: ventcube_heiz_kuehlfunktion_text
friendly_name: "VentCube Status Heiz- Kühlfunktion"
value_template: >
{% set mapper = {
'0': 'Aus',
'1': 'Heizen',
'2': 'Kühlen',
'3': 'Auto T-Außen',
'4': 'Auto Digitaler Eingang'} %}
{% set state = states.sensor.ventcube_heiz_kuehlfunktion.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
ventcube_status_nachheizregister_text:
unique_id: ventcube_status_nachheizregister_text
friendly_name: "VentCube Status Nachheizregister"
value_template: >
{% set mapper = {
'0': 'Inaktiv',
'1': 'Aktiv'} %}
{% set state = states.sensor.ventcube_status_nachheizregister.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
ventcube_status_vorheizregister_text:
unique_id: ventcube_status_vorheizregister_text
friendly_name: "VentCube Status Vorheizregister"
value_template: >
{% set mapper = {
'0': 'Aus',
'1': 'VHR1 Aktiv',
'2': 'VHR2 Aktiv',
'3': 'VHR1+2 Aktiv'} %}
{% set state = states.sensor.ventcube_status_vorheizregister.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
ventcube_status_stosslueftung_text:
unique_id: ventcube_status_stosslueftung_text
friendly_name: "VentCube Status Stoßlüftung"
value_template: >
{% set mapper = {
'0': 'Inaktiv',
'1': 'Aktiv'} %}
{% set state = states.sensor.ventcube_status_stosslueftung.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
ventcube_status_geblaese_zuluft_text:
unique_id: ventcube_status_geblaese_zuluft_text
friendly_name: "VentCube Status Gebläse Zuluft"
value_template: >
{% set mapper = {
'0': 'Deaktiviert',
'1': 'Anlaufphase',
'2': 'Aktiv',
'5': 'Standby',
'6': 'Fehler'} %}
{% set state = states.sensor.ventcube_status_geblaese_zuluft.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
ventcube_status_geblaese_abluft_text:
unique_id: ventcube_status_geblaese_abluft_text
friendly_name: "VentCube Status Gebläse Abluft"
value_template: >
{% set mapper = {
'0': 'Deaktiviert',
'1': 'Anlaufphase',
'2': 'Aktiv',
'5': 'Standby',
'6': 'Fehler'} %}
{% set state = states.sensor.ventcube_status_geblaese_abluft.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
template:
- binary_sensor:
- name: "VentCube Meldung Druckwächter Aktiv"
unique_id: ventcube_meldung_druckwachter_aktiv
device_class: problem
state: >
{% set mapper = {
'0': 'off',
'1': 'on'} %}
{% set state = states.sensor.ventcube_druckwachter_aktiv.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
- name: "VentCube Meldung EVU Sperre aktiv"
unique_id: ventcube_meldung_evu_sperre_aktiv
device_class: problem
state: >
{% set mapper = {
'0': 'off',
'1': 'on'} %}
{% set state = states.sensor.ventcube_evu_sperre_aktiv.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
- name: "VentCube Meldung Wartungstür offen"
unique_id: ventcube_meldung_wartungstur_offen
device_class: problem
state: >
{% set mapper = {
'0': 'off',
'1': 'on'} %}
{% set state = states.sensor.ventcube_wartungstur_offen.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
- name: "VentCube Meldung Gerätefilter verschmutzt"
unique_id: ventcube_meldung_geratefilter_verschmutzt
device_class: problem
state: >
{% set mapper = {
'0': 'off',
'1': 'on'} %}
{% set state = states.sensor.ventcube_geratefilter_verschmutzt.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
- name: "VentCube Meldung Vorgelagerter Filter verschmutzt"
unique_id: ventcube_meldung_vorgelagerter_filter_verschmutzt
device_class: problem
state: >
{% set mapper = {
'0': 'on',
'1': 'off'} %}
{% set state = states.sensor.ventcube_vorgelagerter_filter_verschmutzt.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
- name: "VentCube Meldung Zuluft Zu Kalt"
unique_id: ventcube_meldung_zuluft_zu_kalt
device_class: problem
state: >
{% set mapper = {
'0': 'off',
'1': 'on'} %}
{% set state = states.sensor.ventcube_zuluft_zu_kalt.state %}
{{ mapper[state] if state in mapper else 'Unknown' }}
@Maigus2510
Copy link

@JavanXD , würdest du deine 3 Automatisierungen teilen?

Daran wäre ich auch Interessiert. Wir haben noch ein Leda Luc 2 Unterdruckwächter. Der hat ja auch ein Temperatur-Sensor. Hat den schonmal jemand eingebunden?

Grüße

@JavanXD
Copy link
Author

JavanXD commented Nov 19, 2024

@JavanXD , würdest du deine 3 Automatisierungen teilen?

Hallo @Maigus2510 / @nivost22 ,

meine Automatisierungen hier:

alias: VentCube - Schalte Kühl-/Heizmodus je nach Wetterprognose
description: ""
mode: single
triggers:
  - at: "00:15:00"
    trigger: time
  - at: "07:00:00"
    trigger: time
conditions: []
actions:
  - if:
      - condition: numeric_state
        entity_id: sensor.openweathermap_forecast_temperature
        above: 22
      - condition: time
        before: "01:00:00"
    then:
      - data: {}
        action: script.ventcube_luftstufe_3
      - metadata: {}
        data: {}
        action: script.ventcube_aktiviere_kuhlen
  - if:
      - condition: numeric_state
        entity_id: sensor.openweathermap_forecast_temperature
        below: 19
      - condition: time
        after: "05:00:00"
    then:
      - metadata: {}
        data: {}
        action: script.ventcube_aktiviere_heizen

Im Sommer um Hitze zu Vermeiden:

alias: VentCube - Reguliere Lüftungsstufe wenn warm draußen
description: ""
mode: single
triggers:
  - minutes: /10
    trigger: time_pattern
  - entity_id:
      - sensor.ventcube_bypass_zustand
    from: null
    to: null
    trigger: state
conditions:
  - condition: state
    state: "2"
    entity_id: sensor.ventcube_heiz_kuehlfunktion
actions:
  - if:
      - condition: or
        conditions:
          - condition: numeric_state
            entity_id: sensor.ventcube_t4_temperatur_nach_nacherwarmung
            below: sensor.ventcube_t5_temperatur_abluft
          - condition: numeric_state
            entity_id: sensor.ventcube_t3_temperatur_vor_nacherwarmung
            below: sensor.ventcube_t5_temperatur_abluft
          - condition: state
            entity_id: sensor.ventcube_bypass_zustand
            state: "1"
    then:
      - if:
          - condition: and
            conditions:
              - condition: numeric_state
                entity_id: sensor.ventcube_t5_temperatur_abluft
                above: 23.5
              - condition: numeric_state
                entity_id: sensor.ventcube_t10_temperatur_aussen
                below: 20
        then:
          - action: script.ventcube_luftstufe_3
            data: {}
        else:
          - action: script.ventcube_luftstufe_2
            data: {}
    else:
      - metadata: {}
        data: {}
        action: script.ventcube_luftstufe_1

CO2 Sensor:

alias: VentCube - Anpassung Lüftungsstufe bei CO2
description: ""
mode: single
triggers:
  - minutes: /15
    trigger: time_pattern
conditions:
  - condition: state
    entity_id: sensor.ventcube_betriebsart
    state: "1"
  - type: is_carbon_dioxide
    condition: device
    device_id: ebd29c5419fa6418f130987624a519ed
    entity_id: 54a176aa531b7d4562485fc82402bd3e
    domain: sensor
    above: 380
  - condition: state
    entity_id: input_boolean.turn_on_automation_kohlendioxid
    state: "on"
actions:
  - if:
      - condition: numeric_state
        entity_id: sensor.co2_kohlendioxid
        below: 800
    then:
      - metadata: {}
        data: {}
        action: script.ventcube_luftstufe_1
    else:
      - if:
          - condition: numeric_state
            entity_id: sensor.co2_kohlendioxid
            below: 1000
        then:
          - data: {}
            action: script.ventcube_luftstufe_2
        else:
          - if:
              - condition: numeric_state
                entity_id: sensor.co2_luftfeuchtigkeit
                above: 40
            then:
              - metadata: {}
                data: {}
                action: script.ventcube_luftstufe_3
  - delay:
      hours: 0
      minutes: 5
      seconds: 0
      milliseconds: 0

@JavanXD
Copy link
Author

JavanXD commented Nov 19, 2024

Daran wäre ich auch Interessiert. Wir haben noch ein Leda Luc 2 Unterdruckwächter. Der hat ja auch ein Temperatur-Sensor. Hat den schonmal jemand eingebunden?

Hi @Maigus2510 ,

das lässt sich mit einem ESPHome umsetzen, dazu brauchst du einen ESP32, den kannst du über den USB Port des Displays mit Strom versorgen. Blauer Kreis = USB Anschluss, Roter Kreis den Temperatursensor auslesen.
Der Temperatursensor ist ein PT100, der lässt sich mit der https://esphome.io/components/sensor/max31865.html Komponente auslesen.
Problem ist aber, der Temperatursensor lässt sich nur von einem Receiver auslesen, dh. die Leda LUC würde dann kein Messwert mehr empfangen.

@JavanXD
Copy link
Author

JavanXD commented Nov 23, 2024

@Maigus2510 Ich muss mich korrigieren, ich messe in der Zwischenzeit die LEDA Luc2 Messwerte über den CAN Bus aus. Ich habe die Yaml Datei hier hochgeladen und auch die benötigten Bauteile aufgelistet: https://gist.github.com/JavanXD/696d026ef202a7d6455ed4745df63e39
Image

@StefanZander
Copy link

StefanZander commented Jan 6, 2025

Hallo in die Runde,
erstmal vielen Dank für die tollen Beiträge hier.
Mein Problem ist ein vergleichsweise triviales: Viele der Text-Entitäten (bspw. ventcube_status_waermepumpe_text) liefern bei mir den Wert Unknown obwohl der zugehörige Sensor (bspw. states.sensor.ventcube_status_waermepumpe.state) die korrekte Zahl liefert.

Im YAML sieht der Template Sensor so aus:

      ventcube_status_waermepumpe_text:
        unique_id: ventcube_status_waermepumpe_text
        friendly_name: "VentCube Status Wärmepumpe"
        value_template: >
          {% set mapper = {
            '0': 'Aus',
            '5': 'WP Heizen',
            '49': 'WP Kühlen'} %}
          {% set state =  states.sensor.ventcube_status_waermepumpe.state %}
          {{ mapper[state] if state in mapper else 'Unknown' }}

Interessant ist, dass der Eintrag für den Zustand der Außenklappe mit nahezu identischem YAML-Code funktioniert, d.h., in der Text-Entität (ventcube_zustand_aussenklappe_text) wird der korrekte Text (bspw. Geschlossen bei Status 0) angezeigt.

Zum Vergleich hier der entspr. Auszug aus der modbus_wgt.yaml:

ventcube_zustand_aussenklappe_text:
        unique_id: ventcube_zustand_aussenklappe_text
        friendly_name: "VentCube Zustand Außenklappe"
        value_template: >
          {% set mapper = {
            '0': 'Geschlossen',
            '1': 'Offen'} %}
          {% set state =  states.sensor.ventcube_zustand_aussenklappe.state %}
          {{ mapper[state] if state in mapper else 'Unknown' }}

Vielleicht hat jemand eine Idee woran das liegen könnte...

Vielen Dank vorab und beste Grüße!

Edit: Es scheint, als hätte states.sensor.ventcube_status_waermepumpe.state keinen Wert bzw. ist diese Variable leer. Der Aufruf has_value('sensor.ventcube_status_waermepumpe') liefert False zurück.

Edit 2: Es wird immer kurioser:
Verwende ich statt dem obigen Eintrag diesen hier {% set state = states('sensor.ventcube_status_warmepumpe') %} (man beachte: ...status_warmepumpe statt ...status_waermepumpe) dann funktioniert der template sensor (siehe Autovervollständigung auf beigefügten Screenshot). Ich habe aktuell noch keine Ahnung warum dies der Fall ist. In der modbus_wgt.yaml findet sich an keiner Stelle ein Sensor mit dem Namen ventcube_status_warmepumpe.

Screenshot 2025-01-06 at 21 40 32

@FreshyQS
Copy link

Hi, danke für die Vorarbeit und die ganzen Kommentare.
Das ist mein erstes Projekt im Home Assistend, damit sich andere Anfänger leichter tun, hab ich mal eine Anleitung geschrieben, die gerne angepasst und weitergeführt werden darf.
Teilweise stehen die Infos auch in den Kommentaren hier, dort habe ich mich dann bedient. In der Anleitung steht es nur etwas ausfürhlicher drinnen mit ein paar Zusatzschritten.

Anleitung Ventcube in Homeassistend integrieren

  1. Ventcube in das Hauseigene Netzwerk integrieren
    a. Ventcube via Lan-Verkabeln
    b. In den Einstellungen Modbus TCP aktivieren
    i. WGT Display
    ii. Einstellungen
    iii. Service
    iv. Passwort eingeben (Standard „1234“)
    v. Ihr landet dadurch wieder in den Hauptscreen -> klickt erneut auf Einstellungen
    vi. Grundeinstellungen
    vii. 10. Modbus TCP aktivieren
    viii. WGT neustarten (Sicherung raus/rein -> gibt eventuell auch charmantere Wege)
    c. IP-Adresse der WGT herausfinden
    i. Entweder in den Netzwerkeinstellung am WGT-Display
    ii. Bei Fritzbox-Modem wie folgt
    1. Internet Browser startet -> fritz.box + einloggen
    2. Heimnetz -> Netzwerk

  2. Installation File Editor
    a. Am besten erstmal ein Back-Up in Home Assistent ziehen
    b. Add-On zum Editieren von File Editor installieren (z.B https://github.com/home-assistant/addons/tree/master/configurator) oder
    „File Editor“ aus dem offiziellen Add-On Store (Einstellungen -> Add-ons->Add-on Store-> File Editor->Installieren und starten

3.. Anpassen der Konfiguration
a. Anpassung der /homeassistant/configuration.yaml
i. File-Editor öffnen configuration.yaml suchen und öffnen
ii. In die configuration.yaml folgendes schreiben
grafik
homeassistant:
packages: !include_dir_named packages

  iii.	Neuen Ordner mit dem Namen „packages“ im File Editor anlegen
  iv.	Ordner öffnen und neues File in diesem Ordner anlegen „modbus_wgt.yaml“
  v.	Die oben beschriebene yaml hineinkopieren (am besten in RAW  öffnen (oben rechts) und copy&paste)
  vi.	Zeile 15 „host: !secret wgt_ip“ durch IP-Adresse ersetzen, welche im Schritt 1.c rausgefunden wurde
            Die Zeile sieht dann wie folgt aus „host: XXX.XXX.XX.XX“
  1. YAML-Konfiguration neu laden
    a. Einstellungen
    b. Nach Neu Laden „Alle YAML-Konfigurationen“ suchen und ausführen.

  2. Dashboard anpassen
    a. Übersicht
    b. Stift oben rechts (bearbeiten)
    c. Karten hinzufügen
    i. Nun könnt ihr Karten auswählen oder nach Entität
    ii. Wollt ihr das Diagramm von nivost22 laden, dann bei „Auswahl nach Karte“ nach unten scrollen und „Manuell auswählen“
    iii. Die yaml siehe Kommentar nivost 22 on Sep 19, 2024 kopieren und einfügen (type: darf nur am Anfang einmal stehen
    müsst ihr wsl einmal löschen, da es schon vorgegeben ist)
    iv. Auf „visuellen Editor anzeigen“ wechseln (unten links im Dialog)
    v. Ganz unten „Neues Element hinzufügen“ -> Bild
    vi. Die zugehörigen Bilder hochladen
    vii. ANMERKUNG
    viii. Ab hier müsst ihr die Bildwerte anpassen, das hab ich selbst nur mit mühe und Not hinbekommen. Kann wer evtl die
    Anleitung weiterführen?
    Das Bild wurde bei mir etwas klein und ich habe die ganzen Badges und das Bild rumgeschoben
    ix.
    grafik

    x. Speichern -> Fertig

@JavanXD

Die drei Auswahlfelder:

Damit das Auswahlfelöd der Lüftungsstufe funktioniert brauch man für das Auswahlfeld eine Automation, die so aussieht:..

Kannst du das noch erklären wie wo was?
Finde die Funktion nämlich sehr gut.

Danke :)

@Maxxxe
Copy link

Maxxxe commented Jan 28, 2025

Wir haben im Bad eine elektrische Fußbodenheizung. Die kann ich entweder über die Zeit-Heizprogramme oder die Zusatzheizungen frei geben. Das funktioniert auch. Zusätzliche kann man in dem Bedienfeld auch noch einen 30 Minuten „Boost“ anklicken und die Heizung würde 30 Minuten an bleiben. Das wäre praktisch ähnlich wie die Stoßlüftung. IMG_4610

Hallo Leute,

gibt es eigentlich mittlerweile eine Lösung für die genannte Boost Funktion?

Vielen Dank!

Grüße!

@Maigus2510
Copy link

Ich hab es noch nicht hinbekommen. Ich hatte es versucht ähnlich wie die Stoßlüftung zu programmieren, das geht aber nicht .

@gCZECHer
Copy link

Kann bitte jemand erklären wie die Automation zum Setzten der ventcube_manuelle_luftstufe aussieht? Danke vorab :)

@tobiasbettmann
Copy link

tobiasbettmann commented Apr 22, 2025

viii. Ab hier müsst ihr die Bildwerte anpassen, das hab ich selbst nur mit mühe und Not hinbekommen. Kann wer evtl die Anleitung weiterführen?
Das Bild wurde bei mir etwas klein und ich habe die ganzen Badges und das Bild rumgeschoben

Die Bildwerte müssen nicht angepasst werden.
Die Einrückungen müssen einfach genau wie in dem Template sein.
Dann funktioniert es direkt

@ForumSchlampe
Copy link

ForumSchlampe commented Apr 24, 2025

Kann bitte jemand erklären wie die Automation zum Setzten der ventcube_manuelle_luftstufe aussieht? Danke vorab :)

hänge das an das ende der modbus_wgt.yaml mit dran.

automation BIC_VentCube:      
- id: 'auto.ventcube_manuelle_luftstufe'
  alias: VentCube Manuelle Luftstufe Auswahlfeld
  triggers:
  - entity_id:
    - sensor.ventcube_manuelle_luftstufe
    id: input
    to:
    trigger: state
  - entity_id:
    - input_select.ventcube_manuelle_luftstufe
    id: select
    to:
    trigger: state
  conditions: []
  actions:
  - choose:
    - conditions:
      - condition: trigger
        id: input
      sequence:
      - variables:
          index: '{{ trigger.to_state.state | int(0) }}'
      - data:
          option: '{{ state_attr("input_select.ventcube_manuelle_luftstufe", "options")[
            index ] }}'
        target:
          entity_id: input_select.ventcube_manuelle_luftstufe
        action: input_select.select_option
    - conditions:
      - condition: trigger
        id: select
      sequence:
      - data_template:
          address: 101
          slave: 1
          hub: BIC_VentCube
          value:
          - '{{ trigger.to_state.state[0] | int(0) }}'
        action: modbus.write_register
  mode: queued
  max: 3
- id: 'auto..ventcube_betriebsart'
  alias: VentCube Betriebsart Auswahlfeld
  description: ''
  triggers:
  - entity_id:
    - sensor.ventcube_betriebsart
    id: input
    to:
    trigger: state
  - entity_id:
    - input_select.ventcube_betriebsart
    id: select
    to:
    trigger: state
  conditions: []
  actions:
  - choose:
    - conditions:
      - condition: trigger
        id: input
      sequence:
      - variables:
          index: '{{ trigger.to_state.state | int(0) }}'
      - data:
          option: '{{ state_attr("input_select.ventcube_betriebsart", "options")[
            index ] }}'
        target:
          entity_id: input_select.ventcube_betriebsart
        action: input_select.select_option
    - conditions:
      - condition: trigger
        id: select
      sequence:
      - data_template:
          address: 100
          slave: 1
          hub: BIC_VentCube
          value:
          - '{{ trigger.to_state.state[0] | int(0) }}'
          - 0
        action: modbus.write_register
  mode: queued
  max: 5

Alternativ

  • Homeassistant UI aufrufen
  • Einstellungen
  • Automationen & Szenen
  • Automation erstellen
  • Neue Automation
  • Rechts oben auf die drei Punkte und in YAML Modus wechseln
  • Die Vorlagen @JavanXD reinwerfen (einzeln)
  • Fertig

Ich bin neu mit HA unterwegs und verstehe nicht ganz warum er es nicht in seine yaml direkt mit aufgenommen hat, das könnte eventuell jemand anderes oder direkt javan aufklären aber beide Wege funktionieren.

@cutzenfriend
Copy link

image Danke Dir für das tolle Bild! So sieht's bei mir aktuell aus.

@JavanXD würfest du die Yaml für dieses Dashboard teilen? :) das wäre super lieb

@cutzenfriend
Copy link

Hier mal meine Visualisierung im Tag- & Nachtmodus:

Bildschirmfoto 2024-08-20 um 20 53 58

Würdest du eventuell auch dein YAML Code für das dashboard teilen?

@DaniS81
Copy link

DaniS81 commented May 27, 2025

Hello ;)

für mich ist das mit Modus und Co noch relatives Neuland. Habe jetzt aber im Grunde die Schritte wie beschrieben ausgeführt. Bekomme jedoch bei "Entwicklerwerkzeuge" -> "YAML" bei Konfiguration prüfen folgende Fehlermeldung.

Konfigurationswarnungen
Invalid config for 'modbus' at configuration.yaml, line 12: 'input_select' is an invalid option for 'modbus', check: modbus->0->input_select
Invalid config for 'modbus' at configuration.yaml, line 12: 'modbus' is an invalid option for 'modbus', check: modbus->0->modbus
Invalid config for 'modbus' at configuration.yaml, line 12: 'sensor' is an invalid option for 'modbus', check: modbus->0->sensor
Invalid config for 'modbus' at configuration.yaml, line 12: 'template' is an invalid option for 'modbus', check: modbus->0->template
Invalid config for 'modbus' at configuration.yaml, line 12: required key 'baudrate' not provided
Invalid config for 'modbus' at configuration.yaml, line 12: required key 'bytesize' not provided
Invalid config for 'modbus' at configuration.yaml, line 12: required key 'method' not provided
Invalid config for 'modbus' at configuration.yaml, line 12: required key 'parity' not provided
Invalid config for 'modbus' at configuration.yaml, line 12: required key 'port' not provided
Invalid config for 'modbus' at configuration.yaml, line 12: required key 'stopbits' not provided
Invalid config for 'modbus' at configuration.yaml, line 12: required key 'type' not provided

Hat jemand ne Idee und kann mir hier weiterhelfen? Danke vorab
Grüße
Dani

@NoIdeaForUsernameNow
Copy link

Hallo zusammen,
aktuell läuft bei mir fast alles seht gut, nur leider funktioniert die manuelle Auswahl der Betriebsart & Luftstufe nicht.
Gibt es hier einen separaten Code für für Auswahl Drop-Down-Liste ? Wie muss das konfiguriert werden ?
WGT_manuell

@philipp-bender
Copy link

Hallo zusammen, aktuell läuft bei mir fast alles seht gut, nur leider funktioniert die manuelle Auswahl der Betriebsart & Luftstufe nicht. Gibt es hier einen separaten Code für für Auswahl Drop-Down-Liste ? Wie muss das konfiguriert werden ?

In Home Assistant kannst du nicht direkt in einen modbus sensor schreiben, da sensors grundsätzlich nur lesend arbeiten.
Um einen Wert an ein Modbus-Gerät zu schreiben, musst du stattdessen eine modbus.write_register -Service-Call verwenden – entweder in einer Automation, einem Script oder über eine UI-Button-Action.

Siehe den Kommentar von @ForumSchlampe https://gist.github.com/JavanXD/a3e8911e69f3a27a81eeeb80414bb6ab?permalink_comment_id=5554989#gistcomment-5554989

@Till85apr
Copy link

Till85apr commented Sep 26, 2025

Hi Javan, fettes Dankeschön erstmal für die Mühe hier alles niederzuschreiben.
Ich hab jetzt erstmal deine YAML Codes in meine HA Installation importiert und das meiste funktioniert soweit schon ganz gut.
Ich habe auch dank der verlinkten Dokumentationen zu weiteren Modbus Adressen die Climates für die anderen Räume ergänzen können.

Was bei mir aber nicht funktioniert, ist die Übersetzung mancher Zustände:
{1797DC56-F47C-46C2-BADB-1FE8E3FBFBA4}

Auch der Status der WP (wir haben die WRG134BP/HK, nicht den VentCube) funktioniert auf die gleiche Weise nicht.
Obwohl der numerische Sensorwert korrekt angezeigt wird und die Übersetzungstabelle natürlich diesen Wert übersetzen müsste, ist der Template-Sensor in beiden Fällen dauerhaft auf "UNKNOWN".
wgt_betriebsart_text oder wgt_bypass_zustand_text funktionieren dagegen wie gewollt. Ich verstehe es nicht.
Der Code funktioniert weder 1:1 von dir kopiert, noch wenn ich ihn von einem der funktionierenden Abschnitte kopiere und inhaltlich abändere...

      wgt_status_waermepumpe_text:
        unique_id: wgt_status_waermepumpe_text
        friendly_name: "WGT Status Wärmepumpe"
        value_template: >
          {% set mapper = {
            '0': 'Aus',
            '5': 'WP Heizen',
            '49': 'WP Kühlen'} %}
          {% set state = states.sensor.wgt_status_waermepumpe.state %}
          {{ mapper[state] if state in mapper else 'Unknown' }}

      wgt_heizen_kuehlen_text:
        unique_id: wgt_heizen_kuehlen_text
        friendly_name: "WGT Status Heiz-Kühlfunktion"
        value_template: >
          {% set mapper = {
            '0': 'Aus',
            '1': 'Heizen',
            '2': 'Kühlen',
            '3': 'Auto T-Außen',
            '4': 'Auto Digitaleingang'} %}
          {% set state =  states.sensor.wgt_heiz_kuehlfunktion.state %}
          {{ mapper[state] if state in mapper else 'Unknown' }}

Weißt du woran es liegen könnte?

Und noch eine Frage: Die Climates funktionieren zwar für alle Räume, aber im Dashboard verstehe ich die Thermostat-Anzeige so, dass auf dem Regler die Solltemperatur eingestellt werden soll und darunter klein die IST-Temperatur dargestellt werden soll. Letzteres stimmt aber nicht. Hier wird der Status auf derselben Adresse abgegriffen, also auch die im System hinterlegte Soll-Temperatur. Die IST-Temperaturen müssten anstatt auf den Adressen 400...416 auf den Adressen 360...374 liegen. Aber wie kriege ich diese Werte in die Anzeige?

Beispiel unten: Solltemp ist 21°. Ist-Temp aber 22°C.
{942A2EFF-000F-4BD7-A8C8-E03374278338}

@tobse91
Copy link

tobse91 commented Sep 26, 2025

Bei mir das selbe Problem,

sensor.ventcube_bypass_zustand_text sensor.ventcube_status_geblaese_abluft_text sensor.ventcube_status_geblaese_zuluft_text sensor.ventcube_status_stosslueftung_text sensor.ventcube_status_waermepumpe_text

werden alle als unknown angezeigt.

sensor.ventcube_zustand_aussenklappe_text sensor.ventcube_status_vorheizregister_text sensor.ventcube_status_nachheizregister_text sensor.ventcube_betriebsart_text

Funktionieren hingegen einwandfrei.

Konnte im Code leider auch keinen Fehler entdecken.

@Till85apr
Copy link

Till85apr commented Sep 27, 2025

Und noch eine Frage: Die Climates funktionieren zwar für alle Räume, aber im Dashboard verstehe ich die Thermostat-Anzeige so, dass auf dem Regler die Solltemperatur eingestellt werden soll und darunter klein die IST-Temperatur dargestellt werden soll. Letzteres stimmt aber nicht. Hier wird der Status auf derselben Adresse abgegriffen, also auch die im System hinterlegte Soll-Temperatur. Die IST-Temperaturen müssten anstatt auf den Adressen 400...416 auf den Adressen 360...374 liegen. Aber wie kriege ich diese Werte in die Anzeige?

Beispiel unten: Solltemp ist 21°. Ist-Temp aber 22°C. {942A2EFF-000F-4BD7-A8C8-E03374278338}

Immerhin, dazu hab ich jetzt selbst einen Fix gefunden:
Und zwar ist es falsch für address und target_temp_register dieselbe Addresse zu setzen.
Stattdessen sollte für eine ordnungsgemäße Eintitätsanzeige als Thermostat im Dashboard bei "address" eine aus der Ist-Temperatur Range gewählt werden. Außerdem die Precision auf 1 statt 0.

- name: "Soll-Temperatur Raum 1"
      unique_id: ventcube_soll_temperatur_raum1
      slave: 1
      address: 360
      max_temp: 30
      min_temp: 10
      offset: 0
      precision: 1
      scale: 0.1
      target_temp_register: 400
      target_temp_write_registers: true
      temp_step: 1
      temperature_unit: °C

So sieht das dann aus:
{9F1494D4-AE79-449F-B818-00CD4970C4D0}

@Till85apr
Copy link

Till85apr commented Sep 27, 2025

Bei mir das selbe Problem,

sensor.ventcube_bypass_zustand_text sensor.ventcube_status_geblaese_abluft_text sensor.ventcube_status_geblaese_zuluft_text sensor.ventcube_status_stosslueftung_text sensor.ventcube_status_waermepumpe_text

werden alle als unknown angezeigt.

sensor.ventcube_zustand_aussenklappe_text sensor.ventcube_status_vorheizregister_text sensor.ventcube_status_nachheizregister_text sensor.ventcube_betriebsart_text

Funktionieren hingegen einwandfrei.

Konnte im Code leider auch keinen Fehler entdecken.

Juhuuu! Ich hab es dank Google Gemini geschafft.
Und zwar scheint HA manchmal abweichende Entitäts-IDs zu erstellen. Das muss man über Entwicklerwerkzeuge -> Zustände mit dem Code des Templates abgleichen. Da kommt es scheinbar manchmal zu einem Mismatch und dann fragt der Template Code einen Entitätszustand ab, der nicht existiert.
Konkretes Beispiel bei mir:
a) im YAML Code hinterlegt für den Sensor Heiz-Kühlfunktion ist
unique_id: wgt_heiz_kuehlfunktion

b) im Template wird auf denselben Namen aufgerufen
{%`` set state = states.sensor.wgt_heiz_kuehlfunktion.state %}

Das funktioniert aber nicht, da die Entität anders heißt, nämlich ohne das e:
{AC8294AF-B4A6-4686-AA1C-520B4970B1CF}

Wieso HA das so manchmal macht, ist mir schleierhaft. Vielleicht hat die unique_id aber auch nichts mit dem Entitätsnamen zu tun. Wie der dann generiert wird, ist mir aber auch unklar. Bei Korrektur von b) auf folgendes funktioniert das Template dann aber wie gewollt:
{%`` set state = states.sensor.wgt_heiz_kuhlfunktion.state %}

@AntonWeber93
Copy link

Hallo zusammen, ich bin ziemlich neu in der HA Welt. Wie habt ihr die einzelnen Räume wie Kinderzimmer, Wohnzimmer usw. im HA integriert?

Wäre es generell möglich hier eine Automation o.ä. zu erstellen mit PV?
Es wird geheizt wenn PV den Wert X erreicht und somit die Wärmepumpe mit Zusatzheizung angeht?

@Till85apr
Copy link

Hallo zusammen, ich bin ziemlich neu in der HA Welt. Wie habt ihr die einzelnen Räume wie Kinderzimmer, Wohnzimmer usw. im HA integriert?

Wäre es generell möglich hier eine Automation o.ä. zu erstellen mit PV? Es wird geheizt wenn PV den Wert X erreicht und somit die Wärmepumpe mit Zusatzheizung angeht?

Prinzipiell ist in HA so ziemlich alles möglich sofern man die Werkzeuge dazu hat (Sensordaten und Co). Das heißt du musst das Smart-Meter der PV einbinden und dort die Werte abgreifen. Davon abhängig kannst du dann die Wärmepumpe sowie die ZH im Haus aktivieren lassen und bei Erreichen einer bestimmten Temperatur, oder wenn der HV-Batteriespeicher einen bestimmte Ladezustand unterschreitet, wieder ausschalten.
Hab ich aber bislang selber noch nicht gemacht. PV fehlt derzeit noch. Aber wenn es soweit ist, setze ich mich erstmal daran, den PV-Überschuss dem Heizstab von der elco zu spendieren. Legionellenschutz und so, über SGready aktivieren.

@bbbenjie
Copy link

bbbenjie commented Nov 23, 2025

Hallo zusammen,
danke an @Maigus2510 für den Link zum Gist und euch allen für die Vorarbeiten sowie das Teilen eurer Konfiguration 👍
Ich konnte mich zwischenzeitlich an die Integration unserer VentCube Fresh machen und habe für unseren HA einige Änderungen an der ursprünglichen Quelle vorgenommen, aber auch die input_selects optimiert, die Status in Text überführen und den ausgewählten Wert rückübermitteln, sodass man keine Animationen mehr dafür benötigt. Auch die führenden Nummern (bspw. "3 - Stufe 3") sind entfallen.

Damit ich Werte nicht doppelt und dreifach definieren muss (bspw. die Lüftungsstufen, die an mehreren Sensoren/Selects vorkommen), habe ich Jinja-Templates (Makros) geschrieben, die man in einer Datei in "custom_templates" ablegt.

Hier ein paar markante Unterschiede zu den o.g. Konfigurationen:

  • unique_ids von Deutsch in Englisch übersetzt -> Persönliche Geschmackssache
  • input_select -> Template select (aufgrund der Trigger und select_option, siehe Beschreibung unten)
  • Luftstufe -> Lüftungsstufe und ein paar andere Anpassungen
  • Neue Adressen/Sensoren eingeführt (aus der oben schon referenzierten ioBroker-Quelle) – auch teilweise welche, die mich nicht betreffen (bspw. Erdwärmetauscher), da bin ich vielleicht etwas pedantisch 😄
  • An den Template-Selects setze ich außerdem default_entity_id ein, damit die vorgegebene ID auch tatsächlich so von Home Assistant übernommen wird (siehe Doku; gilt nur solange, wie es noch keine Entität mit diesem Namen gibt). Hilft, wenn man sich darauf verlassen muss, dass sich zwei Entitäten finden.
[...]
select:
  - name: VentCube Betriebsart
    default_entity_id: select.ventcube_operation_mode
    unique_id: ventcube_operation_mode
[...]

Beispiel-Screenshots:
grafik
grafik
grafik

⚠️ Achtung: Wir haben eine LWWP und nutzen die Lüftungsanlage nur als solche, haben an der VentCube Fresh also keine Einzelraumsteuerung. Mein Eintrag "VentCube Temperatur Wohnzimmer IST" ist daher ein "VentCube Ist-Temperatur Hauptbedienteil". Ein Vergleich mit eurer eigenen Konfiguration sollte daher unbedingt gemacht werden, bevor etwas übernommen wird, was auf euch nicht zutrifft. ⚠️


Der vielleicht spannendste Teil: Die Zusammenführung der Input-Selects mit den Animationen

Hier ein Beispiel:

template:
  - triggers:
      - trigger: state
        entity_id: sensor.ventcube_operation_mode
    select:
      - name: VentCube Betriebsart
        default_entity_id: select.ventcube_operation_mode
        unique_id: ventcube_operation_mode
        icon: mdi:fan
        state: >
          {% from 'schwoererhaus_ventcube_fresh.jinja' import ventcube_operation_mode as func %}
          {{ func('map', 'sensor.ventcube_operation_mode') }}
        options: >
          {% from 'schwoererhaus_ventcube_fresh.jinja' import ventcube_operation_mode as func %}
          {{ func('values') }}
        select_option:
          - action: modbus.write_register
            data:
              hub: SchwoererHaus_VentCube_Fresh
              slave: 1
              address: 100
              value: >
                {% from 'schwoererhaus_ventcube_fresh.jinja' import ventcube_operation_mode as func %}
                {{ [func('revmap', option) | int] }}
  - triggers:
    [...]

Sowohl für den aktuellen state, die verfügbaren options als auch die Logik zur Kommunikation mit Modbus via select_option greife ich auf ein Jinja-Makro zurück, das ich via {% from 'schwoererhaus_ventcube_fresh.jinja' import ventcube_operation_mode as func %} lade.
ventcube_operation_mode variiert, das Macro lade ich jedoch immer mit dem Namen func, damit ich nur beim Import den Template-Namen setzen muss und später nur noch auf func(...) zurückgreifen brauche.

Folgende Werte nimmt func(...) für den ersten Parameter an:

Logik Beschreibung Beispiel
map Mappt den Wert eines Modbus-Sensors mit einem lesbaren Wert – ohne führende Nummer! func('map', 'sensor.ventcube_operation_mode')
values Gibt alle lesbaren Werte der Map als Liste aus func('values')
revmap "Reverse Map", d.h. nach Auswahl eines lesbaren Werts (stellt HA als option-Variable zur Verfügung), Bestimmung der Nummer, damit die an Modbus geht; da das eine String-Map ist, muss eine String-Nummer zwingend zu Int gecastet werden! Man beachte auch das Array in Jinja, das als YAML-Liste an die Modbus Action geht. [func('revmap', option) | int]

Für die Sensoren, bei denen der Wert nur angezeigt, aber nicht geändert werden kann (da das dazugehörige Register nur gelesen, aber nicht beschrieben werden kann), habe ich das Mapping weiterhin als reguläre Selects mit Mapping in der YAML umgesetzt.


Da die UI manche Dinge noch nicht abbildet, findet bei mir alles weiterhin in einem Package + der Template-Datei statt, die ich mit euch teilen möchte:

packages/schwoererhaus_ventcube_fresh.yaml

modbus:
  - name: SchwoererHaus_VentCube_Fresh
    delay: 2
    timeout: 3
    type: tcp
    host: IP-GOES-HERE
    port: 502
    sensors:
      - name: VentCube Betriebsart
        unique_id: ventcube_operation_mode
        slave: 1
        address: 100
        # Controllable with template select
      - name: VentCube Manuelle Lüftungsstufe
        unique_id: ventcube_manual_ventilation_level
        slave: 1
        address: 101
        # Controllable with template select
      - name: VentCube Aktuelle Lüftungsstufe
        unique_id: ventcube_current_ventilation_level
        slave: 1
        address: 102
        # Translated with template sensor
      - name: VentCube Manuelle Lineare Luftleistung
        unique_id: ventcube_manual_linear_air_troughput
        slave: 1
        address: 103
        # Controllabe with number template
      - name: VentCube Status Lüftungsstufen-Überschreibung
        unique_id: ventcube_manual_ventilation_level_override_state
        slave: 1
        address: 104
        # Translated with template binary_sensor
      - name: VentCube Lüftungsstufen-Überschreibung
        unique_id: ventcube_manual_ventilation_level_override
        slave: 1
        address: 110
        # Translated with template sensor
      - name: VentCube Status Stoßlüftung
        unique_id: ventcube_shock_ventilation_state
        slave: 1
        address: 111
        # Controllable as switch
      - name: VentCube Restlaufzeit Stoßlüftung
        unique_id: ventcube_shock_ventilation_remaining_time
        slave: 1
        address: 112
        unit_of_measurement: min
        device_class: duration
        min_value: 0
        max_value: 60
      - name: VentCube Status Wärmepumpe
        unique_id: ventcube_heat_pump_state
        slave: 1
        address: 114
        # Translated with template sensor
      - name: VentCube Status Nachheizregister (NHR)
        unique_id: ventcube_post_heating_register_state
        slave: 1
        address: 116
        # Translated with template sensor
      - name: VentCube Status Gebläse Zuluft
        unique_id: ventcube_inlet_air_ventilation_state
        slave: 1
        address: 117
        # Translated with template sensor
      - name: VentCube Status Gebläse Abluft
        unique_id: ventcube_exhaust_air_ventilation_state
        slave: 1
        address: 118
        # Translated with template sensor
      - name: VentCube Status Erdwärmetauscher (EWT)
        unique_id: ventcube_ground_coupled_heat_exchanger
        slave: 1
        address: 121
        # Translated with template sensor
      - name: VentCube Zustand Bypass
        unique_id: ventcube_bypass_state
        slave: 1
        address: 123
        # Translated with template sensor
      - name: VentCube Zustand Außenklappe
        unique_id: ventcube_exterior_hatch_state
        slave: 1
        address: 131
        # Translated with template sensor
      - name: VentCube Status Vorheizregister (VHR)
        unique_id: ventcube_pre_heating_register_state
        slave: 1
        address: 133
        # Translated with template sensor
      - name: VentCube Lüftungsstufe Zeitprogramm
        unique_id: ventcube_ventilation_level_schedule
        slave: 1
        address: 140
        # Translated with template sensor
      - name: VentCube Lüftungs-Sensoren
        unique_id: ventcube_ventilation_level_sensors
        slave: 1
        address: 141
        # Translated with template sensor
        ################################################## To be verified
      - name: VentCube aktuelle Luftleistung Zuluft
        unique_id: ventcube_inlet_air_throughput
        slave: 1
        address: 142
        state_class: measurement
        unit_of_measurement: "%"
        min_value: 0
        max_value: 100
        scale: 1
        precision: 0
      - name: VentCube aktuelle Luftleistung Abluft
        unique_id: ventcube_exhaust_air_throughput
        slave: 1
        address: 143
        state_class: measurement
        unit_of_measurement: "%"
        min_value: 0
        max_value: 100
        scale: 1
        precision: 0
      - name: VentCube aktuelle Drehzahl Zuluft
        unique_id: ventcube_inlet_air_current_rpm
        slave: 1
        address: 144
        state_class: measurement
        unit_of_measurement: "rpm"
        min_value: 0
        max_value: 10000
        precision: 0
      - name: VentCube aktuelle Drehzahl Abluft
        unique_id: ventcube_exhaust_air_current_rpm
        slave: 1
        address: 145
        state_class: measurement
        unit_of_measurement: "rpm"
        min_value: 0
        max_value: 10000
        precision: 0
      - name: VentCube T1 Temperatur nach Erdwärmetauscher (EWT)
        unique_id: ventcube_t1_temperature_after_ground_coupled_heat_exchanger
        slave: 1
        address: 200
        unit_of_measurement: °C
        device_class: temperature
        scale: 0.1
        precision: 1
      - name: VentCube T2 Temperatur nach Vorheizregister
        unique_id: ventcube_t2_temperature_after_pre_heating_register
        slave: 1
        address: 201
        unit_of_measurement: °C
        device_class: temperature
        scale: 0.1
        precision: 1
      - name: VentCube T3 Temperatur vor Nacherwärmung (NE)
        unique_id: ventcube_t3_temperature_before_energy_recovery
        slave: 1
        address: 202
        unit_of_measurement: °C
        device_class: temperature
        scale: 0.1
        precision: 1
      - name: VentCube T4 Temperatur nach Nacherwärmung (NE)
        unique_id: ventcube_t4_temperature_after_energy_recovery
        slave: 1
        address: 203
        unit_of_measurement: °C
        device_class: temperature
        scale: 0.1
        precision: 1
      - name: VentCube T5 Temperatur Abluft
        unique_id: ventcube_t5_temperature_exhaust_air
        slave: 1
        address: 204
        unit_of_measurement: °C
        device_class: temperature
        scale: 0.1
        precision: 1
      - name: VentCube T6 Temperatur im Wärmetauscher
        unique_id: ventcube_t6_temperature_heat_exchanger
        slave: 1
        address: 205
        unit_of_measurement: °C
        device_class: temperature
        scale: 0.1
        precision: 1
      - name: VentCube T7 Temperatur Verdampfer
        unique_id: ventcube_t7_temperature_vaporizer
        slave: 1
        address: 206
        unit_of_measurement: °C
        device_class: temperature
        scale: 0.1
        precision: 1
      - name: VentCube T8 Temperatur Kondensator
        unique_id: ventcube_t8_temperature_capacitor
        slave: 1
        address: 207
        unit_of_measurement: °C
        device_class: temperature
        scale: 0.1
        precision: 1
      - name: VentCube T10 Temperatur Außen
        unique_id: ventcube_t10_temperature_outside
        slave: 1
        address: 209
        unit_of_measurement: °C
        device_class: temperature
        scale: 0.1
        precision: 1
      - name: VentCube Heiz-/Kühlfunktion
        unique_id: ventcube_heating_cooling_function
        slave: 1
        address: 230
        # Controllable with template select
      - name: VentCube Status Wärmepumpe Heizen
        unique_id: ventcube_heat_pump_state_heating
        slave: 1
        address: 231
        # Controllable as switch
      - name: VentCube Status Wärmepumpe Kühlen
        unique_id: ventcube_heat_pump_state_cooling
        slave: 1
        address: 232
        # Controllable as switch
      - name: VentCube Status Zusatzheizung Haus
        unique_id: ventcube_auxiliary_heating_house_state
        slave: 1
        address: 234
        # Controllable as switch
      - name: VentCube Fehlermeldung
        unique_id: ventcube_error_message
        slave: 1
        address: 240
        # Translated with template sensor
      - name: VentCube Meldung Druckwächter aktiv
        unique_id: ventcube_pressure_controller_state
        slave: 1
        address: 242
        # Translated with template binary_sensor
      - name: VentCube Meldung EVU-Sperre aktiv
        unique_id: ventcube_psc_lock_state
        slave: 1
        address: 243
        # Translated with template binary_sensor
      - name: VentCube Wartungstür offen
        unique_id: ventcube_maintenance_door_open
        slave: 1
        address: 244
        # Translated with template binary_sensor
      - name: VentCube Gerätefilter verschmutzt
        unique_id: ventcube_device_filter_polluted
        slave: 1
        address: 245
        # Translated with template binary_sensor
      - name: VentCube vorgelagerter Filter verschmutzt
        unique_id: ventcube_upstream_filter_polluted
        slave: 1
        address: 246
        # Translated with template binary_sensor
      - name: VentCube Niedertarif (NT) abgeschaltet
        unique_id: ventcube_off_peak_tariff_inactive
        slave: 1
        address: 247
        # Translated with template binary_sensor
      - name: VentCube Versorgungsspannung abgeschaltet
        unique_id: ventcube_supply_voltage_off
        slave: 1
        address: 248
        # Translated with template binary_sensor
      - name: VentCube Druckwächter ausgelöst
        unique_id: ventcube_pressure_controller_triggered
        slave: 1
        address: 250
        # Translated with template binary_sensor
      - name: VentCube Meldung EVU-Sperre Extern aktiv
        unique_id: ventcube_psc_external_lock_state
        slave: 1
        address: 251
        # Translated with template binary_sensor
      - name: VentCube Meldung Heizmodul Testbetrieb aktiv
        unique_id: ventcube_heating_module_test_mode_state
        slave: 1
        address: 252
        # Translated with template binary_sensor
      - name: VentCube Notbetrieb aktiv
        unique_id: ventcube_emergency_mode_state
        slave: 1
        address: 253
        # Translated with template binary_sensor
      - name: VentCube Zuluft zu kalt
        unique_id: ventcube_inlet_air_too_cold
        slave: 1
        address: 254
        # Translated with template binary_sensor
      - name: VentCube Restlaufzeit vorgelagerter Filter
        unique_id: ventcube_upstream_filter_majurity_time
        slave: 1
        address: 263
        unit_of_measurement: d
        min_value: 0
        max_value: 255
        device_class: duration
      - name: VentCube Restlaufzeit Gerätefilter
        unique_id: ventcube_device_filter_majurity_time
        slave: 1
        address: 265
        unit_of_measurement: d
        min_value: 0
        max_value: 255
        device_class: duration
      - name: VentCube Ist-Temperatur Hauptbedienteil
        unique_id: ventcube_main_control_unit_temperature_current
        slave: 1
        unit_of_measurement: °C
        device_class: temperature
        address: 360
        scale: 0.1
        precision: 1
        min_value: -50
        max_value: 100
        # Readable via template climate
      - name: VentCube Soll-Temperatur Hauptbedienteil
        unique_id: ventcube_main_control_unit_temperature_target
        slave: 1
        unit_of_measurement: °C
        device_class: temperature
        address: 400
        scale: 0.1
        precision: 1
        min_value: 10
        max_value: 30
        # Controllable via template climate
      - name: VentCube Grund-Temperatur Hauptbedienteil
        unique_id: ventcube_main_control_unit_temperature_base
        slave: 1
        unit_of_measurement: °C
        device_class: temperature
        address: 420
        scale: 0.1
        precision: 1
        min_value: 10
        max_value: 30
        # Controllabe with template number
      - name: VentCube Freigabe Zusatzheizung Hauptbedienteil
        unique_id: ventcube_main_control_unit_auxiliary_heating_state
        slave: 1
        address: 440
        # Controllable as switch
      - name: VentCube Freigabe Zeitprogramm Heizen Hauptbedienteil
        unique_id: ventcube_main_control_unit_schedule_enabled
        slave: 1
        address: 500
        # Controllable as switch
      - name: VentCube Betriebsstunden Lüfter Gesamt
        unique_id: ventcube_fan_operating_hours_total
        slave: 1
        address: 800
        unit_of_measurement: h
        device_class: duration
      - name: VentCube Betriebsstunden Lüfter Stufe 1
        unique_id: ventcube_fan_operating_hours_level1
        slave: 1
        address: 801
        unit_of_measurement: h
        device_class: duration
      - name: VentCube Betriebsstunden Lüfter Stufe 2
        unique_id: ventcube_fan_operating_hours_level2
        slave: 1
        address: 802
        unit_of_measurement: h
        device_class: duration
      - name: VentCube Betriebsstunden Lüfter Stufe 3
        unique_id: ventcube_fan_operating_hours_level3
        slave: 1
        address: 803
        unit_of_measurement: h
        device_class: duration
      - name: VentCube Betriebsstunden Lüfter Stufe 4
        unique_id: ventcube_fan_operating_hours_level4
        slave: 1
        address: 804
        unit_of_measurement: h
        device_class: duration
      - name: VentCube Betriebsstunden Wärmepumpe
        unique_id: ventcube_heat_pump_operating_hours
        slave: 1
        address: 805
        unit_of_measurement: h
        device_class: duration
      - name: VentCube Betriebsstunden Wärmepumpe Kühlen
        unique_id: ventcube_heat_pump_operating_hours_cooling
        slave: 1
        address: 806
        unit_of_measurement: h
        device_class: duration
      - name: VentCube Betriebsstunden Vorheizregister (VHR)
        unique_id: ventcube_pre_heating_register_operating_hours
        slave: 1
        address: 809
        unit_of_measurement: h
        device_class: duration
      - name: VentCube Betriebsstunden Zusatzheizung Raum
        unique_id: ventcube_auxiliary_heating_operating_hours
        slave: 1
        address: 810
        unit_of_measurement: h
        device_class: duration
      - name: VentCube Betriebsstunden Erdwärmetauscher (EWT)
        unique_id: ventcube_ground_coupled_heat_exchanger_operating_hours
        slave: 1
        address: 813
        unit_of_measurement: h
        device_class: duration
    switches:
      - name: VentCube Stoßlüftung
        unique_id: ventcube_shock_ventilation_switch
        slave: 1
        address: 111
        command_on: 0x1 # Aktiv
        command_off: 0x0 # Inaktiv
        write_type: holdings
        verify:
          input_type: holding
          state_on: 0x1
          state_off: 0x0
          delay: 5
      - name: VentCube Freigabe Wärmepumpe Heizen
        unique_id: ventcube_heat_pump_switch_heating
        slave: 1
        address: 231
        command_on: 0x1 # Freigabe
        command_off: 0x0 # Gesperrt
        write_type: holdings
        verify:
          input_type: holding
          state_on: 0x1
          state_off: 0x0
          delay: 5
      - name: VentCube Freigabe Wärmepumpe Kühlen
        unique_id: ventcube_heat_pump_switch_cooling
        slave: 1
        address: 232
        command_on: 0x1 # Freigabe
        command_off: 0x0 # Gesperrt
        write_type: holdings
        verify:
          input_type: holding
          state_on: 0x1
          state_off: 0x0
          delay: 5
      - name: VentCube Freigabe Zusatzheizung Haus
        unique_id: ventcube_auxiliary_heating_house
        slave: 1
        address: 234
        command_on: 0x1 # Freigabe
        command_off: 0x0 # Gesperrt
        write_type: holdings
        verify:
          input_type: holding
          state_on: 0x1
          state_off: 0x0
          delay: 5
      - name: VentCube Freigabe Zusatzheizung Hauptbedienteil
        unique_id: ventcube_main_control_unit_auxiliary_heating
        slave: 1
        address: 440
        command_on: 0x1 # Freigabe
        command_off: 0x0 # Gesperrt
        write_type: holdings
        verify:
          input_type: holding
          state_on: 0x1
          state_off: 0x0
          delay: 5
      - name: VentCube Freigabe Zeitprogramm Heizen Hauptbedienteil
        unique_id: ventcube_main_control_unit_schedule
        slave: 1
        address: 500
        command_on: 0x1 # Freigabe
        command_off: 0x0 # Gesperrt
        write_type: holdings
        verify:
          input_type: holding
          state_on: 0x1
          state_off: 0x0
          delay: 5
    climates:
      - name: "VentCube Temperatursteuerung Hauptbedienteil"
        unique_id: ventcube_climate_main_control_unit
        slave: 1
        address: 360
        max_temp: 30
        min_temp: 10
        offset: 0
        precision: 0
        scale: 0.1
        target_temp_register: 400
        target_temp_write_registers: true
        temp_step: 1
        temperature_unit: °C

template:
  - triggers:
      - trigger: state
        entity_id: sensor.ventcube_operation_mode
    select:
      - name: VentCube Betriebsart
        default_entity_id: select.ventcube_operation_mode
        unique_id: ventcube_operation_mode
        icon: mdi:fan
        state: >
          {% from 'schwoererhaus_ventcube_fresh.jinja' import ventcube_operation_mode as func %}
          {{ func('map', 'sensor.ventcube_operation_mode') }}
        options: >
          {% from 'schwoererhaus_ventcube_fresh.jinja' import ventcube_operation_mode as func %}
          {{ func('values') }}
        select_option:
          - action: modbus.write_register
            data:
              hub: SchwoererHaus_VentCube_Fresh
              slave: 1
              address: 100
              value: >
                {% from 'schwoererhaus_ventcube_fresh.jinja' import ventcube_operation_mode as func %}
                {{ [func('revmap', option) | int] }}
  - triggers:
      - trigger: state
        entity_id: sensor.ventcube_manual_ventilation_level
    select:
      - name: VentCube Manuelle Lüftungsstufe
        default_entity_id: select.ventcube_manual_ventilation_level
        unique_id: ventcube_manual_ventilation_level
        icon: mdi:fan
        state: >
          {% from 'schwoererhaus_ventcube_fresh.jinja' import ventcube_manual_ventilation_level as func %}
          {{ func('map', 'sensor.ventcube_manual_ventilation_level') }}
        options: >
          {% from 'schwoererhaus_ventcube_fresh.jinja' import ventcube_manual_ventilation_level as func %}
          {{ func('values') }}
        select_option:
          - action: modbus.write_register
            data:
              hub: SchwoererHaus_VentCube_Fresh
              slave: 1
              address: 101
              value: >
                {% from 'schwoererhaus_ventcube_fresh.jinja' import ventcube_manual_ventilation_level as func %}
                {{ [func('revmap', option) | int] }}
  - triggers:
      - trigger: state
        entity_id: sensor.ventcube_manual_linear_air_troughput
    number:
      - name: VentCube Manuelle Lineare Luftleistung
        default_entity_id: number.ventcube_manual_linear_air_troughput
        unique_id: ventcube_manual_linear_air_troughput
        icon: mdi:fan
        state: "{{ states('sensor.ventcube_manual_linear_air_troughput') if has_value('sensor.ventcube_manual_linear_air_troughput') }}"
        unit_of_measurement: "%"
        set_value:
          - action: modbus.write_register
            data:
              hub: SchwoererHaus_VentCube_Fresh
              slave: 1
              address: 103
              value: "{{ [value] }}"
        step: 1
        min: 30
        max: 100
  - triggers:
      - trigger: state
        entity_id: sensor.ventcube_manual_linear_air_troughput
    number:
      - name: VentCube Grund-Temperatur Hauptbedienteil
        default_entity_id: number.ventcube_main_control_unit_temperature_base
        unique_id: ventcube_main_control_unit_temperature_base
        icon: mdi:thermometer
        state: "{{ states('sensor.ventcube_main_control_unit_temperature_base') if has_value('sensor.ventcube_main_control_unit_temperature_base') }}"
        unit_of_measurement: °C
        set_value:
          - action: modbus.write_register
            data:
              hub: SchwoererHaus_VentCube_Fresh
              slave: 1
              address: 420
              value: "{{ [value] }}"
        step: 0.1
        min: 10
        max: 30
  - triggers:
      - trigger: state
        entity_id: sensor.ventcube_heating_cooling_function
    select:
      - name: VentCube Heiz-/Kühlfunktion
        default_entity_id: select.ventcube_heating_cooling_function
        unique_id: ventcube_heating_cooling_function
        icon: mdi:hvac
        state: >
          {% from 'schwoererhaus_ventcube_fresh.jinja' import ventcube_heating_cooling_function as func %}
          {{ func('map', 'sensor.ventcube_heating_cooling_function') }}
        options: >
          {% from 'schwoererhaus_ventcube_fresh.jinja' import ventcube_heating_cooling_function as func %}
          {{ func('values') }}
        select_option:
          - action: modbus.write_register
            data:
              hub: SchwoererHaus_VentCube_Fresh
              slave: 1
              address: 230
              value: >
                {% from 'schwoererhaus_ventcube_fresh.jinja' import ventcube_heating_cooling_function as func %}
                {{ [func('revmap', option) | int] }}
  - sensor:
      - name: VentCube Aktuelle Lüftungsstufe
        default_entity_id: sensor.ventcube_current_ventilation_level_text
        unique_id: ventcube_current_ventilation_level_text
        state: >
          {% set map = {
            '0': 'Aus',
            '1': 'Stufe 1',
            '2': 'Stufe 2',
            '3': 'Stufe 3',
            '4': 'Stufe 4',
            '5': 'Automatik',
            '6': 'Linearbetrieb'} %}
          {% set state = states.sensor.ventcube_current_ventilation_level.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Lüftungsstufen-Überschreibung
        default_entity_id: sensor.ventcube_manual_ventilation_level_override_text
        unique_id: ventcube_manual_ventilation_level_override_text
        state: >
          {% set map = {
            '0': 'Aus',
            '1': 'Stufe 1',
            '2': 'Stufe 2',
            '3': 'Stufe 3',
            '4': 'Stufe 4',
            '5': 'Automatik',
            '6': 'Linearbetrieb'} %}
          {% set state = states.sensor.ventcube_manual_ventilation_level_override.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Status Wärmepumpe
        default_entity_id: sensor.ventcube_heat_pump_state_text
        unique_id: ventcube_heat_pump_state_text
        state: >
          {% set map = {
            '0': 'Aus',
            '5': 'WP Heizen',
            '49': 'WP Kühlen'} %}
          {% set state = states.sensor.ventcube_heat_pump_state.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Status Nachheizregister (NHR)
        default_entity_id: sensor.ventcube_post_heating_register_state_text
        unique_id: ventcube_post_heating_register_state_text
        state: >
          {% set map = {
            '0': 'Inaktiv',
            '1': 'Aktiv'} %}
          {% set state = states.sensor.ventcube_post_heating_register_state.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Status Gebläse Zuluft
        default_entity_id: sensor.ventcube_inlet_air_ventilation_state_text
        unique_id: ventcube_inlet_air_ventilation_state_text
        state: >
          {% set map = {
            '0': 'Deaktiviert',
            '1': 'Anlaufphase',
            '2': 'Aktiv',
            '5': 'Standby',
            '6': 'Fehler'} %}
          {% set state = states.sensor.ventcube_inlet_air_ventilation_state.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Status Gebläse Abluft
        default_entity_id: sensor.ventcube_exhaust_air_ventilation_state_text
        unique_id: ventcube_exhaust_air_ventilation_state_text
        state: >
          {% set map = {
            '0': 'Deaktiviert',
            '1': 'Anlaufphase',
            '2': 'Aktiv',
            '5': 'Standby',
            '6': 'Fehler'} %}
          {% set state = states.sensor.ventcube_exhaust_air_ventilation_state.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Status Erdwärmetauscher (EWT)
        default_entity_id: sensor.ventcube_ground_coupled_heat_exchanger_text
        unique_id: ventcube_ground_coupled_heat_exchanger_text
        state: >
          {% set map = {
            '0': 'EWT aus/geschlossen',
            '1': 'EWT im Heizbetrieb aktiv',
            '2': 'EWT im Kühlbetrieb aktiv'} %}
          {% set state = states.sensor.ventcube_ground_coupled_heat_exchanger.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Zustand Bypass
        default_entity_id: sensor.ventcube_bypass_state_text
        unique_id: ventcube_bypass_state_text
        state: >
          {% set map = {
            '0': 'Geschlossen',
            '1': 'Offen (Kühlen)',
            '2': 'Offen (Heizen)'} %}
          {% set state = states.sensor.ventcube_bypass_state.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Zustand Außenklappe
        default_entity_id: sensor.ventcube_exterior_hatch_state_text
        unique_id: ventcube_exterior_hatch_state_text
        state: >
          {% set map = {
            '0': 'Geschlossen',
            '1': 'Offen'} %}
          {% set state = states.sensor.ventcube_exterior_hatch_state.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Status Vorheizregister (VHR)
        default_entity_id: sensor.ventcube_pre_heating_register_state_text
        unique_id: ventcube_pre_heating_register_state_text
        state: >
          {% set map = {
            '0': 'Aus',
            '1': 'VHR 1 Aktiv',
            '2': 'VHR 2 Aktiv',
            '3': 'VHR 1+2 Aktiv'} %}
          {% set state = states.sensor.ventcube_pre_heating_register_state.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Lüftungsstufe Zeitprogramm
        default_entity_id: sensor.ventcube_ventilation_level_schedule_text
        unique_id: ventcube_ventilation_level_schedule_text
        state: >
          {% set map = {
            '0': 'Aus',
            '1': 'Stufe 1',
            '2': 'Stufe 2',
            '3': 'Stufe 3',
            '4': 'Stufe 4'} %}
          {% set state = states.sensor.ventcube_ventilation_level_schedule.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Lüftungs-Sensoren
        default_entity_id: sensor.ventcube_ventilation_level_sensors_text
        unique_id: ventcube_ventilation_level_sensors_text
        state: >
          {% set map = {
            '0': 'Aus',
            '1': 'Stufe 1',
            '2': 'Stufe 2',
            '3': 'Stufe 3',
            '4': 'Stufe 4'} %}
          {% set state = states.sensor.ventcube_ventilation_level_sensors.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Fehlermeldung
        default_entity_id: sensor.ventcube_error_message_text
        unique_id: ventcube_error_message_text
        state: >
          {% set map = {
            '0': 'Kein Fehler',
            '257': 'Drehzahl Zuluft fehlt',
            '258': 'Drehzahl Abluft fehlt',
            '259': 'Ventilator Zuluft Mindestdrehzahl nicht erreicht',
            '260': 'Ventilator Abluft Mindestdrehzahl nicht erreicht',
            '261': 'Ventilator Zuluft max. Drehzahl überschritten',
            '262': 'Ventilator Abluft max. Drehzahl überschritten',
            '513': 'Kommunikationsfehler zur BDE',
            '514': 'Kommunikationsfehler Nebenbedieneinheit',
            '515': 'Kommunikationsfehler Heizmodul',
            '516': 'Kommunikationsfehler Sensor',
            '517': 'Kommunikationsfehler Sensor-Adapter',
            '518': 'Kommunikation Empfänger',
            '770': 'Fehler Sensorelement T1-nach-Ewt',
            '771': 'Fehler Sensorelement T2-nach-Vhr',
            '772': 'Fehler Sensorelement T3-vor-Nhr',
            '773': 'Fehler Sensorelement T4-nach-Nhr',
            '774': 'Fehler Sensorelement T5-Abluft',
            '775': 'Fehler Sensorelement T6-im-WT',
            '776': 'Fehler Sensorelement T7-Verdampfer',
            '777': 'Fehler Sensorelement T8-Kondensator',
            '779': 'Fehler Sensorelement T10-Außentemperatur',
            '1025': 'Fehler Parameterspeicher',
            '1026': 'Fehler System-Bus',
            '1281': 'Wärmepumpe Hochdruck',
            '1282': 'Wärmepumpe Niederdruck',
            '1283': 'Maximal Abtauzeit überschritten',
            '1284': 'Wärmepumpe Niederdruck im Kühlbetrieb',
            '1796': 'Vorheizregister keine Funktion'} %}
          {% set state = states.sensor.ventcube_error_message.state %}
          {{ map[state] if state in map else 'Unknown' }}
  - binary_sensor:
      - name: VentCube Status Lüftungsstufen-Überschreibung
        default_entity_id: binary_sensor.ventcube_manual_ventilation_level_override_state_text
        unique_id: ventcube_manual_ventilation_level_override_state_text
        state: >
          {% set map = {
            '0': 'off',
            '1': 'on'} %}
          {% set state = states.sensor.ventcube_manual_ventilation_level_override_state.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Meldung Druckwächter aktiv
        default_entity_id: binary_sensor.ventcube_pressure_controller_state_text
        unique_id: ventcube_pressure_controller_state_text
        device_class: problem
        state: >
          {% set map = {
            '0': 'off',
            '1': 'on'} %}
          {% set state = states.sensor.ventcube_pressure_controller_state.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: "VentCube Meldung EVU-Sperre aktiv"
        default_entity_id: binary_sensor.ventcube_psc_lock_state_text
        unique_id: ventcube_psc_lock_state_text
        device_class: problem
        state: >
          {% set map = {
            '0': 'off',
            '1': 'on'} %}
          {% set state = states.sensor.ventcube_psc_lock_state.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Wartungstür offen
        default_entity_id: binary_sensor.ventcube_maintenance_door_open_text
        unique_id: ventcube_maintenance_door_open_text
        device_class: problem
        state: >
          {% set map = {
            '0': 'off',
            '1': 'on'} %}
          {% set state = states.sensor.ventcube_maintenance_door_open.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Gerätefilter verschmutzt
        default_entity_id: binary_sensor.ventcube_device_filter_polluted_text
        unique_id: ventcube_device_filter_polluted_text
        device_class: problem
        state: >
          {% set map = {
            '0': 'off',
            '1': 'on'} %}
          {% set state = states.sensor.ventcube_device_filter_polluted.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube vorgelagerter Filter verschmutzt
        default_entity_id: binary_sensor.ventcube_upstream_filter_polluted_text
        unique_id: ventcube_upstream_filter_polluted_text
        device_class: problem
        state: >
          {% set map = {
            '0': 'on',
            '1': 'off'} %}
          {% set state = states.sensor.ventcube_upstream_filter_polluted.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Niedertarif (NT) abgeschaltet
        default_entity_id: binary_sensor.ventcube_off_peak_tariff_inactive_text
        unique_id: ventcube_off_peak_tariff_inactive_text
        state: >
          {% set map = {
            '0': 'off',
            '1': 'on'} %}
          {% set state = states.sensor.ventcube_off_peak_tariff_inactive.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Versorgungsspannung abgeschaltet
        default_entity_id: binary_sensor.ventcube_supply_voltage_off_text
        unique_id: ventcube_supply_voltage_off_text
        device_class: problem
        state: >
          {% set map = {
            '0': 'off',
            '1': 'on'} %}
          {% set state = states.sensor.ventcube_supply_voltage_off.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Druckwächter ausgelöst
        default_entity_id: binary_sensor.ventcube_pressure_controller_triggered_text
        unique_id: ventcube_pressure_controller_triggered_text
        device_class: problem
        state: >
          {% set map = {
            '0': 'off',
            '1': 'on'} %}
          {% set state = states.sensor.ventcube_pressure_controller_triggered.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Meldung EVU-Sperre Extern aktiv
        default_entity_id: binary_sensor.ventcube_psc_external_lock_state_text
        unique_id: ventcube_psc_external_lock_state
        device_class: problem
        state: >
          {% set map = {
            '0': 'off',
            '1': 'on'} %}
          {% set state = states.sensor.ventcube_psc_external_lock_state.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Meldung Heizmodul Testbetrieb aktiv
        default_entity_id: binary_sensor.ventcube_heating_module_test_mode_state_text
        unique_id: ventcube_heating_module_test_mode_state_text
        device_class: problem
        state: >
          {% set map = {
            '0': 'off',
            '1': 'on'} %}
          {% set state = states.sensor.ventcube_heating_module_test_mode_state.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: VentCube Notbetrieb aktiv
        default_entity_id: binary_sensor.ventcube_emergency_mode_state_text
        unique_id: ventcube_emergency_mode_state_text
        device_class: problem
        state: >
          {% set map = {
            '0': 'off',
            '1': 'on'} %}
          {% set state = states.sensor.ventcube_emergency_mode_state.state %}
          {{ map[state] if state in map else 'Unknown' }}
      - name: "VentCube Zuluft zu kalt"
        default_entity_id: binary_sensor.ventcube_inlet_air_too_cold_text
        unique_id: ventcube_inlet_air_too_cold_text
        device_class: problem
        state: >
          {% set map = {
            '0': 'off',
            '1': 'on'} %}
          {% set state = states.sensor.ventcube_inlet_air_too_cold.state %}
          {{ map[state] if state in map else 'Unknown' }}

custom_templates/schwoererhaus_ventcube_fresh.jinja

{%- macro _ventcube_logic(map, type, value) %}
  {%- if type == 'values' %}
    {{- map.values() | list }}
  {%- elif type == 'map' %}
    {%- set state = states(value) %}
    {{- map[state] if state in map else 'Unknown' }}
  {%- elif type == 'revmap' %}
    {%- set ns = namespace(list=[]) %}
    {%- for key, value in map.items() %}
      {%- set ns.list = ns.list + [(value, key)] %}
    {%- endfor %}
    {%- set revmap = dict.from_keys(ns.list) %}
    {{- revmap[value] if value in revmap else 0 }}
  {%- else %}
  {%- endif %}
{%- endmacro %}

{%- macro ventcube_operation_mode(type, value) %}
  {%- set map = {
    '0': 'Aus',
    '1': 'Handbetrieb',
    '2': 'Winterbetrieb',
    '3': 'Sommerbetrieb',
    '4': 'Sommer Abluft'} %}
  {{- _ventcube_logic(map, type, value) }}
{%- endmacro %}

{%- macro ventcube_manual_ventilation_level(type, value) %}
  {%- set map = {
    '0': 'Aus',
    '1': 'Stufe 1',
    '2': 'Stufe 2',
    '3': 'Stufe 3',
    '4': 'Stufe 4',
    '5': 'Automatik',
    '6': 'Linearbetrieb'} %}
  {{- _ventcube_logic(map, type, value) }}
{%- endmacro %}

{%- macro ventcube_heating_cooling_function(type, value) %}
  {%- set map = {
    '0': 'Aus',
    '1': 'Heizen',
    '2': 'Kühlen',
    '3': 'Auto T-Außen',
    '4': 'Auto Digitaler Eingang'} %}
  {{- _ventcube_logic(map, type, value) }}
{%- endmacro %}

Viele Grüße
Benjamin

@Markus1010RT
Copy link

Hi zusammen,

Das ist ja der Wahnsinn, was ihr hier auf die Beine gestellt habt.
Ich habe bereits fleißig bei euch abgekupfert und die modbus Integration so weit zum laufen gebracht.
Ich bekomme allerdings nach wie vor die Meldung "unbekannt" bei eigentlich allen Entitäten angezeigt.
Ich hab die mappings bereits geprüft und alle Namen passen zueinander.
Auch der Zugriff auf das wgt Steuerteil an sich müsste funktionieren.
Hat jemand, bei dem auch nur "unknown" zurück kam einen heißen Tipp wo ich noch suchen könnte?

@tobse91
Copy link

tobse91 commented Nov 26, 2025

Hallo zusammen, danke an @Maigus2510 für den Link zum Gist und euch allen für die Vorarbeiten sowie das Teilen eurer Konfiguration 👍 Ich konnte mich zwischenzeitlich an die Integration unserer VentCube Fresh machen und habe für unseren HA einige Änderungen an der ursprünglichen Quelle vorgenommen, aber auch die input_selects optimiert, die Status in Text überführen und den ausgewählten Wert rückübermitteln, sodass man keine Animationen mehr dafür benötigt. Auch die führenden Nummern (bspw. "3 - Stufe 3") sind entfallen.

Damit ich Werte nicht doppelt und dreifach definieren muss (bspw. die Lüftungsstufen, die an mehreren Sensoren/Selects vorkommen), habe ich Jinja-Templates (Makros) geschrieben, die man in einer Datei in "custom_templates" ablegt.

Hier ein paar markante Unterschiede zu den o.g. Konfigurationen:

* unique_ids von Deutsch in Englisch übersetzt -> Persönliche Geschmackssache

* input_select -> Template select (aufgrund der Trigger und `select_option`, siehe Beschreibung unten)

* Luftstufe -> Lüftungsstufe und ein paar andere Anpassungen

* Neue Adressen/Sensoren eingeführt (aus der oben schon referenzierten [ioBroker-Quelle](https://github.com/Excodibur/ioBroker.schwoerer-ventcube/blob/master/src/lib/schwoerer/parameters.ts)) – auch teilweise welche, die mich nicht betreffen (bspw. Erdwärmetauscher), da bin ich vielleicht etwas pedantisch 😄

* An den Template-Selects setze ich außerdem `default_entity_id` ein, damit die vorgegebene ID auch tatsächlich so von Home Assistant übernommen wird (siehe Doku; gilt nur solange, wie es noch keine Entität mit diesem Namen gibt). Hilft, wenn man sich darauf verlassen muss, dass sich zwei Entitäten finden.
[...]
select:
  - name: VentCube Betriebsart
    default_entity_id: select.ventcube_operation_mode
    unique_id: ventcube_operation_mode
[...]

Viele Grüße Benjamin

Das ist echt sehr gut, vielleicht lohnt es sich ein eigenes Repo oder Fork zu erstellen?

Danke für deine Arbeit. Werde ich testen.

@bbbenjie
Copy link

bbbenjie commented Nov 28, 2025

Vielen Dank für euer Feedback!

@tobse91, an das Repo dachte ich auch schon, um zumindest Änderungen besser nachvollziehen zu können. Aktuell bin ich wieder mit ganz anderen Dingen in HA beschäftigt, d.h. größere Änderungen meinerseits stehen nicht an.

@Markus1010RT, das klingt nach dem "Henne-Ei-Problem", das ich bei mir hatte:
Sobald ich meine Template-Entitäten via Entwicklerwerkzeuge neu geladen hatte, sind sie auf Unknown zurückgesprungen. Das betrifft folgende Einschränkung seitens Home Assistant:

The state, including attributes, of trigger-based sensors and binary sensors is restored when Home Assistant is restarted. The state of other trigger-based template entities is not restored.
Quelle: https://www.home-assistant.io/integrations/template/#trigger-based-template-entities

In diesem Fall hilft es, direkt nach dem Neuladen der Template-Entitäten die Modbus-Entitäten ebenfalls neu zu laden ("Modbus"-Eintrag in den Entwicklerwerkzeugen, bzw. "modbus.reload" als Aktion). Gilt auch bei HA-Neustarts.
Ich habe mir dafür eine Animation geschrieben, die mir das abnimmt:

alias: Modbus neu laden bei HAOS-Neustart und Neuladen von Template-Entitäten
description: ""
triggers:
  - trigger: homeassistant
    event: start
  - trigger: event
    event_type: event_template_reloaded
conditions: []
actions:
  - action: modbus.reload
    metadata: {}
    data: {}
mode: single

Vielleicht trifft es das beschriebene Problem? Ich bin gespannt.

@Markus1010RT
Copy link

Hi,

also ich habe es heute mal mit dem neu laden des modbus versucht, aber nach wie vor sieht es eher schlecht aus.

Screenshot 2025-11-28 201524

Was mich auch ein wenig wundert ist, dass ich alles doppelt und dreifach habe :D ich vermute aber, das kommt von meinen diversen versuchen des neu hinzufuegens der modbus integration.

Ich hab die Einstellungen am Bedienteil auch nochmals geprüft. die ip stimmt und modbus tcp ist auch aktviert

@bbbenjie
Copy link

Hi @Markus1010RT, danke dir.
Nur um sicher zu gehen: Ich gehe davon aus, du hast deine VentCube nach Aktivieren von Modbus via TCP/IP neugestartet? Hier im Thread steht was von Sicherung raus/rein, aber es geht auch per Schwörer-Bedienteil: Solange man sich noch im Service-Modus befindet -> Einstellungen -> Grundeinstellungen -> 11. Datensatz verwalten -> 6. Geräte Neustart Leistungsteil; ich habe sicherheitshalber auch "7. Geräte Neustart BT-S2" ausgeführt.

Ich konnte mich direkt nach Aktivieren von Modbus TCP/IP auf einem Unix-Betriebssystem via netcat davon überzeugen, dass der Port nun offen ist (via nc -vz <ip> 502, also bspw. nc -vz 192.168.1.123 502). Eben nochmal getestet, erhalte ich mittlerweile nur noch einen Connection Timeout, obwohl sich HA weiterhin erfolgreich verbinden kann. Wenn du per netcat eine erfolgreiche Verbindung aufbauen kannst, prima! Beim Ergebnis "Connection Timeout" stehen die Chancen jedoch 50:50.
Du kannst aber auch mit Modbus-Tools prüfen, ob du einzelne Adressen abrufen kannst (oder, für Fortgeschrittene, wahlweise direkt per netcat mit Modbus kommunizieren). Dann hättest du wenigstens Gewissheit, ob es an HA oder der Lüftungsanlage liegt. Ich hatte mal Tools recherchiert, aber noch keines ausgetestet.

Ansonsten, was sagt Home Assistant zur Verbindung? Gibt es entsprechende Einträge im Log?
Andernfalls ggf. das Loglevel temporär hochdrehen, siehe https://www.home-assistant.io/integrations/modbus/ Kapitel "Opening an issue", und danach wahlweise HA neustarten oder die Modbus-YAML-Konfiguration neu laden.

@tobse91
Copy link

tobse91 commented Dec 4, 2025

@bbbenjie

Habe deine .yml und .jinja erstellt und die IP angepasst. Die Sensoren funktionieren als Zahl, aber leider nicht als Text:

grafik

Wenn die Zustände ausgelesen werden können wie man sieht, wieso werden die Text Sensoren nicht angezeigt?

Zudem kann ich bei den neuen Auswahlfeldern leider nichts auswählen:

grafik

Gruß Tobias

@bbbenjie
Copy link

bbbenjie commented Dec 4, 2025

Hi @tobse91,
nur um sicher zu gehen: ich gehe davon aus, dass die Macros unter /custom_templates/ abgelegt wurden und Home Assistant danach neugestartet wurde? So sieht die Struktur bei mir aus:

grafik

Du kannst die Funktionstüchtigkeit der Macros testen, indem du bspw. folgenden Schnipsel unter Entwicklerwerkzeuge > Template einfügst:

{% from 'schwoererhaus_ventcube_fresh.jinja' import ventcube_operation_mode as func %}
{{ func('values') }}

Erscheint dort folgende Ausgabe, können die Macros als Fehlerursache ausgeschlossen werden:
grafik

Da dein Dropdown leer ist, das genannte Macro aber die Listeneinträge für das betroffene Feld erzeugen soll, vermute ich die Fehlerursache an dieser Stelle.

Der Modbus-Sensor für die Betriebsart hat tatsächlich die ID "sensor.ventcube_operation_mode", wie vom Template-Select so erwartet?

Viele Grüße
Benjamin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment