Es ging mir nicht darum, das Programm umzustellen
sondern einen Weg zu zeigen, wie man die Bool'sche Logik aufbauen kann.
Die korrekte Zeile lautet natürlich
Code: Alles auswählen
if((Azimuth.state as Number) > 271.8 && (Azimuth.state as Number) < 287.6 && (Clouds.state as Number) > (Bewoelkung.state as Number)){
Wobei die Reihenfolge der einzelnen Bedingungen irrelevant ist.
Logisch betrachtet gibt es eine Voraussetzung, die "linear" verläuft (Sonnenstand zwischen Grenzwerten) und eine andere Voraussetzung, die variabel ist (Bewölkungsgrenzwert überschritten).
Deshalb habe ich die Reihenfolge der Vergleiche verdreht, aber das ist echt nur Geschmacksache.
Wenn man ganz sauber arbeiten will, muss man vor der Verwendung des Castings auf Gültigkeit prüfen:
Code: Alles auswählen
if(!(Azimuth.state instanceof Number)) return;
if(!(Clouds.state instanceof Number)) return;
if(!(Bewoelkung.state instanceof Number)) return;
var boolean bInBorders = false
if((Azimuth.state as Number) > 271.8 && (Azimuth.state as Number) < 287.6) bInBorders = true
if(bInBorders && (Clouds.state as Number) > (Bewoelkung.state as Number)){
// bla
} else {
// blie
}
Die Logikfunktionen aufzuteilen, lohnt sich eigentlich nur, wenn man die Werte mehrfach in unterschiedlicher Konstellation benötigt.
Das Abfangen ungültiger Werte (... instanceof ...) ist immer dann sinnvoll, wenn man nicht sicher weiß, ob die Werte gültig sind, das ist vor allem bei Regeln wichtig, die mit
System started triggern (eventuell wurde der letzte Wert noch nicht durch die Persistence wiederhergestellt), oder auch in Fällen, wo Sensoren evtl. unzuverlässig arbeiten.
Manchmal möchte man vielleicht einen Default Wert setzen, falls kein gültiger Wert vorliegt. Dann sollte man immer im Hinterkopf haben, dass openHAB
multithreaded und
asynchron arbeitet.
sendCommand() und
postUpdate() starten jeweils ein Unterprogramm, welches sich um den Job kümmert, die Rule wartet aber nicht auf die Ausführung sondern macht einfach weiter. Beispiel:
Code: Alles auswählen
if(!(Azimuth.state instanceof Number)) Azimuth.postUpdate(15)
if((Azimuth.state as Number) > 14) logInfo("test","Azimuth größer 14")
Wenn Azimuth keinen gültigen Wert hat, wird die Rule vermutlich mit einer Nullpointer Exception abbrechen. Zwar wird umgehend ein gültiger Zahlenwert nach Azimuth geschrieben, jedoch wird auch unmittelbar im Anschluss eben jener Wert gelesen. Durch das asynchrone Modell weiß man aber nicht, ob der Schreibvorgang bereits beendet wurde. Sicher funktioniert das nur, wenn man stattdessen Variablen verwendet:
Code: Alles auswählen
var Number nAzimuth = 15
if(Azimuth.state instanceof Number) nAzimuth = Azimuth.state as Number
if(nAzimuth > 14) logInfo("test","Azimuth größer 14")
Da wir hier mit einer Variablen arbeiten, können wir sicher sein, dass diese zum Zeitpunkt des Vergleichs auch mit einem gültigen Wert gefüllt ist.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet