-
-
Save JavanXD/a3e8911e69f3a27a81eeeb80414bb6ab to your computer and use it in GitHub Desktop.
| # 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' }} | |
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?
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
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_textwerden alle als unknown angezeigt.
sensor.ventcube_zustand_aussenklappe_text sensor.ventcube_status_vorheizregister_text sensor.ventcube_status_nachheizregister_text sensor.ventcube_betriebsart_textFunktionieren 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:

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 %}
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?
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.


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_textwerden alle als unknown angezeigt.
sensor.ventcube_zustand_aussenklappe_text sensor.ventcube_status_vorheizregister_text sensor.ventcube_status_nachheizregister_text sensor.ventcube_betriebsart_textFunktionieren hingegen einwandfrei.
Konnte im Code leider auch keinen Fehler entdecken.