Seite 3 von 5

Re: Beeinflussung einer Rule durch eine andere Rule ?

Verfasst: 24. Mär 2020 11:33
von PeterA
Hi Udo,

dann Prüft also dieser Teil der Rule ob überhaupt genug gültige Werte vorhanden sind um den Durchschnitt zu berechnen...

Re: Beeinflussung einer Rule durch eine andere Rule ?

Verfasst: 24. Mär 2020 13:52
von PeterA
udo1toni hat geschrieben: 24. Mär 2020 11:24 Der Code iteriert über alle Gruppenmitglieder. Er prüft für jedes Item, ob es einen gültigen Wert zurück liefert. Ist das der Fall, zählt er einen Zähler hoch und addiert den Wert zu einer Summe. Zum Schluss prüft der Code, ob der Wert höher als der bisherige Maximalwert ist und ersetzt diesen, falls das der Fall ist.

Da ich es eh nicht lassen kann, einige kleine Anmerkungen:
  1. Es gibt eine Methode forEach, welche sich hier anbietet, um über die Gruppe zu iterieren.
  2. Wann immer möglich, sollte man keine Primitives verwenden. Hier also lieber Integer statt int
  3. Die Definition als Integer ist nur für lfCnt zwingend, da sonst die Abkürzung lfCnt+=1 fehlschlägt. lfAvg könnte dann natürlich auch einen Dezimalbruch enthalten, das sollte aber für die Funktion keine Rolle spielen.
    Allgemein wird davon abgeraten, alle Variablen auf einen Typ festzulegen, da sich dadurch die Startzeit erhöht. Ob das stimmt, weiß ich nicht. ;)
  4. Die Rule sendet bei jedem Trigger ein postUpdate, gleichgültig, ob das notwendig ist oder nicht.
Hier die optimierte Version:

Code: Alles auswählen

rule "PluggitLuftfeuchtigkeit"                              // bestimme die durchschnittliche und maximale Luftfeuchte
when
    Member of gPluggit_Items_Luftfeuchtigkeit changed
then
    var lfSumme=0
    var lfMax=0
    var Integer lfCnt=0
    gPluggit_Items_Luftfeuchtigkeit.members.filter[i |
    i.state instanceof Number].forEach[ item |
        lfCnt+=1
        val Integer lf=(item.state as Number).intValue
        lfSumme+=lf
        if (lf>lfMax) lfMax=lf
    ]
    var lfAvg
    if (lfCnt>=2)                                           // nur bei mindestens 2 Werten ist es sinnvoll, die Werte zu betrachten
        lfAvg=(lfSumme/lfCnt).intValue
    else {
        lfAvg=0
        lfMax=0
    }
    newState=Pluggit_Status_Luftfeuchte.state
    if (lfMax>=65 || lfAvg>=60) newState=ON                 // Bei mehr als max 65% oder avg 60% Luftfeuchtigkeit lüfte.
    else if (lfMax<60) newState=OFF                         // fällt die Luftfeuchte aller Stationen unter 60%, wurde genug gelüftet
    if(Pluggit_Status_Luftfeuchte.state != newState)
        Pluggit_Status_Luftfeuchte.postUpdate(newState)
end
Hi Udo,
wie immer bis ins letzte ausgefeilt :) Hut AB!

In der original Rule von Tokamak und in der überarbeiteten von Dir wird, wenn getriggert wird, ein "postUpdate" ausgelöst.
Hier bräuchte ich aber ein "sendCommand". Kann ich ich das austauschen ?

Re: Beeinflussung einer Rule durch eine andere Rule ?

Verfasst: 24. Mär 2020 14:00
von udo1toni
Ja, sicher. Welche Aktion ausgeführt wird, ist der Rule egal :)

Mir fällt grade auf, dass da das Schlüsselwort var fehlt... Ich hab das mal in meinem vorigen Posting korrigiert.

Re: Beeinflussung einer Rule durch eine andere Rule ?

Verfasst: 24. Mär 2020 15:22
von PeterA
Es rattert weiter :)

Nun kann ja der Fall eintreten das die Lüftung steht weil die Luftfeuchte unter 60% liegt aber Nahrung zubereitet wird :)
Hier könnte ich die Energieaufnahme der Umlufthaube in WATT erfassen (mit einem Shelly) um dann die Lüftung wieder anlaufen zu lassen
um die Gerüche hinaus zubekommen. Sagen wir mal für 60min.
Der Trigger müsste sein: Wenn die Energieaufnahme einmal über X WATT liegt ist die Umlufthaube eingeschaltet worden und dann müsste ja auch ein Timer laufen ?

Ich vermute das müsste dann als weitere "ODER" Bedingung in diese Zeile:

Code: Alles auswählen

if (lfMax>=65 || lfAvg>=60) newState=ON 
Aber wie bekomme ich die Lüftung dann wieder abgeschaltet ?

Re: Beeinflussung einer Rule durch eine andere Rule ?

Verfasst: 24. Mär 2020 15:41
von udo1toni
Das passiert in der Zeile drunter.

Code: Alles auswählen

else if (lfMax<60) newState=OFF // fällt die Luftfeuchte aller Stationen unter 60%, wurde genug gelüftet
Gesendet von meinem SM-G973F mit Tapatalk



Re: Beeinflussung einer Rule durch eine andere Rule ?

Verfasst: 24. Mär 2020 15:47
von PeterA
udo1toni hat geschrieben: 24. Mär 2020 15:41 Das passiert in der Zeile drunter.

Code: Alles auswählen

else if (lfMax<60) newState=OFF // fällt die Luftfeuchte aller Stationen unter 60%, wurde genug gelüftet
Gesendet von meinem SM-G973F mit Tapatalk
Alles klar...
ist hier ein Timer oder die Verwendung des Expire Bindings besser ?

Re: Beeinflussung einer Rule durch eine andere Rule ?

Verfasst: 24. Mär 2020 15:51
von udo1toni
Weder noch. Eingeschaltet wird, wenn die durchschnittliche Luftfeuchte über 60% liegt oder der Spitzenwert über 65%. Ausgeschaltet wird, wenn alle Sensoren weniger als 60% melden. Weder in der einen noch in der anderen Richtung ändern sich die Werte so schnell, dass Du eine zu hohe Schaltfrequenz fürchten musst.

Gesendet von meinem SM-G973F mit Tapatalk





Re: Beeinflussung einer Rule durch eine andere Rule ?

Verfasst: 24. Mär 2020 15:55
von PeterA
udo1toni hat geschrieben: 24. Mär 2020 15:51 Weder noch. Eingeschaltet wird, wenn die durchschnittliche Luftfeuchte über 60% liegt oder der Spitzenwert über 65%. Ausgeschaltet wird, wenn alle Sensoren weniger als 60% melden. Weder in der einen noch in der anderen Richtung ändern sich die Werte so schnell, dass Du eine zu hohe Schaltfrequenz fürchten musst.

Gesendet von meinem SM-G973F mit Tapatalk
Meine Frage jetzt bezog sich auf das "zwischenzeitliche" Einschalten der Lüftung für zb 60min wenn in der Küche gekocht wird um
dann die Gerüche zu entfernen.

Re: Beeinflussung einer Rule durch eine andere Rule ?

Verfasst: 24. Mär 2020 16:01
von udo1toni
Ah. Dafür müsste man eine Priorisierung vorsehen. Die Automatik Rule muss abgebrochen werden, solange die Anlage zwangsweise läuft. Beim Umschalten auf Automatik muss geprüft werden, ob die Anlage nicht weiterhin aktiv sein muss. Wenn die Anlage abgeschaltet wird, muss ein Wiedereinschalten für einige Zeit verhindert werden. Also nicht mal eben so...

Gesendet von meinem SM-G973F mit Tapatalk


Re: Beeinflussung einer Rule durch eine andere Rule ?

Verfasst: 24. Mär 2020 20:15
von PeterA
udo1toni hat geschrieben: 24. Mär 2020 11:24 Der Code iteriert über alle Gruppenmitglieder. Er prüft für jedes Item, ob es einen gültigen Wert zurück liefert. Ist das der Fall, zählt er einen Zähler hoch und addiert den Wert zu einer Summe. Zum Schluss prüft der Code, ob der Wert höher als der bisherige Maximalwert ist und ersetzt diesen, falls das der Fall ist.

Da ich es eh nicht lassen kann, einige kleine Anmerkungen:
  1. Es gibt eine Methode forEach, welche sich hier anbietet, um über die Gruppe zu iterieren.
  2. Wann immer möglich, sollte man keine Primitives verwenden. Hier also lieber Integer statt int
  3. Die Definition als Integer ist nur für lfCnt zwingend, da sonst die Abkürzung lfCnt+=1 fehlschlägt. lfAvg könnte dann natürlich auch einen Dezimalbruch enthalten, das sollte aber für die Funktion keine Rolle spielen.
    Allgemein wird davon abgeraten, alle Variablen auf einen Typ festzulegen, da sich dadurch die Startzeit erhöht. Ob das stimmt, weiß ich nicht. ;)
  4. Die Rule sendet bei jedem Trigger ein postUpdate, gleichgültig, ob das notwendig ist oder nicht.
Hier die optimierte Version:

Code: Alles auswählen

rule "PluggitLuftfeuchtigkeit"                              // bestimme die durchschnittliche und maximale Luftfeuchte
when
    Member of gPluggit_Items_Luftfeuchtigkeit changed
then
    var lfSumme=0
    var lfMax=0
    var Integer lfCnt=0
    gPluggit_Items_Luftfeuchtigkeit.members.filter[i |
    i.state instanceof Number].forEach[ item |
        lfCnt+=1
        val Integer lf=(item.state as Number).intValue
        lfSumme+=lf
        if (lf>lfMax) lfMax=lf
    ]
    var lfAvg
    if (lfCnt>=2)                                           // nur bei mindestens 2 Werten ist es sinnvoll, die Werte zu betrachten
        lfAvg=(lfSumme/lfCnt).intValue
    else {
        lfAvg=0
        lfMax=0
    }
    var newState=Pluggit_Status_Luftfeuchte.state
    if (lfMax>=65 || lfAvg>=60) newState=ON                 // Bei mehr als max 65% oder avg 60% Luftfeuchtigkeit lüfte.
    else if (lfMax<60) newState=OFF                         // fällt die Luftfeuchte aller Stationen unter 60%, wurde genug gelüftet
    if(Pluggit_Status_Luftfeuchte.state != newState)
        Pluggit_Status_Luftfeuchte.postUpdate(newState)
end
Hi Udo,

VsCode mault leider rum :(

Code: Alles auswählen

{
	"resource": "/Volumes/openHAB-conf/rules/test.rules",
	"owner": "_generated_diagnostic_collection_name_#0",
	"code": "org.eclipse.xtext.xbase.validation.IssueCodes.invalid_mutable_variable_access",
	"severity": 8,
	"message": "Cannot refer to the non-final variable lfCnt inside a lambda expression",
	"startLineNumber": 10,
	"startColumn": 9,
	"endLineNumber": 10,
	"endColumn": 14
}

Code: Alles auswählen

{
	"resource": "/Volumes/openHAB-conf/rules/test.rules",
	"owner": "_generated_diagnostic_collection_name_#0",
	"code": "org.eclipse.xtext.xbase.validation.IssueCodes.incompatible_types",
	"severity": 8,
	"message": "Type mismatch: cannot convert from int to Integer",
	"startLineNumber": 10,
	"startColumn": 14,
	"endLineNumber": 10,
	"endColumn": 16
}

Code: Alles auswählen

{
	"resource": "/Volumes/openHAB-conf/rules/test.rules",
	"owner": "_generated_diagnostic_collection_name_#0",
	"code": "org.eclipse.xtext.xbase.validation.IssueCodes.invalid_mutable_variable_access",
	"severity": 8,
	"message": "Cannot refer to the non-final variable lfSumme inside a lambda expression",
	"startLineNumber": 12,
	"startColumn": 9,
	"endLineNumber": 12,
	"endColumn": 16
}

Code: Alles auswählen

{
	"resource": "/Volumes/openHAB-conf/rules/test.rules",
	"owner": "_generated_diagnostic_collection_name_#0",
	"code": "org.eclipse.xtext.xbase.validation.IssueCodes.invalid_mutable_variable_access",
	"severity": 8,
	"message": "Cannot refer to the non-final variable lfMax inside a lambda expression",
	"startLineNumber": 13,
	"startColumn": 16,
	"endLineNumber": 13,
	"endColumn": 21
}

Code: Alles auswählen

{
	"resource": "/Volumes/openHAB-conf/rules/test.rules",
	"owner": "_generated_diagnostic_collection_name_#0",
	"code": "org.eclipse.xtext.xbase.validation.IssueCodes.invalid_mutable_variable_access",
	"severity": 8,
	"message": "Cannot refer to the non-final variable lfMax inside a lambda expression",
	"startLineNumber": 13,
	"startColumn": 23,
	"endLineNumber": 13,
	"endColumn": 28
}

Code: Alles auswählen

{
	"resource": "/Volumes/openHAB-conf/rules/test.rules",
	"owner": "_generated_diagnostic_collection_name_#0",
	"code": "org.eclipse.xtext.xbase.validation.IssueCodes.missing_type",
	"severity": 8,
	"message": "Type cannot be derived",
	"startLineNumber": 15,
	"startColumn": 9,
	"endLineNumber": 15,
	"endColumn": 14
}

Code: Alles auswählen

{
	"resource": "/Volumes/openHAB-conf/rules/test.rules",
	"owner": "_generated_diagnostic_collection_name_#0",
	"code": "org.eclipse.xtext.xbase.validation.IssueCodes.incompatible_types",
	"severity": 8,
	"message": "Type mismatch: type int is not applicable at this location",
	"startLineNumber": 17,
	"startColumn": 15,
	"endLineNumber": 17,
	"endColumn": 39
}

Code: Alles auswählen

{
	"resource": "/Volumes/openHAB-conf/rules/test.rules",
	"owner": "_generated_diagnostic_collection_name_#0",
	"code": "org.eclipse.xtext.xbase.validation.IssueCodes.incompatible_types",
	"severity": 8,
	"message": "Type mismatch: type int is not applicable at this location",
	"startLineNumber": 19,
	"startColumn": 15,
	"endLineNumber": 19,
	"endColumn": 16
}
Schon wieder Böhmische Dörfer für mich... :/