Hilfe bei der Realisierung meiner Heizungsregelung

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
Eleven
Beiträge: 53
Registriert: 15. Okt 2018 10:27
Answers: 0

Hilfe bei der Realisierung meiner Heizungsregelung

Beitrag von Eleven »

Hallo zusammen,

ich benötige Eure Hilfe bei der Realisierung meiner Heizungsregelung. Aber fangen wir ganz vorne an.

Aktueller IST-Zustand:
Ich habe an allen Heizkörpern in meinem Haus Eurotronic Spirits verbaut. Diese werden aktuell noch händisch über die sitemap eingestellt, also das Einstellen der Soll-Temperatur, Heizkörper AN oder Aus, etc. Einzig die Spirits in den Badezimmern werden mittels einer Rule getriggert.
Dort ist eine Heizzeit festgelegt und wenn in dieser Zeit das Fenster geöffnet wird geht der Heizkörper aus.

Hier mal ein Ausschnitt aus der rule für einen Heizkörper.

heizkörper.rules

Code: Alles auswählen

var Timer fenstertimer = null                                    // Timervariable definieren


// Heizzeit für Heizkörper Badezimmer oben
rule "Heizung Bad oben"
when
    Time cron "0 0 5 * * ?" or                                   // Triggere täglich um 5 Uhr
    Time cron "0 0 23 * * ?" or                                  // Triggere täglich um 23 Uhr
    Item Fenster_Bad_oben_Status changed                         // Triggere wenn der Fensterkontakt geschaltet hat
then
    if(now.getHourOfDay > 4 && now.getHourOfDay < 23) {          // Innerhalb des Zeitfensters?
        if(Fenster_Bad_oben_Status.state != CLOSED) {               // Fenster offen oder nicht initialisiert?
            BDO_Heizung_Mode.sendCommand(0)  
            logInfo("Heizung", "Fenster im Bad oben geöffnet und Heizkörper abgedreht")
            fenstertimer = createTimer(now.plusMinutes(10), [|   // Starte Timer für Meldung
                sendPushoverMessage(pushoverBuilder("Info, Fenster Bad oben 10 Min. geöffnet").withDevice("iPhoneXR"))
                fenstertimer = null 
            ])                                                   // Lambda in die Funktion verschoben, Lesbarkeit des Codes
        } else {                                                 // Fenster ist geschlossen!
            BDO_Heizung_Mode.sendCommand(1)
            logInfo("Heizung", "Fenster im Bad oben geschlossen und Heizkörper aufgedreht")
            if(fenstertimer !== null) {                          // Timer läuft?
                fenstertimer.cancel                              // Timer abbrechen
                fenstertimer = null 
            }
        }
    }
    else {                                                       // Außerhalb des Zeitfensters, Heizung aus!
        BDO_Heizung_Mode.sendCommand(0)
        logInfo("Heizung", "Nachtmodus Bad oben")
        if(fenstertimer !== null) {                              // Timer läuft?
            fenstertimer.cancel                                  // Timer abbrechen
            fenstertimer = null 
        }
    }
end
Diese funktioniert auch wie gewünscht, allerdings würde ich meine gesamte Heizungsregelung gerne automatisieren.
Vor einiger Zeit habe ich im englischsprachigen openhab Forum einen Beitrag bzw. ein Howto über einer Heizungsregelung von Thom Dietrich gefunden (https://community.openhab.org/t/heating ... odes/34843).

Diese entspricht im Prinzip schon meinen Vorstellungen, allerdings würde ich diese gerne noch um folgende Punkte erweitern:
- Eine Festgelegte Heizzeit. Innerhalb der Heizzeit stellen sich die Thermostate auf den Modus "HEAT", Außerhalb in den Mode "OFF".
- Sommermodus. Sofern ich den Mode OFF_SUMMER setze sollen ebenfalls alle Thermostate in den Mode "OFF" gehen und dort bleiben, bis ein anderen Mode gesetzt wird.
- Fenster-offen Erkennung. Wird innerhalb der Heizzeit z.B. im Bad das Fenster geöffnet soll der Heizkörper so lange aus gehen bis das Fenster wieder geschlossen wird.

Nun stellt sich mir die Frage wieviel man in einer rule unterbringen kann, bzw. wie man dies am sinnvollsten angeht.
Ich habe als erstes man angefangen, die nötigen items gemäß des Howtos anzulegen.
Hier findet Ihr einen Ausschnitt für einen Heizkörper. Die weiteren Heizkörper sind natürlich identisch aufgebaut.

Eurotronic.items

Code: Alles auswählen

Number      BDO_Heizung_ActTemp                         "BDO_Heizung Ist-Temperatur [%.1f °C]"                                  <temperature>                                               { channel="zwave:device:e16eec95:node35:sensor_temperature", autoupdate="false" }
Number      BDO_Heizung_Mode                            "BDO_Heizung Thermostatmodusmodus"                                      <temperature>       (Heating_Mode)                          { channel="zwave:device:e16eec95:node35:thermostat_mode", autoupdate="false" }
Number      BDO_Heizung_SetTemp                         "BDO_Heizung Solltemperatur [%.1f °C]"                                  <temperature>       (Heating_TargetTemps)                   { channel="zwave:device:e16eec95:node35:thermostat_setpoint_heating", autoupdate="false" }
Number      BDO_Heizung_SetTempEco                      "BDO_Heizung Solltemperatur Eco [%.1f °C]"                              <temperature>       (Heating_TargetTempsEco)                { channel="zwave:device:e16eec95:node35:thermostat_setpoint_heating_econ", autoupdate="false" }
Dimmer      BDO_Heizung_Valve                           "BDO_Heizung Ventilstellung [%d %%]"                                    <heating>                                                   { channel="zwave:device:e16eec95:node35:switch_dimmer", autoupdate="false" } 
Number      BDO_Heizung_Battery                         "BDO_Heizung Batteriezustand  [%s %%]"                                  <battery>                                                   { channel="zwave:device:e16eec95:node35:battery-level", autoupdate="false" } 
Switch      BDO_Heizung_AlarmSystem                     "BDO_Heizung Alarm (System)"                                                                                                        { channel="zwave:device:e16eec95:node35:alarm_system", autoupdate="false" }
Switch      BDO_Heizung_Alarm_Power                     "BDO_Heizung Alarm (Power)"                                                                                                         { channel="zwave:device:e16eec95:node35:alarm_power", autoupdate="false" }
Number      BDO_Heizung_ExtTemp                         "BDO_Heizung Aktuelle Temperatur extern"                                <temperature>                                               { channel="zwave:device:e16eec95:node35:sensor_report", autoupdate="false" }
String      BDO_Heizung_ActTemp_SetTemp                 "BDO_Heizung Akt-Temp / Soll-Temp  [%s]"                                <temperature>       (Heating_Ist_Soll)
Number      BDO_PresetTempNormal                        "BDO_Heizung Soll-Temperatur Zeitprogramm (Normal Mode) [%.1f °C]"                          (Heating_TargetPresets)
Zusätzlich natürlich noch die beides items für den Mode und der Switch für das Update der Wunschtemperatur.

System.items

Code: Alles auswählen

String      Whg_Heating_Mode                "Wohnung Heizmodus [%s]"                    <heating>       (Whg)
Switch      Whg_Heating_UpdateHeater        "Sende Soll-Temperaturen an Heizkörper"     <heating>       (Whg)
Als nächstes habe ich angefangen die rule aus dem Howto zu übernehmen. Auch hier ist nur exemplarisch ein item in der rule enthalten um den Beitrag nicht künstlich aufzublähen.

Heizung-modus.rules

Code: Alles auswählen

val String filename = "Heizung-modus.rules"

// vordefinierte Temperaturen
val Number tempHigh = 23.0
val Number tempComfort = 21.0
val Number tempMid = 19.0
val Number tempLower = 17.0
val Number tempAway = 15.0

rule "Initialisiere noch nicht initialisierte virtuelle Items"
when
    Time cron "0 03 23 * * ?"
then
    createTimer(now.plusSeconds(180)) [ |
        logInfo(filename, "Whg_Heating system gestartet")
        if (Whg_Heating_Mode.state == NULL) Whg_Heating_Mode.postUpdate("NORMAL")
        Heating_TargetPresets.members.filter[item | item.state == NULL].forEach[item | item.postUpdate(21.0)]
        Whg_Heating_UpdateHeater.sendCommand(ON)
    ]
end

rule "Überprüfung der Heizzeit"
when
    Time cron "0 0 5 * * ?" or                                   //Triggere täglich um 5 Uhr                 
    Time cron "0 0 23 * * ?" or                                  //Triggere täglich um 23 Uhr
then
    if(now.getHourOfDay > 4 && now.getHourOfDay < 23) {          //Innerhalb des Zeitfensters?
        if(Whg_Heating_Mode.state == "NORMAL" || Whg_Heating_Mode.state == "URLAUB" || Whg_Heating_Mode.state == "SICKDAY") {   //Modus Normal, Urlaub oder Sickdday aktiviert? 
            BDO_Heizung_Mode.sendCommand(1)                      //Setze Heizkröper in den Heat Modus
        }
        else(Whg_Heating_Mode.state == "OFF_SUMMER") {           //Falls die oben Parameter nicht passen oder der Sommermodus aktiviert ist
            BDO_Heizung_Mode.sendCommand(0)                      //Setze die Heizkörper in den Modus AUS
        }
    }else {
        BDO_Heizung_Mode.sendCommand(0)  			 // Heizkörper AUS, da außerhalb der Heizzeit
    }
end

rule "Heizmodus umschalten und Stellglieder setzen"
when
    Item Whg_Heating_Mode received update or
    Item Whg_Heating_UpdateHeater received command ON
then
    Whg_Heating_UpdateHeater.postUpdate(OFF)
    logInfo(filename, "Wohnung Heizmodus: " + Whg_Heating_Mode.state)
    switch Whg_Heating_Mode.state {
        case "NORMAL" : {
            BDO_Heizung_SetTemp.sendCommand(BDO_PresetTempNormal.state as Number)
        }
        case "URLAUB": {
            BDO_Heizung_SetTemp.sendCommand(tempComfort)
        }       
        case "SICKDAY": {
            BDO_Heizung_SetTemp.sendCommand(tempHigh)
        }
        case "OFF_SUMMER": {
            BDO_Heizung_Mode.sendCommand(0)
        }
        default: { logError(filename, "Wohnung Heizmodus ungültig: " + Whg_Heating_Mode.state) }
    }
end

// Whg_Heating_Mode NORMAL Zeitprogramm

rule "MON-FRI, 05:01"
when
    Time cron "0 1 5 ? * MON-FRI *" 
then
    logInfo(filename, "Wohnung Heizmodus: Zeitprogramm: " + now.toString)
    BDO_PresetTempNormal.postUpdate(21.0)
    Whg_Heating_UpdateHeater.sendCommand(ON)
end

rule "SAT-SUN, 06:00"
when
    Time cron "0 0 6 ? * SAT,SUN *"
then
    logInfo(filename, "Wohnung Heizmodus: Zeitprogramm: " + now.toString)
    BDO_PresetTempNormal.postUpdate(21.0)
    Whg_Heating_UpdateHeater.sendCommand(ON)
end
Nun habe ich mich gefragt, ob man die einzelnen Regeln in der Heizung-modus.rules nicht zusammenfassen kann?

Ich habe mich damit beschäftigt, hier der aktuelle Stand:
Heizung-modus.rules --> Teilweise zusammengefasst

Code: Alles auswählen

rule "Heizungsmodus"
when 
    Time cron "0 0 5 * * ?" or 
    Time cron "0 0 23 * * ?" or
    Item Whg_Heating_Mode received update or
    Item Whg_Heating_UpdateHeater received command ON
then 
    if(now.getHourOfDay > 4 && now.getHourOfDay < 23) {
            if(Whg_Heating_Mode.state == "NORMAL" || Whg_Heating_Mode.state == "URLAUB" || Whg_Heating_Mode.state == "SICKDAY") {
                logInfo("Heizung", "Heating Mode: " + Whg_Heating_Mode.state)
                BDO_Heizung_Mode.sendCommand(1)
                Whg_Heating_UpdateHeater.postUpdate(OFF)
                    switch Whg_Heating_Mode.state {
                        case "NORMAL": {
                            BDO_Heizung_SetTemp.sendCommand(BDO_PresetTempNormal.state as Number)
                        }
                        case "URLAUB": {
                            BDO_Heizung_SetTemp.sendCommand(tempComfort)
                        }
                        case "SICKDAY": {
                            BDO_Heizung_SetTemp.sendCommand(tempHigh)
                        }
                        case "OFF_SUMMER": {
                            Heating_Mode.sendCommand(0)
                        }
                        default : { logError(filename, "Heating Mode unknown: " + Whg_Heating_Mode.state) }
                    }
            }else(Whg_Heating_Mode.state == "OFF_SUMMER") {
                logInfo("Heizung", "Heating Mode: " + Whg_Heating_Mode.state)
                Whg_Heating_UpdateHeater.postUpdate(OFF)
                BDO_Heizung_Mode.sendCommand(0)
            }    
    }else {
        logInfo("Heizung", "Nachtmodus Whg")
        Whg_Heating_UpdateHeater.postUpdate(OFF)
        Heating_Mode.sendCommand(0)
    }
end
Ich habe aber überhaupt keine Ahnung ob man so etwas lieber splitten sollte oder wieviel man zusammen in eine Regel packt. Denn es es fehlt ja auch noch die Fenster offen Erkennung.
Schreibe ich diese in einer separaten rule? Wie sieht es dann in dieser rule mit der Heizzeit aus? Wäre das doppelt gemoppelt oder muss man diese sogar nochmal hinzufügen?

Ich bin aktuell ziemlich überfordert und weiß ehrlich gesagt gar nicht mehr wo in anfangen soll. Ich hoffe das Ihr mir bei der Realisierung meines Vorhabens helfen könnt. Ich danke euch schon mal im voraus!!!

Eleven
Beiträge: 53
Registriert: 15. Okt 2018 10:27
Answers: 0

Re: Hilfe bei der Realisierung meiner Heizungsregelung

Beitrag von Eleven »

Hallo, ich habe mich weiter an meinem Vorhaben versucht und bin jetzt soweit, das in einer rule die Heizzeit abgefragt wird und man den Heizungsmodus auswählen, bzw. verändern kann.

Code: Alles auswählen

val String filename = "Heizung-modus.rules"

// vordefinierte Temperaturen
val Number tempHigh = 23.0
val Number tempComfort = 21.0
val Number tempMid = 19.0
val Number tempLower = 17.0
val Number tempAway = 15.0
val Number tempOff = 8.0



rule "Initialisiere moch nicht initialisierte virtuelle Items"
when
    System started
then
    createTimer(now.plusSeconds(180)) [ |
        logInfo(filename, "Whg_Heating system gestartet")
        if (Whg_Heating_Mode.state == NULL) Whg_Heating_Mode.postUpdate("NORMAL")
        Heating_TargetPresets.members.filter[item | item.state == NULL].forEach[item | item.postUpdate(tempComfort)]
        Whg_Heating_UpdateHeater.sendCommand(ON)
    ]
end

rule "Heizmodus umschalten und Stellglieder setzen"
when
    Time cron "0 0 5 * * ?" or
    Time cron "0 0 23 * * ?" or
    Item Whg_Heating_Mode received update or
    Item Whg_Heating_UpdateHeater received command ON 
then
    if(now.getHourOfDay > 4 && now.getHourOfDay < 23) {
        Whg_Heating_UpdateHeater.postUpdate(OFF)
        logInfo(filename, "Wohnung Heizmodus: " + Whg_Heating_Mode.state)
            switch Whg_Heating_Mode.state {
                case "NORMAL" : {
                    BDO_Heizung_SetTemp.sendCommand(BDO_PresetTempNormal.state as Number)
                    BDU_Heizung_SetTemp.sendCommand(BDU_PresetTempNormal.state as Number)
                    EZ_Heizung_SetTemp.sendCommand(EZ_PresetTempNormal.state as Number)
                    WZKL_Heizung_SetTemp.sendCommand(WZKL_PresetTempNormal.state as Number)
                    WZKR_Heizung_SetTemp.sendCommand(WZKR_PresetTempNormal.state as Number)
                    WZG_Heizung_SetTemp.sendCommand(WZG_PresetTempNormal.state as Number)
                    SZ_Heizung_SetTemp.sendCommand(SZ_PresetTempNormal.state as Number)
                }
                case "URLAUB": {
                    BDO_Heizung_SetTemp.sendCommand(tempComfort)
                    BDU_Heizung_SetTemp.sendCommand(tempComfort)
                    EZ_Heizung_SetTemp.sendCommand(tempComfort)
                    WZKL_Heizung_SetTemp.sendCommand(tempComfort)
                    WZKR_Heizung_SetTemp.sendCommand(tempComfort)
                    WZG_Heizung_SetTemp.sendCommand(tempComfort)
                    SZ_Heizung_SetTemp.sendCommand(tempLower)
                }       
                case "KRANK": {
                    BDO_Heizung_SetTemp.sendCommand(tempComfort)
                    BDU_Heizung_SetTemp.sendCommand(tempComfort)
                    EZ_Heizung_SetTemp.sendCommand(tempHigh)
                    WZKL_Heizung_SetTemp.sendCommand(tempHigh)
                    WZKR_Heizung_SetTemp.sendCommand(tempHigh)
                    WZG_Heizung_SetTemp.sendCommand(tempHigh)
                    SZ_Heizung_SetTemp.sendCommand(tempLower)
                }
                case "SOMMERMODUS": {
                    BDO_Heizung_SetTemp.sendCommand(tempOff)
                    BDU_Heizung_SetTemp.sendCommand(tempOff)
                    EZ_Heizung_SetTemp.sendCommand(tempOff)
                    WZKL_Heizung_SetTemp.sendCommand(tempOff)
                    WZKR_Heizung_SetTemp.sendCommand(tempOff)
                    WZG_Heizung_SetTemp.sendCommand(tempOff)
                    SZ_Heizung_SetTemp.sendCommand(tempOff)
                }
                default: { logError(filename, "Wohnung Heizmodus ungültig: " + Whg_Heating_Mode.state) }
            }
    }else {
        Whg_Heating_UpdateHeater.postUpdate(OFF)
        BDO_Heizung_SetTemp.sendCommand(tempOff)
        BDU_Heizung_SetTemp.sendCommand(tempOff)
        EZ_Heizung_SetTemp.sendCommand(tempOff)
        WZKL_Heizung_SetTemp.sendCommand(tempOff)
        WZKR_Heizung_SetTemp.sendCommand(tempOff)
        WZG_Heizung_SetTemp.sendCommand(tempOff)
        SZ_Heizung_SetTemp.sendCommand(tempOff)
        logInfo("Heizung", "WHG Nachtmodus")
    }        
end


// Whg_Heating_Mode NORMAL Zeitprogramm

rule "MON-FRI, 05:01"
when
    Time cron "0 1 5 ? * MON-FRI *" 
then
    logInfo(filename, "Wohnung Heizmodus: Zeitprogramm: " + now.toString)
    BDO_PresetTempNormal.postUpdate(21.0)
    BDU_PresetTempNormal.postUpdate(21.0)
    EZ_PresetTempNormal.postUpdate(21.0)
    WZKL_PresetTempNormal.sendCommand(21.0)
    WZKR_PresetTempNormal.sendCommand(21.0)
    WZG_PresetTempNormal.sendCommand(21.0)
    SZ_PresetTempNormal.sendCommand(18.0)
    Whg_Heating_UpdateHeater.sendCommand(ON)
end


rule "MON-FRI, 07:30"
when
    Time cron "0 30 7 ? * MON-FRI *"
then 
    logInfo(filename, "Wohnung Heizmodus: Zeitprogramm: " + now.toString)
    BDO_PresetTempNormal.postUpdate(18.0)
    BDU_PresetTempNormal.postUpdate(18.0)
    EZ_PresetTempNormal.postUpdate(18.0)
    WZKL_PresetTempNormal.sendCommand(18.0)
    WZKR_PresetTempNormal.sendCommand(18.0)
    WZG_PresetTempNormal.sendCommand(18.0)
    SZ_PresetTempNormal.sendCommand(18.0)
    Whg_Heating_UpdateHeater.sendCommand(ON)
end


rule "MON-FRI, 11:00"
when
    Time cron "0 0 11 ? * MON-FRI *"
then 
    logInfo(filename, "Wohnung Heizmodus: Zeitprogramm: " + now.toString)
    BDO_PresetTempNormal.postUpdate(21.0)
    BDU_PresetTempNormal.postUpdate(21.0)
    EZ_PresetTempNormal.postUpdate(21.0)
    WZKL_PresetTempNormal.sendCommand(21.0)
    WZKR_PresetTempNormal.sendCommand(21.0)
    WZG_PresetTempNormal.sendCommand(21.0)
    SZ_PresetTempNormal.sendCommand(18.0)
    Whg_Heating_UpdateHeater.sendCommand(ON)
end


rule "MON-FRI, 21:00"
when
    Time cron "0 0 21 ? * MON-FRI *"
then 
    logInfo(filename, "Wohnung Heizmodus: Zeitprogramm: " + now.toString)
    BDO_PresetTempNormal.postUpdate(8.0)
    BDU_PresetTempNormal.postUpdate(8.0)
    EZ_PresetTempNormal.postUpdate(8.0)
    WZKL_PresetTempNormal.sendCommand(8.0)
    WZKR_PresetTempNormal.sendCommand(8.0)
    WZG_PresetTempNormal.sendCommand(8.0)
    SZ_PresetTempNormal.sendCommand(8.0)
    Whg_Heating_UpdateHeater.sendCommand(ON)
end


rule "SAT-SUN, 06:00"
when
    Time cron "0 0 6 ? * SAT,SUN *"
then
    logInfo(filename, "Wohnung Heizmodus: Zeitprogramm: " + now.toString)
    BDO_PresetTempNormal.postUpdate(21.0)
    BDU_PresetTempNormal.postUpdate(21.0)
    EZ_PresetTempNormal.postUpdate(21.0)
    WZKL_Heizung_SetTemp.sendCommand(21.0)
    WZKR_Heizung_SetTemp.sendCommand(21.0)
    WZG_PresetTempNormal.sendCommand(21.0)
    SZ_PresetTempNormal.sendCommand(18.0)
    Whg_Heating_UpdateHeater.sendCommand(ON)
end                 


rule "SAT-SUN, 22:00"
when
    Time cron "0 0 22 ? * SAT,SUN *"
then
    logInfo(filename, "Wohnung Heizmodus: Zeitprogramm: " + now.toString)
    BDO_PresetTempNormal.postUpdate(8.0)
    BDU_PresetTempNormal.postUpdate(8.0)
    EZ_PresetTempNormal.postUpdate(8.0)
    WZKL_PresetTempNormal.sendCommand(8.0)
    WZKR_PresetTempNormal.sendCommand(8.0)
    WZG_PresetTempNormal.sendCommand(8.0)
    SZ_PresetTempNormal.sendCommand(8.0)
    Whg_Heating_UpdateHeater.sendCommand(ON)
end 
Es funktioniert soweit wie gewünscht. Nun würde den Sommermodus angehen, also bei Auswahl sollen die Heizkörper aus gehen und auch aus bleiben bis der Modus wieder geändert wird.
Hierbei ist mir aufgefallen, das sofern der Sommermodus angewählt wurde, dieser nur in der während der Heizzeit von 5 - 23 Uhr aktiv wäre!

Also müsste ich den Sommermodus in der Regel noch vor der Abrage der Heiztzeit setzen? Ich habe leider nur keine Anhnung wie. Kann man hier wieder mittels if/ else arbeiten?
Hat hier jemand eine Idee?

Antworten