Meine Lüftungsanlage hängt im Netzwerk. Das wusste ich ein ganzes Jahr lang nicht. Erst ein Servicetechniker hat mich bei der Wartung darauf hingewiesen. Die Hersteller-App hat leider nur Fehlermeldungen ausgespuckt, also habe ich mir den Laptop meiner Frau geschnappt, ihn per USB an den Service-Port der Anlage angeschlossen und in der Installateur-Software nachgeschaut. Siehe da: eine statische IP-Adresse, die gar nicht in meinem Netzwerkbereich lag. Das korrigiert, 10 Minuten später lief alles.
Dann wollte ich natürlich mehr. Die Lüftung rauscht nachts manchmal ein bisschen laut, und das wollte ich automatisieren. Über die Hersteller-App geht das leider nicht. Also habe ich mich mit Modbus beschäftigt, um die komplette Steuerung in Home Assistant zu bekommen. Das hat mich ein paar graue Haare gekostet, weil es im Internet kaum vernünftige Anleitungen dazu gab. Damit du dir die sparen kannst, findest du hier alles Schritt für Schritt.
Was ist Modbus?
Modbus ist eine Kommunikationsschnittstelle, mit der Geräte untereinander Daten austauschen. Du kannst damit Werte auslesen (aktuelle Lüftungsstufe, Temperaturen, CO2-Gehalt) und Werte schreiben (Betriebsmodus umschalten, Lüftungsstufe ändern). Das läuft über TCP/IP, also ganz normal übers Netzwerk. Home Assistant hat eine native Modbus-Integration, du brauchst keine externe Erweiterung.
Die Anleitung hier zeigt das am Beispiel einer Maico WS 300 Flat A. Andere Anlagen funktionieren genauso, du brauchst nur die passende Modbus-Registertabelle von deinem Hersteller.
Was du dafür brauchst
Bevor du loslegst, ein paar Voraussetzungen:
1. Die IP-Adresse deiner Lüftungsanlage. Die Anlage muss im lokalen Netzwerk erreichbar sein. Teste das am einfachsten mit einem Ping: Öffne ein Terminal (oder die Eingabeaufforderung unter Windows) und tippe ping 10.10.146.32 (deine IP natürlich einsetzen). Wenn du eine Antwort bekommst, ist die Anlage erreichbar. Falls nicht: Prüfe, ob eine statische IP vergeben ist, die nicht in deinem Netzwerkbereich liegt. Bei mir war genau das das Problem.
2. Die Modbus-Registertabelle deines Herstellers. Das ist ein Dokument (oft ein PDF), in dem der Hersteller alle Modbus-Adressen auflistet. So eine Tabelle hat typischerweise diese Spalten:
- Adresse/ID (z.B. 650) - die eindeutige Nummer, unter der ein Wert gespeichert ist
- Beschreibung (z.B. "Aktuelle Lüftungsstufe") - was der Wert bedeutet
- Berechtigung (Lesen/Schreiben) - ob du den Wert nur auslesen oder auch ändern darfst
- Datentyp (z.B. uint16) - wie der Wert gespeichert ist
- Wertebereich (z.B. 0-5) - welche Werte möglich sind, oft mit einer Legende (0 = Aus, 1 = Manuell, 2 = Auto-Zeit, ...)
Wichtig: Bei manchen Anlagen gibt es getrennte Adressen zum Lesen und zum Schreiben. Bei der Maico WS 300 ist z.B. Adresse 650 das Leseregister für die aktuelle Lüftungsstufe, aber Adresse 554 das Schreibregister, um die Lüftungsstufe zu ändern. Das steht in der Berechtigungs-Spalte der Tabelle.
3. Home Assistant mit Zugriff auf die Konfigurationsdateien (File Editor, Studio Code Server oder direkt per SSH).
Schritt 1: Modbus-Sensoren konfigurieren
Die Modbus-Konfiguration wird etwas länger. Ich empfehle dir, dafür eine eigene Datei im packages-Verzeichnis anzulegen, z.B. modbus.yaml. So bleibt deine configuration.yaml übersichtlich.
Falls du das packages-System noch nicht nutzt: Füge in deine configuration.yaml diese Zeile ein:
homeassistant:
packages: !include_dir_named packagesErstelle dann einen Ordner packages im selben Verzeichnis wie deine configuration.yaml. Alle YAML-Dateien, die du dort reinlegst, werden automatisch geladen.
Alternativ kannst du den gesamten Code auch direkt in deine configuration.yaml packen. Dann wird die Datei halt ein bisschen lang.
Hier ist die komplette Sensorkonfiguration für die KWL-Anlage. Lege diese Datei als packages/modbus.yaml an:
1modbus:
2 - name: ws300
3 type: tcp
4 host: 10.10.146.32 # Hier DEINE IP-Adresse eintragen
5 port: 502 # Standard-Port für Modbus TCP
6 sensors:
7 # Temperaturen (Adressen aus der Maico Registertabelle)
8 - name: "kwl_t_aul" # Außenluft-Temperatur
9 unit_of_measurement: °C
10 slave: 1
11 address: 703
12 input_type: holding
13 data_type: int16
14 precision: 1
15 scale: 0.1
16
17 - name: "kwl_t_zu" # Zuluft-Temperatur
18 unit_of_measurement: °C
19 slave: 1
20 address: 704
21 input_type: holding
22 data_type: int16
23 precision: 1
24 scale: 0.1
25
26 - name: "kwl_t_ab" # Abluft-Temperatur
27 unit_of_measurement: °C
28 slave: 1
29 address: 705
30 input_type: holding
31 data_type: int16
32 precision: 1
33 scale: 0.1
34
35 - name: "kwl_t_fol" # Fortluft-Temperatur
36 unit_of_measurement: °C
37 slave: 1
38 address: 706
39 input_type: holding
40 data_type: int16
41 precision: 1
42 scale: 0.1
43
44 # Betriebsdaten
45 - name: "kwl_betriebsart" # 0=Aus, 1=Manuell, 2=Auto-Zeit, 3=Auto-Sensor
46 slave: 1
47 address: 550
48 input_type: holding
49 data_type: uint16
50
51 - name: "kwl_lueftungsstufe" # 0=Aus, 1=Feuchteschutz, 2=Reduziert, 3=Nennlüftung, 4=Intensiv
52 slave: 1
53 address: 650
54 input_type: holding
55 data_type: uint16
56
57 # Drehzahlen und Volumenstrom
58 - name: "kwl_drehzahl_zu"
59 unit_of_measurement: "U/min"
60 slave: 1
61 address: 651
62 input_type: holding
63 data_type: uint16
64
65 - name: "kwl_drehzahl_ab"
66 unit_of_measurement: "U/min"
67 slave: 1
68 address: 652
69 input_type: holding
70 data_type: uint16
71
72 - name: "kwl_volumenstrom_zu"
73 unit_of_measurement: "m³/h"
74 slave: 1
75 address: 653
76 input_type: holding
77 data_type: uint16
78
79 - name: "kwl_volumenstrom_ab"
80 unit_of_measurement: "m³/h"
81 slave: 1
82 address: 654
83 input_type: holding
84 data_type: uint16
85
86 # Filterrestlaufzeiten (in Tagen)
87 - name: "kwl_restlaufzeit_filter_zu"
88 unit_of_measurement: "d"
89 slave: 1
90 address: 655
91 input_type: holding
92 data_type: uint16
93
94 - name: "kwl_restlaufzeit_filter_aul"
95 unit_of_measurement: "d"
96 slave: 1
97 address: 656
98 input_type: holding
99 data_type: uint16
100
101 - name: "kwl_restlaufzeit_filter_ab"
102 unit_of_measurement: "d"
103 slave: 1
104 address: 657
105 input_type: holding
106 data_type: uint16
107
108 # Luftqualität
109 - name: "kwl_rF_ab" # Relative Feuchte Abluft
110 unit_of_measurement: "%"
111 slave: 1
112 address: 750
113 input_type: holding
114 data_type: uint16
115
116 - name: "kwl_CO2" # CO2-Gehalt
117 unit_of_measurement: "ppm"
118 slave: 1
119 address: 755
120 input_type: holding
121 data_type: uint16
122
123 # Schaltzustände
124 - name: "kwl_schalt_zu" # Zuluftventilator
125 slave: 1
126 address: 800
127 input_type: holding
128 data_type: uint16
129
130 - name: "kwl_schalt_ab" # Abluftventilator
131 slave: 1
132 address: 801
133 input_type: holding
134 data_type: uint16
135
136 - name: "kwl_schalt_bypass" # Bypass-Klappe
137 slave: 1
138 address: 802
139 input_type: holding
140 data_type: uint16Die IP-Adresse bei host musst du auf deine Anlage anpassen. Den Port 502 kannst du in der Regel so lassen, das ist der Standard für Modbus TCP.
Woher kommen die Adressen? Aus der Modbus-Registertabelle von Maico. Adresse 703 ist dort als "Außenlufttemperatur" beschrieben, 704 als "Zulufttemperatur" und so weiter. Wenn du eine andere Anlage hast, schlag die passenden Adressen in deiner Registertabelle nach.
Schritt 2: Template-Sensoren für lesbare Werte
Die Modbus-Sensoren liefern dir erstmal nur Zahlen. Eine 3 bei der Betriebsart sagt dir ohne Tabelle gar nichts. Also brauchen wir Template-Sensoren, die diese Zahlen in lesbare Texte übersetzen.
Füge diesen Code in eine eigene Datei packages/sensors.yaml ein (oder ergänze eine bestehende):
1template:
2 - sensor:
3 - name: "KWL Betriebsmodus"
4 state: >
5 {% set mode = states('sensor.kwl_betriebsart') | int(0) %}
6 {% if mode == 0 %}Aus
7 {% elif mode == 1 %}Manuell
8 {% elif mode == 2 %}Auto-Zeit
9 {% elif mode == 3 %}Auto-Sensor
10 {% elif mode == 4 %}ECO Zuluft
11 {% elif mode == 5 %}ECO Abluft
12 {% else %}Unbekannt{% endif %}
13
14 - name: "KWL Lüftungsstufe"
15 state: >
16 {% set stufe = states('sensor.kwl_lueftungsstufe') | int(0) %}
17 {% if stufe == 0 %}Aus
18 {% elif stufe == 1 %}Feuchteschutz
19 {% elif stufe == 2 %}Reduziert
20 {% elif stufe == 3 %}Nennlüftung
21 {% elif stufe == 4 %}Intensiv
22 {% else %}Unbekannt{% endif %}
23
24 - name: "KWL Bypass"
25 state: >
26 {% set bypass = states('sensor.kwl_schalt_bypass') | int(0) %}
27 {% if bypass == 0 %}Zu
28 {% elif bypass == 1 %}Auf
29 {% else %}Unbekannt{% endif %}
30
31 - name: "KWL Wärmerückgewinnung"
32 unit_of_measurement: "%"
33 state: >
34 {% set t_ab = states('sensor.kwl_t_ab') %}
35 {% set t_aul = states('sensor.kwl_t_aul') %}
36 {% set t_zu = states('sensor.kwl_t_zu') %}
37 {% if t_ab in ['unavailable','unknown']
38 or t_aul in ['unavailable','unknown']
39 or t_zu in ['unavailable','unknown'] %}
40 0
41 {% else %}
42 {% set ab = t_ab | float(0) %}
43 {% set aul = t_aul | float(0) %}
44 {% set zu = t_zu | float(0) %}
45 {% if (ab - aul) != 0 %}
46 {{ (((zu - aul) / (ab - aul)) * 100) | round(0) }}
47 {% else %}
48 0
49 {% endif %}
50 {% endif %}Woher kommen die Werte für das Mapping? Wieder aus der Registertabelle. Bei Maico steht dort z.B. bei der Betriebsart: 0 = Aus, 1 = Manuell, 2 = Auto-Zeit, 3 = Auto-Sensor, 4 = ECO Zuluft, 5 = ECO Abluft. Diese Zuordnung habe ich einfach in die Template-Sensoren übernommen.
Die Wärmerückgewinnung berechnet sich aus den drei Temperaturen: (Zuluft - Außenluft) / (Abluft - Außenluft) * 100. Wenn die Anlage aus ist oder ein Sensor nicht verfügbar, gibt der Sensor einfach 0 zurück.
Schritt 3: Konfiguration prüfen und neu starten
Bevor du Home Assistant neu startest, prüfe erst, ob deine Konfiguration fehlerfrei ist. Das geht so:
- Öffne Home Assistant und gehe zu Einstellungen > System > Allgemein
- Klicke oben rechts auf die drei Punkte und wähle Konfiguration prüfen
- Warte, bis die Prüfung abgeschlossen ist
Wenn dort ein Fehler auftaucht, stimmt etwas in deiner YAML-Datei nicht. Meistens ist es ein Einrückungs-Fehler. YAML ist da wahnsinnig empfindlich.
Wenn die Prüfung erfolgreich war, klicke auf Neu starten. Ein schnelles Neuladen reicht hier leider nicht, weil die Modbus-Integration einen vollständigen Neustart braucht.
Schritt 4: Prüfen, ob die Sensoren da sind
Nach dem Neustart kontrollierst du, ob alles funktioniert hat:
- Gehe zu Entwicklerwerkzeuge > Zustände
- Tippe oben ins Suchfeld
kwlein - Du solltest jetzt alle Sensoren sehen, die du angelegt hast
Die Modbus-Sensoren (z.B. sensor.kwl_betriebsart) zeigen dir die rohen Zahlenwerte. Die Template-Sensoren (z.B. sensor.kwl_betriebsmodus) zeigen dir den übersetzten Text wie "Auto-Sensor" oder "Intensiv".
Wenn keine Sensoren auftauchen: Prüfe, ob die IP-Adresse stimmt und ob deine Anlage im Netzwerk erreichbar ist (Ping-Test, siehe oben). Schau auch ins Home Assistant Log unter Einstellungen > System > Protokolle, dort findest du Fehlermeldungen zur Modbus-Verbindung.
Schritt 5: Dashboard aufbauen
Jetzt wird es sichtbar. Gehe auf dein Dashboard, klicke auf die drei Punkte oben rechts, dann auf Dashboard bearbeiten und Karte hinzufügen.
Zuerst eine Entities-Karte, die dir alle wichtigen Werte auf einen Blick zeigt:
1type: entities
2title: Wohnraumlüftung
3entities:
4 - entity: sensor.kwl_t_aul
5 name: Außenluft
6 icon: mdi:thermometer
7 - entity: sensor.kwl_t_zu
8 name: Zuluft
9 icon: mdi:thermometer
10 - entity: sensor.kwl_t_ab
11 name: Abluft
12 icon: mdi:thermometer
13 - entity: sensor.kwl_t_fol
14 name: Fortluft
15 icon: mdi:thermometer
16 - type: divider
17 - entity: sensor.kwl_volumenstrom_zu
18 name: Volumenstrom Zuluft
19 icon: mdi:fan
20 - entity: sensor.kwl_volumenstrom_ab
21 name: Volumenstrom Abluft
22 icon: mdi:fan
23 - entity: sensor.kwl_drehzahl_zu
24 name: Drehzahl Zuluft
25 - entity: sensor.kwl_drehzahl_ab
26 name: Drehzahl Abluft
27 - type: divider
28 - entity: sensor.kwl_co2
29 name: CO2
30 icon: mdi:molecule-co2
31 - entity: sensor.kwl_rf_ab
32 name: Relative Feuchte Abluft
33 icon: mdi:water-percent
34 - type: divider
35 - entity: sensor.kwl_betriebsmodus
36 name: Betriebsmodus
37 icon: mdi:cog
38 - entity: sensor.kwl_lueftungsstufe_2
39 name: Lüftungsstufe
40 icon: mdi:fan
41 - entity: sensor.kwl_bypass
42 name: Bypass
43 icon: mdi:valve
44 - entity: sensor.kwl_warmeruckgewinnung
45 name: Wärmerückgewinnung
46 icon: mdi:heat-wave
47 - type: divider
48 - entity: sensor.kwl_restlaufzeit_filter_zu
49 name: Filter Zuluft (Tage)
50 icon: mdi:air-filter
51 - entity: sensor.kwl_restlaufzeit_filter_aul
52 name: Filter Außenluft (Tage)
53 icon: mdi:air-filter
54 - entity: sensor.kwl_restlaufzeit_filter_ab
55 name: Filter Abluft (Tage)
56 icon: mdi:air-filterUm diese Karte anzulegen: Klicke auf Karte hinzufügen, suche nach Manuell, klicke drauf und füge den YAML-Code per Copy & Paste ein.
Direkt darunter kommen die Steuerungs-Buttons. Die nutzen modbus.write_register, um Werte direkt an die Anlage zu schicken:
1type: horizontal-stack
2cards:
3 - type: button
4 name: Aus
5 icon: mdi:fan-off
6 show_name: true
7 show_icon: true
8 tap_action:
9 action: perform-action
10 perform_action: modbus.write_register
11 data:
12 address: 550
13 unit: 1
14 value:
15 - 0
16 hub: ws300
17
18 - type: button
19 name: Manuell
20 icon: mdi:fan
21 show_name: true
22 show_icon: true
23 tap_action:
24 action: perform-action
25 perform_action: modbus.write_register
26 data:
27 address: 550
28 unit: 1
29 value:
30 - 1
31 hub: ws300
32
33 - type: button
34 name: Auto-Sensor
35 icon: mdi:fan-auto
36 show_name: true
37 show_icon: true
38 tap_action:
39 action: perform-action
40 perform_action: modbus.write_register
41 data:
42 address: 550
43 unit: 1
44 value:
45 - 3
46 hub: ws300Und eine zweite Reihe für die Lüftungsstufen. Hier wird an eine andere Adresse geschrieben, weil Betriebsmodus (Adresse 550) und Lüftungsstufe (Adresse 554) bei der Maico getrennte Schreibregister sind:
1type: horizontal-stack
2cards:
3 - type: button
4 name: Feuchteschutz
5 icon: mdi:fan-speed-1
6 show_name: true
7 show_icon: true
8 tap_action:
9 action: perform-action
10 perform_action: modbus.write_register
11 data:
12 address: 554
13 unit: 1
14 value:
15 - 1
16 hub: ws300
17
18 - type: button
19 name: Nennlüftung
20 icon: mdi:fan-speed-2
21 show_name: true
22 show_icon: true
23 tap_action:
24 action: perform-action
25 perform_action: modbus.write_register
26 data:
27 address: 554
28 unit: 1
29 value:
30 - 3
31 hub: ws300
32
33 - type: button
34 name: Intensiv
35 icon: mdi:fan-speed-3
36 show_name: true
37 show_icon: true
38 tap_action:
39 action: perform-action
40 perform_action: modbus.write_register
41 data:
42 address: 554
43 unit: 1
44 value:
45 - 4
46 hub: ws300Den hub-Wert (ws300) musst du auf den Namen anpassen, den du oben in der Modbus-Konfiguration vergeben hast.
Nach einem Button-Klick dauert es ein paar Sekunden, bis sich die Werte im Dashboard aktualisieren. Das ist normal, die Modbus-Register werden nicht in Echtzeit abgefragt.
Schritt 6: Automatisierungen bauen
Wenn die Grundlagen stehen, kannst du anfangen, Automatisierungen zu bauen. Zwei Beispiele, die bei mir im Alltag laufen:
Leise lüften nachts: Um 22:30 Uhr schaltet die Anlage in den manuellen Modus und auf Feuchteschutz (die leiseste Stufe). Um 6:00 Uhr morgens geht sie zurück auf Auto-Sensor.
1alias: "Lüftung: Leise lüften"
2mode: single
3triggers:
4 - at: "22:30:00"
5 id: Nachtmodus
6 platform: time
7 - at: "06:00:00"
8 id: Auto-Modus
9 platform: time
10actions:
11 - choose:
12 - conditions:
13 - condition: trigger
14 id:
15 - Nachtmodus
16 sequence:
17 # Erst auf Manuell schalten (Betriebsmodus)
18 - action: modbus.write_register
19 data:
20 address: 550
21 unit: 1
22 value:
23 - 1
24 hub: ws300
25 # Dann Feuchteschutz-Stufe setzen (Lüftungsstufe)
26 - action: modbus.write_register
27 data:
28 address: 554
29 unit: 1
30 value:
31 - 1
32 hub: ws300
33 - conditions:
34 - condition: trigger
35 id:
36 - Auto-Modus
37 sequence:
38 # Morgens zurück auf Auto-Sensor
39 - action: modbus.write_register
40 data:
41 address: 550
42 unit: 1
43 value:
44 - 3
45 hub: ws300Du siehst hier, dass für die Nacht zwei Befehle nötig sind: Erst den Betriebsmodus auf Manuell (Adresse 550, Wert 1), dann die Stufe auf Feuchteschutz (Adresse 554, Wert 1). Morgens reicht ein einziger Befehl, weil Auto-Sensor sich die Stufe selbst regelt.
Stoßlüften nach dem Duschen: Wenn die Luftfeuchtigkeit im Bad über 60% steigt, schaltet die Anlage für 15 Minuten auf Intensiv. Danach geht sie je nach Tageszeit in den passenden Modus zurück.
1alias: "Lüftung: Stoßlüften nach Duschen"
2mode: single
3triggers:
4 - type: humidity
5 entity_id: sensor.DEIN_FEUCHTIGKEITSSENSOR # z.B. sensor.bad_humidity
6 above: 60
7 for:
8 minutes: 2
9 platform: device
10actions:
11 # Intensivlüftung starten
12 - action: modbus.write_register
13 data:
14 address: 554
15 unit: 1
16 value:
17 - 4
18 hub: ws300
19 # 15 Minuten warten
20 - delay:
21 minutes: 15
22 # Danach: je nach Tageszeit den richtigen Modus wiederherstellen
23 - choose:
24 # Nachts (22:00-06:00): zurück in den leisen Feuchteschutz
25 - conditions:
26 - condition: time
27 after: "22:00:00"
28 before: "06:00:00"
29 sequence:
30 - action: modbus.write_register
31 data:
32 address: 550
33 unit: 1
34 value:
35 - 1
36 hub: ws300
37 - action: modbus.write_register
38 data:
39 address: 554
40 unit: 1
41 value:
42 - 1
43 hub: ws300
44 # Tagsüber: zurück auf Auto-Sensor
45 - conditions:
46 - condition: time
47 after: "06:00:00"
48 before: "22:00:00"
49 sequence:
50 - action: modbus.write_register
51 data:
52 address: 550
53 unit: 1
54 value:
55 - 3
56 hub: ws300Den Platzhalter sensor.DEIN_FEUCHTIGKEITSSENSOR musst du durch die Entity-ID deines Feuchtigkeitssensors ersetzen. Die findest du wieder unter Entwicklerwerkzeuge > Zustände.
Was du noch wissen solltest
Lese- vs. Schreibregister: Bei der Maico sind die Adressen zum Lesen und Schreiben teilweise unterschiedlich. Die aktuelle Lüftungsstufe liest du über Adresse 650, aber zum Ändern schreibst du an Adresse 554. Das steht in der Berechtigungs-Spalte der Registertabelle. Wenn du eine andere Anlage hast, prüfe dort, welche Adressen Schreibrechte haben.
Eigene Buttons bauen: Du kannst dir beliebige weitere Buttons zusammenbauen. Schau in deine Registertabelle, welche Werte du wohin schreiben darfst. Zum Beispiel könntest du mit einem Button die Stoßlüftung starten oder den ECO-Modus aktivieren.
Weitere Sensoren auslesen: In der Registertabelle findest du noch viel mehr Werte, die du auslesen könntest, z.B. Betriebsstunden der Lüftung, Relais-Status der Nachheizung oder den Wärmetauscher-Status. Ergänze dafür einfach weitere Sensoren in deiner modbus.yaml nach dem gleichen Muster.
Hast du deine Lüftungsanlage auch in Home Assistant eingebunden, oder planst du das noch? Schreib gerne in die Kommentare, welche Anlage du nutzt und ob du irgendwo hängen geblieben bist.
