Haus entfeuchten oder runterkühlen – Dank openHAB und Daikin-binding einfach möglich…

Kürzlich habe ich über den Einbau einer Daikin-Klimaanlage sowie der Verknüpfung mit openHAB berichtet und hierfür nun erste Automatismen gebastelt.

Dabei waren mir folgende Anwendungsfälle wichtig:

  • Schnelles Herunterkühlen des Hauses für eine definierte Zeit – z.B. nach bzw. kurz vor Rückkehr aus dem Urlaub im Sommer mit maximaler Leistung
  • Schnelles Kühlen des Hauses für eine definierte Zeit auf die aktuell eingestellten Ziel-Temperaturen
  • Entfeuchten des Hauses ohne Kühlleistung bei zu hoher Luftfeuchtigkeit im Haus – z.B. nach einem Gewitter, Regen usw. i.V.m. mit Lüften und dann im Haus vorhandener zu feuchter Luft
  • In allen Szenarien soll dann automatisch der vorherige Modus aller Geräte wiederhergestellt werden (also Geräte z.B. wieder aus oder auf die zuvor eingestellten Settings stellen)

Umgesetzt habe ich das dann mit Szenen / Automatismen für die Klimaanlage. Wird eine „Szene“ ausgewählt, dann wird in zusätzlichen Sicherungs-Items der frühere Zustand je Gerät gespeichert und nach Ende der Ausführung wiederhergestellt. Da die Anzahl der verbauten Geräte sich nicht „mal schnell“ ändern wird, habe ich hier auf generische Regeln verzichtet und jedes Gerät entsprechend „hart kodiert“ angesprochen. Hier muss jeder das eben für sich anpassen…

items-Datei

// Allgemeine Items für Szene sowie Speicher, wenn eine Szene gerade "in Aktion" ist...
Number   szeneKlima                     "Szene Klimageräte"             <fan>
Number   szeneKlima_szeneInAktion

// Wohnzimmer
Switch DaikinACUnit_Wohnzimmer_Power_Backup
Number:Temperature DaikinACUnit_Wohnzimmer_SetPoint_Backup
String DaikinACUnit_Wohnzimmer_Mode_Backup
String DaikinACUnit_Wohnzimmer_Fan_Backup

// Analog weiter für jedes Gerät...

Weitere Werte als Backup mit hineinzunehmen erscheint mir aktuell nicht notwendig (auch mit Blick auf weitere, noch kommende Automatismen). Notfalls eben einfach ergänzen…

sitemap-Datei

In der Sitemap werden auswählbare Szenen definiert und sind dann als Auswahl anwählbar. Solange eine Szene läuft (außer es geht nur um ein „Alle Aus“ oder „Alle an“) wird sie nicht zurück auf „Keine Automatik-Szene“ gestellt, das erfolgt dann nach Abschluss des Cool-Downs oder des Entfeuchtens..

        Selection item=szeneKlima mappings=[0="Keine Automatik-Szene", 2="Alle Klimageräte AN", 3="Alle Klimageräte AUS", 4="Power-Klima 20min", 5="Power-CoolDown 18°C 20min", 1="Haus entfeuchten 45min"]

rules-Datei

In den Rules findet nun die Verarbeitung statt. Um für spätere weitere Regeln den Backup & Restore-Mechanismus für frühere Klimagerät-Status nicht redundant halten zu müssen habe ich das auch als Art Szene umgesetzt. Bitte davon nicht irritieren lassen 😉

Beim Start und auch beim Ende von länger laufenden Aktionen erfolgt zudem eine Text-To-Speech-Ansage über alle meine Alexa-Devices. Wer dazu mehr Infos braucht wird in diesem Artikel weiter fündig.

var boolean log = true
var String logPrefix = 'Klimaanlage.rules - '
rule "Szenen-Verwaltung Klima"
when
    Item szeneKlima received command
then
    if (log) logInfo('rules', logPrefix + 'Automatik gestartet')
    switch(receivedCommand) {
        case 0: { // Keine Szene - wenn noch Regel läuft, dann zurücksetzen auf vorherigen State
            if (szeneKlima_szeneInAktion.state != 0) {
                szeneKlima_szeneInAktion.sendCommand(0)
                if (log) logInfo('rules', logPrefix + 'Szene 0 - Restore letztes Backup vor letzter Regel...')
                // Zurücksetzen auf Werte vor Aufruf der Szene
                // -- Wohnzimmer
                DaikinACUnit_Wohnzimmer_Power.sendCommand(DaikinACUnit_Wohnzimmer_Power_Backup.state)
                DaikinACUnit_Wohnzimmer_SetPoint.sendCommand(DaikinACUnit_Wohnzimmer_SetPoint_Backup.state)
                DaikinACUnit_Wohnzimmer_Mode.sendCommand(DaikinACUnit_Wohnzimmer_Mode_Backup.state)
                DaikinACUnit_Wohnzimmer_Fan.sendCommand(DaikinACUnit_Wohnzimmer_Fan_Backup.state)
                // -- Schlafzimmer
                DaikinACUnit_Schlafzimmer_Power.sendCommand(DaikinACUnit_Schlafzimmer_Power_Backup.state)
                DaikinACUnit_Schlafzimmer_SetPoint.sendCommand(DaikinACUnit_Schlafzimmer_SetPoint_Backup.state)
                DaikinACUnit_Schlafzimmer_Mode.sendCommand(DaikinACUnit_Schlafzimmer_Mode_Backup.state)
                DaikinACUnit_Schlafzimmer_Fan.sendCommand(DaikinACUnit_Schlafzimmer_Fan_Backup.state)
                // -- Sonja
                DaikinACUnit_Sonja_Power.sendCommand(DaikinACUnit_Sonja_Power_Backup.state)
                DaikinACUnit_Sonja_SetPoint.sendCommand(DaikinACUnit_Sonja_SetPoint_Backup.state)
                DaikinACUnit_Sonja_Mode.sendCommand(DaikinACUnit_Sonja_Mode_Backup.state)
                DaikinACUnit_Sonja_Fan.sendCommand(DaikinACUnit_Sonja_Fan_Backup.state)
                // -- Simon
                DaikinACUnit_Simon_Power.sendCommand(DaikinACUnit_Simon_Power_Backup.state)
                DaikinACUnit_Simon_SetPoint.sendCommand(DaikinACUnit_Simon_SetPoint_Backup.state)
                DaikinACUnit_Simon_Mode.sendCommand(DaikinACUnit_Simon_Mode_Backup.state)
                DaikinACUnit_Simon_Fan.sendCommand(DaikinACUnit_Simon_Fan_Backup.state)
            } else {
                if (log) logInfo('rules', logPrefix + 'Szene 0 - Backup musste nicht wiederhergestellt werden, da zwischenzeitlich Szene-Wechsel erfolgte...')
            }
        }
        case 98: { // Speichern de aktuellen Werte für späteres Restore...
            if (log) logInfo('rules', logPrefix + 'Szene 99 - Backup aktueller Werte...')
            // Speichern der aktuellen Werte
            // -- Wohnzimmer
            DaikinACUnit_Wohnzimmer_Power_Backup.sendCommand(DaikinACUnit_Wohnzimmer_Power.state)
            DaikinACUnit_Wohnzimmer_SetPoint_Backup.sendCommand(DaikinACUnit_Wohnzimmer_SetPoint.state)
            DaikinACUnit_Wohnzimmer_Mode_Backup.sendCommand(DaikinACUnit_Wohnzimmer_Mode.state)
            DaikinACUnit_Wohnzimmer_Fan_Backup.sendCommand(DaikinACUnit_Wohnzimmer_Fan.state)
            // -- Schlafzimmer
            DaikinACUnit_Schlafzimmer_Power_Backup.sendCommand(DaikinACUnit_Schlafzimmer_Power.state)
            DaikinACUnit_Schlafzimmer_SetPoint_Backup.sendCommand(DaikinACUnit_Schlafzimmer_SetPoint.state)
            DaikinACUnit_Schlafzimmer_Mode_Backup.sendCommand(DaikinACUnit_Schlafzimmer_Mode.state)
            DaikinACUnit_Schlafzimmer_Fan_Backup.sendCommand(DaikinACUnit_Schlafzimmer_Fan.state)
            // -- Sonja
            DaikinACUnit_Sonja_Power_Backup.sendCommand(DaikinACUnit_Sonja_Power.state)
            DaikinACUnit_Sonja_SetPoint_Backup.sendCommand(DaikinACUnit_Sonja_SetPoint.state)
            DaikinACUnit_Sonja_Mode_Backup.sendCommand(DaikinACUnit_Sonja_Mode.state)
            DaikinACUnit_Sonja_Fan_Backup.sendCommand(DaikinACUnit_Sonja_Fan.state)
            // -- Simon
            DaikinACUnit_Simon_Power_Backup.sendCommand(DaikinACUnit_Simon_Power.state)
            DaikinACUnit_Simon_SetPoint_Backup.sendCommand(DaikinACUnit_Simon_SetPoint.state)
            DaikinACUnit_Simon_Mode_Backup.sendCommand(DaikinACUnit_Simon_Mode.state)
            DaikinACUnit_Simon_Fan_Backup.sendCommand(DaikinACUnit_Simon_Fan.state)
        }
        case 5: { // Power-Cool-Down: 20 Minuten volle Kühlleistung auf 18°C
            if (szeneKlima_szeneInAktion.state != 5) {
                if (log) logInfo('rules', logPrefix + 'Szene 5 - Power Cool-Down 18°C- Backup aktueller Werte')
                GENERIC_TTS_TEXT.postUpdate("Klimaautomatik - Power-Cool-Down 18°C für 20 Minuten gestartet")
                szeneKlima_szeneInAktion.sendCommand(5)
                szeneKlima.sendCommand(98) // Backup aktuelle Werte
                szeneKlima.sendCommand(5)
                Thread::sleep(1500) // etwas warten, damit auch 100%ig die alten Werte via Szene-98-Aufruf weggespeichert wurden...
                // Geräte ansteuern
                // -- Wohnzimmer
                DaikinACUnit_Wohnzimmer_Power.sendCommand(ON)
                DaikinACUnit_Wohnzimmer_Fan.sendCommand("LEVEL_5")
                DaikinACUnit_Wohnzimmer_Mode.sendCommand("COLD")
                DaikinACUnit_Wohnzimmer_SetPoint.sendCommand(18)
                // -- Schlafzimmer
                DaikinACUnit_Schlafzimmer_Power.sendCommand(ON)
                DaikinACUnit_Schlafzimmer_Fan.sendCommand("LEVEL_5")
                DaikinACUnit_Schlafzimmer_Mode.sendCommand("COLD")
                DaikinACUnit_Schlafzimmer_SetPoint.sendCommand(18)
                // -- Simon
                DaikinACUnit_Simon_Power.sendCommand(ON)
                DaikinACUnit_Simon_Fan.sendCommand("LEVEL_5")
                DaikinACUnit_Simon_Mode.sendCommand("COLD")
                DaikinACUnit_Simon_SetPoint.sendCommand(18)
                // -- Sonja
                DaikinACUnit_Sonja_Power.sendCommand(ON)
                DaikinACUnit_Sonja_Fan.sendCommand("LEVEL_5")
                DaikinACUnit_Sonja_Mode.sendCommand("COLD")
                DaikinACUnit_Sonja_SetPoint.sendCommand(18)

                // Warten...
                if (log) logInfo('rules', logPrefix + 'Szene 5 - Starte Timer...')
                createTimer(now.plusSeconds(60*20)) [|
                    if (log) logInfo('rules', logPrefix + 'Szene 5 - Timer beendet, setze Szene zurück...')
                    // Ende der Szene, sofern zwischenzeitlich manuell die Szene nicht beendet oder gewechselt wurde - Herstellen alter Werte erfolgt automatisch
                    szeneKlima.sendCommand(0)
                    GENERIC_TTS_TEXT.postUpdate("Klimaautomatik - Power Cool-Down 18°C wurde beendet")
                    ]
            } else {
                if (log) logInfo('rules', logPrefix + 'Szene 5 - ist bereits eingestellt!')
            }
        }
        case 4: { // Power-Klima: 20 Minuten volle Leistung auf aktuell eingestellte Temperatur
            if (szeneKlima_szeneInAktion.state != 4) {
                if (log) logInfo('rules', logPrefix + 'Szene 4 - Klima  - Backup aktueller Werte')
                GENERIC_TTS_TEXT.postUpdate("Klimaautomatik - Power-Klima für 20 Minuten gestartet")
                szeneKlima_szeneInAktion.sendCommand(4)
                szeneKlima.sendCommand(98) // Backup aktuelle Werte
                szeneKlima.sendCommand(4)
                Thread::sleep(1500) // etwas warten, damit auch 100%ig die alten Werte via Szene-98-Aufruf weggespeichert wurden...
                // Geräte ansteuern
                // -- Wohnzimmer
                DaikinACUnit_Wohnzimmer_Power.sendCommand(ON)
                DaikinACUnit_Wohnzimmer_Fan.sendCommand("LEVEL_5")
                DaikinACUnit_Wohnzimmer_Mode.sendCommand("COLD")
                // -- Schlafzimmer
                DaikinACUnit_Schlafzimmer_Power.sendCommand(ON)
                DaikinACUnit_Schlafzimmer_Fan.sendCommand("LEVEL_5")
                DaikinACUnit_Schlafzimmer_Mode.sendCommand("COLD")
                // -- Simon
                DaikinACUnit_Simon_Power.sendCommand(ON)
                DaikinACUnit_Simon_Fan.sendCommand("LEVEL_5")
                DaikinACUnit_Simon_Mode.sendCommand("COLD")
                // -- Sonja
                DaikinACUnit_Sonja_Power.sendCommand(ON)
                DaikinACUnit_Sonja_Fan.sendCommand("LEVEL_5")
                DaikinACUnit_Sonja_Mode.sendCommand("COLD")

                // Warten...
                if (log) logInfo('rules', logPrefix + 'Szene 4 - Starte Timer...')
                createTimer(now.plusSeconds(60*20)) [|
                    if (log) logInfo('rules', logPrefix + 'Szene 4 - Timer beendet, setze Szene zurück...')
                    // Ende der Szene, sofern zwischenzeitlich manuell die Szene nicht beendet oder gewechselt wurde - Herstellen alter Werte erfolgt automatisch
                    szeneKlima.sendCommand(0)
                    GENERIC_TTS_TEXT.postUpdate("Klimaautomatik - Power-Klima wurde beendet")
                ]
            } else {
                if (log) logInfo('rules', logPrefix + 'Szene 4 - ist bereits eingestellt!')
            }
        }
        case 3: { // Alle Klimageräte aus
                if (log) logInfo('rules', logPrefix + 'Szene 2 - Alle Geräte aus')
                DaikinACUnit_Schlafzimmer_Power.sendCommand(OFF)
                DaikinACUnit_Wohnzimmer_Power.sendCommand(OFF)
                DaikinACUnit_Simon_Power.sendCommand(OFF)
                DaikinACUnit_Sonja_Power.sendCommand(OFF)
                GENERIC_TTS_TEXT.postUpdate("Alle Klimageräte wurden ausgeschalten")
                // Szene in Aktion auf 0 setzen, damit kein Restore früherer Werte geschieht
                szeneKlima_szeneInAktion.sendCommand(0)
                szeneKlima.sendCommand(0)
        }
        case 2: { // Alle Klimageräte an
                if (log) logInfo('rules', logPrefix + 'Szene 2 - Alle Geräte an')
                DaikinACUnit_Schlafzimmer_Power.sendCommand(ON)
                DaikinACUnit_Schlafzimmer_Mode.sendCommand("COLD")
                DaikinACUnit_Wohnzimmer_Power.sendCommand(ON)
                DaikinACUnit_Wohnzimmer_Mode.sendCommand("COLD")
                DaikinACUnit_Simon_Power.sendCommand(ON)
                DaikinACUnit_Simon_Mode.sendCommand("COLD")
                DaikinACUnit_Sonja_Power.sendCommand(ON)
                DaikinACUnit_Sonja_Mode.sendCommand("COLD")
                GENERIC_TTS_TEXT.postUpdate("Alle Klimageräte wurden auf An und auf Kühlung geschalten")
                // Szene in Aktion auf 0 setzen, damit kein Restore früherer Werte geschieht
                szeneKlima_szeneInAktion.sendCommand(0)
                szeneKlima.sendCommand(0)
        }
        case 1: { // Entfeuchtung aller Räume
            if (szeneKlima_szeneInAktion.state != 1) {
                if (log) logInfo('rules', logPrefix + 'Szene 1 - Entfeuchtung - Backup aktueller Werte')
                GENERIC_TTS_TEXT.postUpdate("Klimaautomatik - Raumentfeuchtung für 45 Minuten gestartet")
                szeneKlima_szeneInAktion.sendCommand(1)
                szeneKlima.sendCommand(98) // Backup aktuelle Werte
                szeneKlima.sendCommand(1)
                Thread::sleep(1500) // etwas warten, damit auch 100%ig die alten Werte via Szene-98-Aufruf weggespeichert wurden...
                // Geräte ansteuern
                // -- Wohnzimmer
                DaikinACUnit_Wohnzimmer_Power.sendCommand(ON)
                DaikinACUnit_Wohnzimmer_Fan.sendCommand("AUTO")
                DaikinACUnit_Wohnzimmer_Mode.sendCommand("DEHUMIDIFIER")
                // -- Schlafzimmer
                DaikinACUnit_Schlafzimmer_Power.sendCommand(ON)
                DaikinACUnit_Schlafzimmer_Fan.sendCommand("AUTO")
                DaikinACUnit_Schlafzimmer_Mode.sendCommand("DEHUMIDIFIER")
                // -- Simon
                DaikinACUnit_Simon_Power.sendCommand(ON)
                DaikinACUnit_Simon_Fan.sendCommand("AUTO")
                DaikinACUnit_Simon_Mode.sendCommand("DEHUMIDIFIER")
                // -- Sonja
                DaikinACUnit_Sonja_Power.sendCommand(ON)
                DaikinACUnit_Sonja_Fan.sendCommand("AUTO")
                DaikinACUnit_Sonja_Mode.sendCommand("DEHUMIDIFIER")

                // Warten...
                if (log) logInfo('rules', logPrefix + 'Szene 1 - Starte Timer...')
                createTimer(now.plusSeconds(60*45)) [|
                    if (log) logInfo('rules', logPrefix + 'Szene 1 - Timer beendet, setze Szene zurück...')
                    // Ende der Szene, sofern zwischenzeitlich manuell die Szene nicht beendet oder gewechselt wurde - Herstellen alter Werte erfolgt automatisch
                    szeneKlima.sendCommand(0)
                    GENERIC_TTS_TEXT.postUpdate("Klimaautomatik - Raumentfeuchtung wurde beendet")
                ]
            }
        }
    }
end

Fazit

Die 45-Minuten für das Entfeuchten führen tatsächlich zu einem Abfall der Luftfeuchte im Haus um ca. 10% und zu einem angenehmen Raumklima. Der Cool-Down genügt auch, damit das Haus auch nach einem Sonnentag vor Rückkehr schön heruntergekühlt wird.

Vermutlich kann man in den Regeln manches noch ein bisschen schicker lösen, anstatt ein Thread-sleep z.B. einen Timer einsetzen usw. Aber die Lösung funktioniert bisher ganz gut und wer Vorschläge, Kommentare, was auch immer hat, darf diese gern als Kommentar hinterlassen 😉

Mal sehen, was mir mit den Anlagen noch so an Ideen einfällt…

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.