Seite 1 von 1

Rules aus Openhab 2.4 in 4.0 migrieren

Verfasst: 20. Dez 2023 12:02
von Skully
Hallo zusammen,
ich steige gerade von meinem alten Openhab 2.4 (PI3) auf Openhab 4.0.4 (PI5) um. Ich war schon fast am Ziel meiner Umstellung, da bin ich über die Rules gestolpert. Ich habe damals meine ganzen Rules in einer Datei .rules programmiert. Wenn ich meine alte 2.4 rules Datei in Openhab 4.0 kopiere habe ich zwei Probleme:

1. Die Rules werden in die neue Rules Struktur übernommen ( ...und ich dachte mir hey cool, wie praktisch, ...) aber funktionieren nicht mehr.
Zur Frage: Ich habe gelesen das DSL in Zukunft sterben soll, deswegen ist es vermutlich besser direkt in Java zu migrieren. Gibt es eine Möglichkeit die alte rules Datei automatiesiert in Java zu übertragen? (Ich befüchte ich kenne die Antwort, wollte aber dennoch nachfragen)

2. Die Rules wurden in die neue Struktur übertragen und haben in der Rules Übersicht nun eine kleines Schloss. Wenn ich die Rules Zombies löschen möchte kommt die Fehlermeldung, das ich sie nicht löschen kann, da sie aus einer Datei übertragen wurden. Wie kann ich die Rules dennoch löschen?
(Fehlermeldung: Some of the selected rules are not modifiable because they have been provisioned by files)

Re: Rules aus Openhab 2.4 in 4.0 migrieren

Verfasst: 20. Dez 2023 15:55
von udo1toni
Zu Punkt 0 :) Rules funktionieren nicht mehr: Das war zu erwarten, weil sich einfach sehr viel seit Version 2 geändert hat. Dennoch mögen die Rules ein guter Startpunkt sein, Du musst sie lediglich anpassen.

Zu Punkt 1: Nein, die Rules DSL stirbt nicht, jedenfalls nicht in den nächsten Jahren. Was tatsächlich auf lange Sicht passieren wird, ist, dass die Rules DSL optional wird, genau wie zum jetzigen Zeitpunkt alle anderen Scriptsprachen optional sind - und das wird sich für diese Sprachen auch nicht ändern, nur wird die DSL nicht mehr so arg bevorzugt gegenüber den anderen Scriptsprachen sein...
Das heißt also, die DSL wird aus Core herausgelöst und wird als Addon installierbar sein. Zeitpunkt jetzt ist die DSL eben nicht optional, als einzige der Scriptsprachen.

Zu Punkt 2: die Rules wurden nicht übertragen, sie werden lediglich in der UI angezeigt, und so wie alle anderen Dinge, die über Textdateien konfiguriert wurden auch, sind diese Rules read only gekennzeichnet, was nur bedeutet, dass Du sie - wie bisher auch - über die Textdatei selbst bearbeiten musst.

Du willst die Rules nicht löschen, Du willst sie verändern. Du willst definitiv nicht auf Biegen und Brechen alles über die UI erledigen, schon gar nicht in der Phase des Umstiegs. Allerdings hast Du die Möglichkeit, auf lange Sicht Deine Arbeitsweise zu ändern (wenn Du das partout willst).

Java steht übrigens als Scriptsprache nicht zur Verfügung :) stattdessen müsstest Du auf JavaScript ausweichen (JavaScript ist NICHT Java) falls Du unbedingt den Begriff Java im Namen der Scriptsprache haben willst.
Die DSL ist in XTend realisiert, XTend wiederum basiert auf Java, daraus wird schon klar, dass die DSL noch am ehesten mit Java vergleichbar ist (und in der DSL kann man viele Java Module direkt nutzen)

Ach so... Zeige gerne Deine Rules, wenn Du nicht herausfindest, warum Geier das Ding nicht macht was es soll ;)

Re: Rules aus Openhab 2.4 in 4.0 migrieren

Verfasst: 20. Dez 2023 20:01
von Skully
Danke für die Antwort udo1toni! :)
Zu Punkt 2: Ich habe komischerweise meine ganzen Rules doppelt in der Übersicht. Ich dachte mir schon fast das ich die Rules nur in der Datei ändern kann. Wenn ich die ABC.rules Datei aus meinem Rules Ordner lösche verschwindet ein Teil der doppelten Reglen, aber irgendwo muss die gleiche Datei nochmal abgelegt sein. Weiß du oder jemand wo diese .rules Datei noch abgelegt sein könnte?
Du willst die Rules nicht löschen, Du willst sie verändern. Du willst definitiv nicht auf Biegen und Brechen alles über die UI erledigen, schon gar nicht in der Phase des Umstiegs. Allerdings hast Du die Möglichkeit, auf lange Sicht Deine Arbeitsweise zu ändern (wenn Du das partout willst).
Am liebsten wäre mir wenn ich die .rule Datei verändern könnte so das sie wieder läuft. Ich habe nur leider absolut keine Ahnung was ich in der Datei ändern muss, damit sie wieder gehen könnten. Deswegen dachte ich mir ich baue sie einfach nochmal neu in JavaScript.

Re: Rules aus Openhab 2.4 in 4.0 migrieren

Verfasst: 20. Dez 2023 20:48
von Skully
Und hier meine Rule Datei, falls jemand Lust hat sich dort durch zu kämpfen. Allerdings keine muss. Meine Freundin würde sich allerdings bedanken wenn die Heizungs Regelung wieder funktioniert :lol:

Code: Alles auswählen

// 20.12.2023

// Variablen***************************************************************************************************************************************************************************************

var Number Bad = 1 
var Timer KuecheLightTimer = null

// Initialisieren Systemstart***************************************************************************************************************************************************************************************


rule "Init virtual Items"

when
    System started
then
    
	Bewegungsmelder_Kueche_MotionOffTimer.sendCommand(10)		//NULL Standart Wert
	Bewegungsmelder_Flur_MotionOffTimer.sendCommand(10)		//NULL Standart Wert
	Bewegungsmelder_Wohnzimmer_MotionOffTimer.sendCommand(15) 	//NULL Standart Wert


	if (TemperaturBad.state == Uninitialized) {  //Badtemperatur
        TemperaturBad.sendCommand(16.5) //postUpdate ist nur f?r Aktualisierungen innerhalb von openHAB (sendCommand gibt diese auch auf den Bus)
    		}
    	if (Badtemperatur_Soll_Setpoint.state == Uninitialized) {
        Badtemperatur_Soll_Setpoint.sendCommand(16)
		}

    	if (TemperaturWon.state == Uninitialized) {  //Wohnzimmertemperatur
        TemperaturWon.sendCommand(16.5) //postUpdate ist nur f?r Aktualisierungen innerhalb von openHAB (sendCommand gibt diese auch auf den Bus)
    	}
    	if (Wontemperatur_Soll_Setpoint.state == Uninitialized) {
        Wontemperatur_Soll_Setpoint.sendCommand(16)
		}

	if (TemperaturSchl.state == Uninitialized) {  //Schlafzimmertemperatur
        TemperaturSchl.sendCommand(16.5) //postUpdate ist nur f?r Aktualisierungen innerhalb von openHAB (sendCommand gibt diese auch auf den Bus)
    		}
    	if (Schltemperatur_Soll_Setpoint.state == Uninitialized) {
        Schltemperatur_Soll_Setpoint.sendCommand(16)
		}
	
end


// Regeln Badezimmer***************************************************************************************************************************************************************************************


rule "Temperatur Ist mit Soll vergleichen im Bad"

when
        Item TemperaturBad changed or Item Badtemperatur_Soll_Setpoint changed
then

       if (TemperaturBad.state < Badtemperatur_Soll_Setpoint.state){
	    Heizung_Switch_Ba.sendCommand(ON)
    }
       if (TemperaturBad.state >= Badtemperatur_Soll_Setpoint.state){
            Heizung_Switch_Ba.sendCommand(OFF)
    }   


end


rule "Badfenster geoeffnet"

when
        Item Bad_Fenster_1_OpenStatus changed from CLOSED to OPEN or
	Item Bad_Fenster_2_OpenStatus changed from CLOSED to OPEN
then	
	Badtemperatur_Soll_Setpoint.sendCommand(3)
end


rule "Badfenster geschlossen"

when
        Item Bad_Fenster_1_OpenStatus changed from OPEN to CLOSED or
	Item Bad_Fenster_2_OpenStatus changed from OPEN to CLOSED
then	
	if(Bad_Fenster_1_OpenStatus.state == CLOSED && Bad_Fenster_2_OpenStatus.state == CLOSED ) {
	Badtemperatur_Soll_Setpoint.sendCommand(17)
	}
end


// Regeln Wohnzimmerheizung***************************************************************************************************************************************************************************************


rule "Temperatur Ist mit Soll vergleichen"

when
        Item TemperaturWon changed or Item Wontemperatur_Soll_Setpoint changed
then

       if (TemperaturWon.state < Wontemperatur_Soll_Setpoint.state){

            Heizung_Switch_Won1.sendCommand(ON)
            Heizung_Switch_Won2.sendCommand(ON)
        }
        if (TemperaturWon.state >= Wontemperatur_Soll_Setpoint.state){

            Heizung_Switch_Won1.sendCommand(OFF)
            Heizung_Switch_Won2.sendCommand(OFF)
        }
	
end


rule "Wohnzimmer Tablet einschalten"

when
	Item Bewegungsmelder_Wohnzimmer_MotionStatus received update ON
then
	sendHttpGetRequest("http://192.168.178.91:8080/TabletWohnzimmerEin")
end


// Regeln Flur***************************************************************************************************************************************************************************************


rule "Taster im Flur"

when
	Item Touch_G1_Flur_Lampe received update ON
then
	Touch_G1_Flur_Lampe.sendCommand(OFF)
end


rule "Flur Nachtlicht"
	when 
		Item Bewegungsmelder_Flur_MotionStatus received update ON
	then
		var Number hour = now.getHourOfDay
		
		
		if(hour <= 8 || hour >= 17){ 				// Nachtlich an zwischen 8:00Uhr und 17:00Uhr
		XiaomiMiSmartHomeGateway_Brightness.sendCommand(ON)

		createTimer(now.plusSeconds(130)) [ |			//plusMinutes(2)
		XiaomiMiSmartHomeGateway_Brightness.sendCommand(OFF)
		]
}
	
end


// Regeln Schlafzimmer***************************************************************************************************************************************************************************************


rule "Temperatur Ist mit Soll vergleichen im Schlafzimmer"

when
        Item Schltemperatur_Soll_Setpoint changed or Item TemperaturSchl changed 
then

       if (TemperaturSchl.state < Schltemperatur_Soll_Setpoint.state){
            Heizung_Switch_Schl.sendCommand(ON)
        }

       if (TemperaturSchl.state >= Schltemperatur_Soll_Setpoint.state){
            Heizung_Switch_Schl.sendCommand(OFF)
        }
end


rule "Schlafzimmerfenster geoeffnet"

when
        Item Schlaf_Fenster_1_OpenStatus changed from CLOSED to OPEN or
	Item Schlaf_Fenster_2_OpenStatus changed from CLOSED to OPEN
then
	
	Schltemperatur_Soll_Setpoint.sendCommand(3)
end


rule "Schlafzimmerfenster geschlossen"

when
        Item Schlaf_Fenster_1_OpenStatus changed from OPEN to CLOSED or
	Item Schlaf_Fenster_2_OpenStatus changed from OPEN to CLOSED
then	
	if(Schlaf_Fenster_1_OpenStatus.state == CLOSED && Schlaf_Fenster_2_OpenStatus.state == CLOSED ) {
	Schltemperatur_Soll_Setpoint.sendCommand(18)
	}	
end


// Regeln K che***************************************************************************************************************************************************************************************


rule "Kueche Bewegungsmelder"

when Item Bewegungsmelder_Kueche_MotionStatus changed from OFF to ON

then
	var Number hour = now.getHourOfDay
	if(hour <= 8 || hour >= 17){                                    // K chenlicht an zwischen 8:00Uhr und 17:00Uhr
		if(KuecheLightTimer!==null) {
			KuecheLightTimer.cancel()  //cancel existing timer
		}
		Touch_G1_Kueche_Lampe.sendCommand(ON)  //turn on light
		S20_48_LED_Leiste_Kueche_Power.sendCommand(ON)
	}
end


rule "Kueche Light Timer"
when Item Bewegungsmelder_Kueche_MotionStatus changed from ON to OFF
then
	var Number hour = now.getHourOfDay
	if(hour <= 8 || hour >= 18){
		if(KuecheLightTimer!==null) {
			KuecheLightTimer.cancel() //cancel exsiting timer
		}
		KuecheLightTimer = createTimer(now.plusSeconds(180)) [| //create new timer  //code to run at timers end goes in this block.  Rest of rule continues.
			Touch_G1_Kueche_Lampe.sendCommand(OFF) // turn off light
			S20_48_LED_Leiste_Kueche_Power.sendCommand(OFF)
		]
	}
end


//*****************************************************************************************************************************************************************************************


rule "Gesamte Automatisierung"
when
	Time cron "0 59 23 ? * MON,TUE,WED,THU,FRI,SAT,SUN *"      //Monag bis Sonntag um 23:59 Uhr wird die Temperatur eingestellt
then

			//Wonautomatik_Hz_ein_aus.sendCommand(1)
			//Badautomatik_Hz_ein_aus.sendCommand(1)
		Badtemperatur_Soll_Setpoint.sendCommand(17)
		Wontemperatur_Soll_Setpoint.sendCommand(17)
		Schltemperatur_Soll_Setpoint.sendCommand(18)

end


rule "Schlafen gehen/ Out of House"
when
	Item Out_of_House received command ON
 
then

		Touch_G2_Won_Lampe_1_1.sendCommand(OFF)
		Touch_G2_Won_Lampe_1_2.sendCommand(OFF)
		Touch_G2_Won_Lampe_2_1.sendCommand(OFF)
		Touch_G2_Won_Lampe_2_2.sendCommand(OFF)
		Touch_G1_Schlaf_Lampe.sendCommand(OFF)
		Touch_G2_Bad_Lampe_1_1.sendCommand(OFF)
		S20_Stehlampe.sendCommand(OFF)
		Badtemperatur_Soll_Setpoint.sendCommand(17)
		Wontemperatur_Soll_Setpoint.sendCommand(17)
		Schltemperatur_Soll_Setpoint.sendCommand(18)
		Out_of_House.sendCommand(OFF)
		XiaomiMiSmartHomeGateway_Brightness.sendCommand(OFF)
		Touch_G1_Kueche_Lampe.sendCommand(OFF)
		Touch_G1_Flur_Lampe.sendCommand(OFF)

end


rule "Ich bin wieder zu Hause"
when
	Item bin_wieder_da received command ON
	
 
then

		var Number hour = now.getHourOfDay

		if(hour <= 8 || hour >= 17){ 				// Licht an zwischen 8:00Uhr und 17:00Uhr

		Touch_G2_Won_Lampe_1_1.sendCommand(ON)
		Touch_G2_Won_Lampe_1_2.sendCommand(ON)
		Touch_G2_Won_Lampe_2_1.sendCommand(ON)
	}	
				
		Badtemperatur_Soll_Setpoint.sendCommand(20)
		Wontemperatur_Soll_Setpoint.sendCommand(22)
		Schltemperatur_Soll_Setpoint.sendCommand(18)

		bin_wieder_da.sendCommand(OFF)

end

//**Automatisierung***************************************************************************************************************************************************************************************

rule "Cron_Heizungs_Automatisierung_BAD_1"
when
	Time cron "0 30 5 ? * MON,TUE,WED,THU,FRI *" //5:30 Uhr Aufheizperiode Bad EIN (Mo-Fr)
then

	Badtemperatur_Soll_Setpoint.sendCommand(19)

end


rule "Cron_Heizungs_Automatisierung_Bad_2"
when
	Time cron "0 30 7 ? * MON,TUE,WED,THU,FRI *" //8:00 Uhr Abschaltung Bad AUS (Mo-Fr)
then

	Heizung_Switch_Ba.sendCommand(OFF)
	Badtemperatur_Soll_Setpoint.sendCommand(17)

end


rule "Cron_Heizungs_Automatisierung_Wohnzimmer_1"
when
	Time cron "0 30 15 ? * MON,TUE,WED,THU,FRI *" //15:30 Uhr Aufheizperiode Wohnzimmer EIN (Mo-Fr)
then
	Wontemperatur_Soll_Setpoint.postUpdate(20)
end



Re: Rules aus Openhab 2.4 in 4.0 migrieren

Verfasst: 20. Dez 2023 23:51
von udo1toni
Es scheint als hättest Du beim Anlegen zu irgendeinem Zeitpunkt etwas kaputt gemacht :)

Benenne erst mal die Datei mit den Rules um (insbesondere sollten im Dateinamen keine Leerzeichen vorkommen, aber zu diesem Zeitpunkt ändere auch die Endung von .rules z.B. auf .rules.old ab. Nun sollten eigentlich alle Rules verschwunden sein. Ist das nicht der Fall, starte openHAB bitte einmal neu. Spätestens dann sollten die überzähligen Rules weg sein.
Ansonsten könnte es natürlich noch sein, dass Du im Verzeichnis $OPENHAB_CONF/rules/ noch weitere Dateien liegen hast, die da aber nicht sein sollten :) insbesondere keine Dateien, die keine aktiven Rules enthalten, deren Endung aber .rules lautet (auch nicht in Unterverzeichnissen, die außerdem nicht in der Verzeichnisstruktur erlaubt sind)

Tatsächlich wird keine der Rules von oben große Probleme bereiten, im Grunde sollte alle (bis auf die mit getHourOfDay) einwandfrei funktionieren. Da die Rules bei Dir doppelt auftauchen, hast Du ein anderes Problem, welches vermutlich jeglichen Betrieb von openHAB stört.

Trotzdem hier mal die überarbeiteten Rules:

Code: Alles auswählen

// globale Variablen 

var Number Bad = 1 
var Timer tKueche = null
var Timer tFlur = null

// Initialisieren Systemstart 

rule "Init virtual Items"
when
    System started
then
    Bewegungsmelder_Kueche_MotionOffTimer.sendCommand(10)        // NULL Standard Wert
    Bewegungsmelder_Flur_MotionOffTimer.sendCommand(10)          // NULL Standard Wert
    Bewegungsmelder_Wohnzimmer_MotionOffTimer.sendCommand(15)    // NULL Standard Wert

    if(!(TemperaturBad.state instanceof Number))                 // Badtemperatur
        TemperaturBad.postUpdate(16.5)

    if(!(Badtemperatur_Soll_Setpoint.state instanceof Number))
        Badtemperatur_Soll_Setpoint.sendCommand(16)

    if(!(TemperaturWon.state instanceof Number))                 // Wohnzimmertemperatur
        TemperaturWon.postUpdate(16.5)

    if(!(Wontemperatur_Soll_Setpoint.state instanceof Number))
        Wontemperatur_Soll_Setpoint.sendCommand(16)

    if(!(TemperaturSchl.state instanceof Number))                // Schlafzimmertemperatur
        TemperaturSchl.postUpdate(16.5)

    if(!(Schltemperatur_Soll_Setpoint.state instanceof Number))
        Schltemperatur_Soll_Setpoint.sendCommand(16)
end

// Regeln Badezimmer

rule "Temperatur Ist mit Soll vergleichen im Bad"
when
    Item TemperaturBad changed or
    Item Badtemperatur_Soll_Setpoint changed
then
    if(!(TemperaturBad.state instanceof Number)) {
        logWarn("temp","Temperatur Bad liefert ungültigen Wert {}",TemperaturBad.state)
        return;
    }
    val fIst = (TemperaturBad.state as Number).floatValue

    var fSoll = 16.0
    if(Badtemperatur_Soll_Setpoint.state instanceof Number)
        fSoll = (Badtemperatur_Soll_Setpoint.state as Number).floatValue

    var soll = OFF

    if(fSoll > fIst)
        soll = ON

    if(Heizung_Switch_Ba.state != soll)
       Heizung_Switch_Ba.sendCommand(soll.toString)
end

rule "Badfenster"
when
    Item Bad_Fenster_1_OpenStatus changed or
    Item Bad_Fenster_2_OpenStatus changed
then
    var soll = 3
    if(Bad_Fenster_1_OpenStatus.state == CLOSED && Bad_Fenster_2_OpenStatus.state == CLOSED)
        soll = 17

    if(Badtemperatur_Soll_Setpoint.state != soll)
        Badtemperatur_Soll_Setpoint.sendCommand(soll)
end

// Regeln Wohnzimmerheizung

rule "Temperatur Ist mit Soll vergleichen"
when
    Item TemperaturWon changed or 
    Item Wontemperatur_Soll_Setpoint changed
then
    if(!(TemperaturWon.state instanceof Number)) {
        logWarn("temp","Temperatur Wohnzimmer liefert ungültigen Wert {}",TemperaturWon.state)
        return;
    }
    val fIst = (TemperaturWon.state as Number).floatValue

    var fSoll = 16.0

    if(Wontemperatur_Soll_Setpoint.state instanceof Number)
        fSoll = (Wontemperatur_Soll_Setpoint.state as Number).floatValue

    var soll = OFF

    if(fSoll > fIst)
        soll = ON

    if(Heizung_Switch_Won1.state != soll)
       Heizung_Switch_Won1.sendCommand(soll.toString)

    if(Heizung_Switch_Won2.state != soll)
       Heizung_Switch_Won2.sendCommand(soll.toString)
end

rule "Wohnzimmer Tablet einschalten"
when
    Item Bewegungsmelder_Wohnzimmer_MotionStatus received update ON
then
    sendHttpGetRequest("http://192.168.178.91:8080/TabletWohnzimmerEin")
end

// Regeln Flur

rule "Taster im Flur"
when
    Item Touch_G1_Flur_Lampe received update ON
then
    Touch_G1_Flur_Lampe.sendCommand(OFF)
end

rule "Flur Nachtlicht"
when
    Item Bewegungsmelder_Flur_MotionStatus received update ON
then
    if(now.getHour > 7 && now.getHour < 17)                   // zwischen 8 Uhr und 17 Uhr kein Nachtlicht
        return;

    tFlur?.cancel
    if(XiaomiMiSmartHomeGateway_Brightness.state != ON)
        XiaomiMiSmartHomeGateway_Brightness.sendCommand(ON)
    tFlur = createTimer(now.plusSeconds(130), [ |
        XiaomiMiSmartHomeGateway_Brightness.sendCommand(OFF)
    ])
end

// Regeln Schlafzimmer

rule "Temperatur Ist mit Soll vergleichen im Schlafzimmer"
when
    Item TemperaturSchl changed or
    Item Schltemperatur_Soll_Setpoint changed
then
    if(!(TemperaturSchl.state instanceof Number)) {
        logWarn("temp","Temperatur Schlafzimmer liefert ungültigen Wert {}",TemperaturSchl.state)
        return;
    }
    val fIst = (TemperaturSchl.state as Number).floatValue

    var fSoll = 16.0

    if(Schltemperatur_Soll_Setpoint.state instanceof Number)
        fSoll = (Schltemperatur_Soll_Setpoint.state as Number).floatValue

    var soll = OFF

    if(fSoll > fIst)
        soll = ON

    if(Heizung_Switch_Schl.state != soll)
       Heizung_Switch_Schl.sendCommand(soll.toString)
end

rule "Schlafzimmerfenster"
when
    Item Schlaf_Fenster_1_OpenStatus changed or
    Item Schlaf_Fenster_2_OpenStatus changed
then
    var soll = 3
    if(Schlaf_Fenster_1_OpenStatus.state == CLOSED && Schlaf_Fenster_2_OpenStatus.state == CLOSED ) {
        soll = 18

    if(Schltemperatur_Soll_Setpoint.state != soll)
        Schltemperatur_Soll_Setpoint.sendCommand(soll)
end

// Regeln Küche

rule "Küche Bewegungsmelder"
when Item Bewegungsmelder_Kueche_MotionStatus changed
then
    if(now.getHour > 8 && now.getHour < 17) // kein Licht zwischen 8 Uhr und 17 Uhr
        return;
    tKueche?.cancel()                      // cancel existing timer
    if(newState == ON) {
        if(Touch_G1_Kueche_Lampe.state != ON)
            Touch_G1_Kueche_Lampe.sendCommand(ON)  //turn on light
        if(S20_48_LED_Leiste_Kueche_Power.state != ON)
            S20_48_LED_Leiste_Kueche_Power.sendCommand(ON)
    } else 
        tKueche = createTimer(now.plusSeconds(180), [| 
            Touch_G1_Kueche_Lampe.sendCommand(OFF)
            S20_48_LED_Leiste_Kueche_Power.sendCommand(OFF)
        ])
end

// 

rule "Gesamte Automatisierung"
when
    Time cron "0 59 23 * * ?"       // täglich um 23:59 Uhr wird die Temperatur eingestellt
then
    // Wonautomatik_Hz_ein_aus.sendCommand(1)
    // Badautomatik_Hz_ein_aus.sendCommand(1)
    Badtemperatur_Soll_Setpoint.sendCommand(17)
    Wontemperatur_Soll_Setpoint.sendCommand(17)
    Schltemperatur_Soll_Setpoint.sendCommand(18)
end

rule "Schlafen gehen/ Out of House"
when
    Item Out_of_House received command ON
then
    Touch_G2_Won_Lampe_1_1.sendCommand(OFF)
    Touch_G2_Won_Lampe_1_2.sendCommand(OFF)
    Touch_G2_Won_Lampe_2_1.sendCommand(OFF)
    Touch_G2_Won_Lampe_2_2.sendCommand(OFF)
    Touch_G1_Schlaf_Lampe.sendCommand(OFF)
    Touch_G2_Bad_Lampe_1_1.sendCommand(OFF)
    S20_Stehlampe.sendCommand(OFF)
    Badtemperatur_Soll_Setpoint.sendCommand(17)
    Wontemperatur_Soll_Setpoint.sendCommand(17)
    Schltemperatur_Soll_Setpoint.sendCommand(18)
    Out_of_House.sendCommand(OFF)
    XiaomiMiSmartHomeGateway_Brightness.sendCommand(OFF)
    Touch_G1_Kueche_Lampe.sendCommand(OFF)
    Touch_G1_Flur_Lampe.sendCommand(OFF)
end

rule "Ich bin wieder zu Hause"
when
    Item bin_wieder_da received command ON
then
    Badtemperatur_Soll_Setpoint.sendCommand(20)
    Wontemperatur_Soll_Setpoint.sendCommand(22)
    Schltemperatur_Soll_Setpoint.sendCommand(18)
    bin_wieder_da.sendCommand(OFF)

    if(now.getHour > 7 && now.getHour < 17)                 // Licht an zwischen 8:00Uhr und 17:00Uhr
       return;

    Touch_G2_Won_Lampe_1_1.sendCommand(ON)
    Touch_G2_Won_Lampe_1_2.sendCommand(ON)
    Touch_G2_Won_Lampe_2_1.sendCommand(ON)
end

// Automatisierung

rule "Cron Heizung Automatisierung Bad 1"
when
    Time cron "0 30 5 ? * MON-FRI"              // 5:30 Uhr Aufheizperiode Bad EIN (Mo-Fr)
then
    Badtemperatur_Soll_Setpoint.sendCommand(19)
end

rule "Cron Heizung Automatisierung Bad 2"
when
    Time cron "0 30 7 ? * MON-FRI"              // 8:00 Uhr Abschaltung Bad AUS (Mo-Fr)
then
    Heizung_Switch_Ba.sendCommand(OFF)
    Badtemperatur_Soll_Setpoint.sendCommand(17)
end

rule "Cron Heizung Automatisierung Wohnzimmer 1"
when
    Time cron "0 30 15 ? * MON-FRI"             // 15:30 Uhr Aufheizperiode Wohnzimmer EIN (Mo-Fr)
then
    Wontemperatur_Soll_Setpoint.postUpdate(20)
end
Wie gesagt, im Grunde muss da nichts weiter geändert werden.
Ich habe dennoch ein paar Dinge anders gelöst. Im Einzelnen: einen Wert Uninitialized gibt und gab es nie. Wenn überhaupt, gäbe es UNINITIALIZED als Wert, der aber vermutlich eher NULL wäre, oder alternativ gäbe es bei String Items auch einen Wert "Uninitialized" (man beachte die Anführungszeichen)
Besser ist aber ohnehin die Prüfung auf einen gültigen Zahlenwert instanceof Number, das ist eher zielführend.
Du hast kommentiert
postUpdate ist nur für Aktualisierungen innerhalb von openHAB (sendCommand gibt diese auch auf den Bus)
Ja, aber.
Der Punkt ist: .postUpdate() setzt den Status eines Items, während .sendCommand() einen Befehl an das Item sendet, nicht mehr und nicht weniger.
Das default Verhalten von openHAB ist dabei: ein empfangener Befehl wird an alle verknüpften Bindings weitergeleitet. Außerdem wird der Trigger Item received command ausgelöst. Weiterhin bestimmt openHAB anhand des gesendeten Befehls den mutmaßlichen neuen Status des Items und führt ein postUpdate für das Item aus. Dieses Verhalten kann mit dem Parameter autoupdate=false unterbunden werden.
Du sendest in der ersten Rule Werte an Sensoren, was vollkommen sinnlos erscheint, denn ein Sensor sollte nicht auf Befehle von außen reagieren. An dieser Stelle wäre also ein .postUpdate() wesentlich sinnvoller. Ich gehe davon aus, dass Du ab Systemstart schon einen Zahlenwert im Item stehen haben willst, selbst wenn dieser Wert nicht dem realen Messwert entspricht.
Und wie sieht es mit den Setpoints aus? Da Du die Werte ja selbst per Rule auswertest um damit die Heizung zu steuern, befürchte ich, dass auch diese gar nicht an externe Hardware gehen, sondern ausschließlich in openHAB selbst Verwendung finden, kann das sein? In diesem Fall wären auch diese Items besser mit .postUpdate() zu setzen (und zwar in allen Rules)

Nun zu den ganzen Temperaturvergleichen...
Es wäre sinnvoller, die Items geschickt zu benennen und eine Gruppe zu definieren, so:

Code: Alles auswählen

Group  gHeat "Heizung"
Number Bad_Soll          "Bad Soll"            (gHeat)
Number Bad_Ist           "Bad Ist"             (gHeat)
Switch Bad_Heat          "Bad heizen"          (gHeat)
Number Wohnzimmer_Soll   "Wohnzimmer Soll"     (gHeat)
Number Wohnzimmer_Ist    "Wohnzimmer Ist"      (gHeat)
Switch Wohnzimmer_1_Heat "Wohnzimmer 1 heizen" (gHeat)
Switch Wohnzimmer_2_Heat "Wohnzimmer 2 heizen" (gHeat)
Number Schlafzimmer_Soll "Schlafzimmer Soll"   (gHeat)
Number Schlafzimmer_Ist  "Schlafzimmer Ist"    (gHeat)
Switch Schlafzimmer_Heat "Schlafzimmer heizen" (gHeat)
Nun reicht eine Rule...

Code: Alles auswählen

rule "Heizung schalten"
when
    Member of gHeat changed
then
    if(triggeringItem.name.endsWith("Heat")) Änderung des Heizvorgangs interessiert uns nicht
        return;

    val strHK = triggeringItem.name.split("_").get(0)

    val iIst  = gHeat.members.filter[i|i.name.startsWith(strHK) && i.name.endsWith("Ist")].head
    val iSoll = gHeat.members.filter[i|i.name.startsWith(strHK) && i.name.endsWith("Soll")].head
    val iHeat = gHeat.members.filter[i|i.name.startsWith(strHK) && i.name.endsWith("Heat")]

    if(!(iIst.state instanceof Number)) {
        logWarn("temp","Temperatur {} liefert ungültigen Wert {}", strHK, iIst.state)
        return;
    }
    val fIst = (iIst.state as Number).floatValue
    var fSoll = 16.0
    if(iSoll.state instanceof Number)
        fSoll = (iSoll.state as Number).floatValue

    var soll = OFF

    if(fSoll > fIst)
        soll = ON

    iHeat.forEach[i|
        if(i.state != soll)
           i.sendCommand(soll.toString)
    ]
end
die sich um alle drei Heizkreise kümmert, und ja, sie berücksichtigt auch, dass es im Wohnzimmer mehr als einen Heizkörper gibt.

Ähnliiches kann man auch für die Überwachung der Fensterstatus machen, wenn die Namen der Items besser gewählt werden.

Aber auch da siehst Du schon von vornherein eine Optimierung, denn warum sollte man hier zwei Rules verwenden, wenn man doch ohnehin beide Status überwachen muss. Ich gehe davon aus, dass es sich bei den Kontakten um eine Meldung "geöffnet" und eine Meldung "gekippt" handelt, es wäre sinnvoll, diese Items zu einem Item zusammenzuführen. Wenn Du ein String Item dafür hernimmst, kannst Du als Texte hier CLOSED, OPEN und AJAR setzen, dann wird ein verlinktes window-Icon den Zustand auch korrekt anzeigen. Leider geht das nur über ein Proxy Item, sähe dann z.B. so aus:

Code: Alles auswählen

Group gWindows "Fenster"
Contact Bad_Open            "Badfenster geöffnet"          (gWindows)
Contact Bad_Ajar            "Badfenster gekippt"           (gWindows)
String  Bad_Window          "Badfenster"                   (gWindows)
Contact Schlafzimmer_Open   "Schlafzimmerfenster geöffnet" (gWindows)
Contact Schlafzimmer_Ajar   "Schlafzimmerfenster gekippt"  (gWindows)
String  Schlafzimmer_Window "Schlafzimmerfenster"          (gWindows)

rule "Fensterzustand"
when
    Member of gWindows changed
then
    val strRoom = triggeringItem.name.split("_").get(0)
    if(triggeringItem.name.endsWith("Window")) {
        if(newState != "CLOSED") {
            gHeat.members.filter[i|i.name.startsWith(strRoom) && i.name.endsWith("Soll")].head.postUpdate(3)
        } else {
            var soll = 17
            if(strRoom == "Schlafzimmer")
                soll = 18
            gHeat.members.filter[i|i.name.startsWith(strRoom) && i.name.endsWith("Soll")].head.postUpdate(soll)
        }
    } else {
        gWindows.members.filter[i|i.name.startsWith(strRoom) && i.name.endsWith("Window")].head.postUpdate(
            if(gWindows.members.filter[i|i.name.startsWith(strRoom) && i.name.endsWith("Open")].head.state != CLOSED) 
                "OPEN"
            else if(gWindows.members.filter[i|i.name.startsWith(strRoom) && i.name.endsWith("Ajar")].head.state != CLOSED)
                "AJAR"
            else
                "CLOSED"
        )
    }
end
Eine Rule für beide Fenster, es wird sogar berücksichtigt, dass die Solltemperatur im Schlafzimmer bei geschlossenem Fenster ein wenig höher sein soll als im Bad. Die Rule triggert sich im Übrigen selbst, weil ja alle Items in der gleichen Gruppe liegen, das macht es etwas weniger intuitiv, zu verstehen, was da passiert, aber die Grundidee sollte klar werden.

Eine "Warnung" am Rande: Ich habe die Rules nicht ausprobiert, es kann also gut sein, dass da noch Fehler lauern oder ich irgendwo einen Denkfehler gemacht habe :) aber wie ich oben ja schon erwähnt habe: im Grunde sollten Deine Rules funktionieren, abgesehen vom now.getHourOfDay, welches nun now.getHour heißt, ansonsten gibt es keine Fallen. Die Stellen im Code führen nur dazu, dass die von Dir verwendete Variable nicht korrekt initialisiert wird, ansonsten sollte der Code dennoch durchlaufen, Dein Problem liegt also erst mal darin begründet, dass Du es irgendwie geschafft hast, die Rules doppelt anzulegen, und das musst Du zuerst fixen.

Re: Rules aus Openhab 2.4 in 4.0 migrieren

Verfasst: 21. Dez 2023 18:13
von Skully
udo1toni, ich muss dir wirklich danken und vor allem meine Freundin dankt dir, weil die Heizung und das Nachtlicht im Flur wieder funktionieren :D
Mega, da hast du dir aber echt noch viel Arbeit gemacht, viel viel mehr als ich erwartet habe :)
Vielen Lieben Dank Dafür <3

Ich konnte bis jetzt nur einen Teil deines umfangreichen Beitrages abarbeiten. Das Problem mit den doppelten Rules konnte ich nun lösen. Anfangs dachte ich der Fehler liegt daran, dass ich im Rule Ordner einen zweiten Archiv Ordner angelegt habe mit alten .rules Dateien. Doch der Fehler ist viel banaler. Beim löschen aller Dateien im Rule Odner, mit anschließendem PI Neustart verschwinden die doppelten Rules. Lege ich nun die .rules Datei im Ordner ab ist alles so wie es sein soll, die Rules erscheinen nur einmal. Sobald ich nun aber die .rules Datei im Ordner mit einem Text Editor oder Visual Studio öffne, verändere und speichere erscheinen die Rules doppelt in der Übersicht. Ich kann den Fehler so beliebig oft reproduzieren.
Ja, aber.
Der Punkt ist: .postUpdate() setzt den Status eines Items, während .sendCommand() einen Befehl an das Item sendet, nicht mehr und nicht weniger.
Das default Verhalten von openHAB ist dabei: ein empfangener Befehl wird an alle verknüpften Bindings weitergeleitet. Außerdem wird der Trigger Item received command ausgelöst. Weiterhin bestimmt openHAB anhand des gesendeten Befehls den mutmaßlichen neuen Status des Items und führt ein postUpdate für das Item aus. Dieses Verhalten kann mit dem Parameter autoupdate=false unterbunden werden.
Du sendest in der ersten Rule Werte an Sensoren, was vollkommen sinnlos erscheint, denn ein Sensor sollte nicht auf Befehle von außen reagieren. An dieser Stelle wäre also ein .postUpdate() wesentlich sinnvoller. Ich gehe davon aus, dass Du ab Systemstart schon einen Zahlenwert im Item stehen haben willst, selbst wenn dieser Wert nicht dem realen Messwert entspricht.
Und wie sieht es mit den Setpoints aus? Da Du die Werte ja selbst per Rule auswertest um damit die Heizung zu steuern, befürchte ich, dass auch diese gar nicht an externe Hardware gehen, sondern ausschließlich in openHAB selbst Verwendung finden, kann das sein? In diesem Fall wären auch diese Items besser mit .postUpdate() zu setzen (und zwar in allen Rules)
Danke für die Erklärung, genau mir ging es nur darum im HABPanel einen angezeigten Wert zu bekommen. Der Wert .postUpdate() erscheint hier deutlich sinniger. Ich habs sogar noch kommentiert aber dann falsch umgesetzt. :)

Ich bin jetzt ersmla froh das alles wieder läuft. Deinen unteren Abschnitt muss ich nochmal in Ruhe durchdenken. Danke nochmal für die Überarbeitung meiner Rules. Die Tage werde ich mich mal an den Rules Blocky wagen :)

Re: Rules aus Openhab 2.4 in 4.0 migrieren

Verfasst: 21. Dez 2023 20:47
von udo1toni
Skully hat geschrieben: 21. Dez 2023 18:13 Beim löschen aller Dateien im Rule Odner, mit anschließendem PI Neustart verschwinden die doppelten Rules. Lege ich nun die .rules Datei im Ordner ab ist alles so wie es sein soll, die Rules erscheinen nur einmal. Sobald ich nun aber die .rules Datei im Ordner mit einem Text Editor oder Visual Studio öffne, verändere und speichere erscheinen die Rules doppelt in der Übersicht.
Hmm... das darf aber nicht sein...
Kann es sein, dass Dein Editor eine Backup Datei anlegt?

Was noch möglich wäre, dass es mit einer Eigenheit des Pi5 zu tun hat (wobei das schon sehr weird wäre, aber immerhin wäre das ein Unterschied zu anderen Systemen...)
Skully hat geschrieben: 21. Dez 2023 18:13 Die Tage werde ich mich mal an den Rules Blocky wagen
Blockly hat vor allem den Vorteil, dass Du über die UI nur die Befehle eingeben kannst, die auch zur Verfügung stehen. Es mag auch als Einstieg für Nicht-Programmierer intuitiver erscheinen, mir erscheint es aber umständlich.

Wenn Du komplett mit der DSL auf Kriegsfuß stehst, ist Blockly sicher ein Punkt, interessanter wären aber andere Features, die nun zu Verfügung stehen - ich empfehle hier dringend die offizielle Doku, insbesondere den getting started-Teil, die Seiten werden immer wieder aktualisiert und neue Konzepte sind auch für "alte Hasen" interessant.

Re: Rules aus Openhab 2.4 in 4.0 migrieren

Verfasst: 21. Dez 2023 22:41
von Skully
Hmm... das darf aber nicht sein...
Kann es sein, dass Dein Editor eine Backup Datei anlegt?
Also zumindest nicht in dem Rule Ordner. Vielleicht irgend wo anders :?:
Wenn Du komplett mit der DSL auf Kriegsfuß stehst, ist Blockly sicher ein Punkt, interessanter wären aber andere Features, die nun zu Verfügung stehen - ich empfehle hier dringend die offizielle Doku, insbesondere den getting started-Teil, die Seiten werden immer wieder aktualisiert und neue Konzepte sind auch für "alte Hasen" interessant.
Auf Kriegsfuß stehe ich nicht :), ich dachte nur das DSL bald abgelöst wird und dann bin ich lieber auf dem nächsten Zug als auf dem Zug, bei dem bald wieder nichst mehr läuft ;). Aber so wie es sich anhört, wird es DSL noch eine Weile geben.

Re: Rules aus Openhab 2.4 in 4.0 migrieren

Verfasst: 22. Dez 2023 00:17
von udo1toni
Skully hat geschrieben: 21. Dez 2023 22:41 ich dachte nur das DSL bald abgelöst wird und dann bin ich lieber auf dem nächsten Zug als auf dem Zug, bei dem bald wieder nichst mehr läuft ;). Aber so wie es sich anhört, wird es DSL noch eine Weile geben.
Vor der Einführung von openHAB3 gab es eine entsprechende Ankündigung, die aber schon Monate bevor openHAB3 stable wurde zurückgezogen wurde (und das ist auch gut so...) Wie gesagt soll die DSL aus Core ausgebaut werden, so dass sie anschließend - wie jede andere Scriptsprache auch - optional als Addon nachzuinstallieren ist. Sie wird aber nicht abgeschafft, auch nicht mit openHAB5 (und das dauert noch mindestens eineinhalb Jahre...).