Die Rules sind in dieser Form aus verschiedenen Gründen ned so dolle
Formal:
logInfo() erzeugt Zeilen im zugehörigen log File (default ist das
openhab.log). ABER: Man kann dieses Logging abschalten, und zwar über die Karaf Konsole im laufenden Betrieb. Das geht getrennt für jeden definierten Logger. Der Logger wird
mit durch den ersten String definiert, in den Rules also
"rules", was halt etwas sehr allgemein ist. Besser wäre z.B.
"autoshutter", der entsprechende Logger hieße dann
org.openhab.core.model.script.autoshutter (der Teil vor dem letzten Punkt ist für alle Logs aus Rules heraus identisch).
Mittels
Code: Alles auswählen
log:set WARN org.openhab.core.model.script.autoshutter
werden also alle logInfo()-Zeilen spezifisch für diese beiden Rules unterdrückt. Deshalb scheint ein Konstrukt
if(log) logInfo() nicht sehr elegant - zumal es mit einem Neustart der Rule Engine verbunden ist - die rules-Datei muss neu eingelesen werden...
Dann die Schachtelung der verschiedenen Bedingungen... es wäre sinnvoller, die Bedingungen in der Form abzuarbeiten, dass, wenn eine Bedingung für das Fahren nicht erfüllt ist, die Meldung geloggt wird und anschließend die Rule direkt beendet wird (dafür gibt es den Befehl
return;)
Das Konstrukt, sich über einen Datumsstempel zu merken, ob die Rule am aktuellen Tag bereits ausgeführt wurde, ist auch... mäßig elegant. Einfacher, und genauso wirkungsvoll ist es, sich in einer globalen Variablen zu merken, wenn die Fahrt stattgefunden hat (wahlweise könnte man das auch über Items lösen, die können persistiert werden). Man benötigt lediglich eine Mini Rule, welche um 0 Uhr die Merker zurücksetzt - und falls man schon so eine Mitternachtsrule hat, kann man den Reset auch mit dort rein packen.
Beide Rules werden durch unterschiedliche Ereignisse des selben Bindings getriggert, beide Ereignisse treten immer (!) zeitgleich auf. Es werden also immer (!) beide Rules gestartet, unmittelbar. Es gibt keinen Grund, warum man immer zwei Rules gleichzeitig laufen lässt - eine reicht (allerdings hat das Konsequenzen für die Abbruchbedingungen...).
Es ist recht wichtig, die Status von Items immer auf einen sinnvollen Inhalt zu prüfen. Die beiden Items Azimuth und Sonnenstand enthalten zwei Winkel. in allen aktuellen openHAB Versionen wird also nach der Zahl ein ° stehen (und das ist für openHAB ein wichtiger Unterschied). Man muss das erst los werden, damit Vergleiche mit anderen Zahlen funktionieren. Ähnliches gilt auch für Temperatur (°C) und Bewölkung (%).
Ausnahme: z.B. ein Rollershutter Item liefert immer eine Zahl (genauso ein Dimmer Item) - eigentlich sollten die auch eine Prozentwert liefern, sind aber keine UoM Items

(UoM -> Units of Measurement, die Einheit wird mit übergeben und auch berücksichtigt, z.B. 0°C == 32°F - das geht tatsächlich!)
Ich gehe anhand der Fehlermeldung davon aus, dass hier der eigentliche Fehler liegt (Wert wird nicht korrekt gewandelt) Könnte auch damit zusammenhängen, dass hier fälschlich ein intValue genutzt wird, die Winkel Azimuth und Sonnenstand (eigentlich Elevation) sind aber vom Typ Float.
Hier mal eine aktuell überarbeitete Variante unter Berücksichtigung aller obigen Punkte.
Zu beachten wäre noch, dass es diverse Grenzwerte gibt, die korrekt gesetzt wein müssen. Man könnte default Werte direkt in der Rule einpflegen (bei der Konstantendefinition hinter dem
else des ternären Operators)
Code: Alles auswählen
// Globale Variablen müssen vor der ersten Rule definiert werden!
var Boolean bAutoZu = false
var Boolean bAutoAuf = false
rule "Rollos West abfahren"
when Item Azimuth changed
then
logInfo('autoshutter', 'Rolloautomatik (West) - Regel wurde gestartet')
if(bAutoAuf && bAutoZu) {
logInfo('autoshutter', 'Rolloautomatik (West) - Stoppe die Rule frühzeitig, da bereits beide Bewegungen stattfanden.')
return;
}
// lokale Variablen definieren
var Boolean bNoAutoZu = false
var Boolean bNoAutoAuf = false
// lokale Konstanten definieren
val fAzimuthIs = if(Rolloautomatik_azimuth_start.state instanceof Number) (Rolloautomatik_azimuth_start.state as Number).floatValue else 0.0
val fElevationIs = if(Sonnenstand.state instanceof Number) (Sonnenstand.state as Number).floatValue else 0.0
val fTempIs = if(LocalWeatherAndForecastCurrentTemperature.state instanceof Number) (LocalWeatherAndForecastCurrentTemperature.state as Number).floatValue else 0.0
val iCloudIs = if(LocalWeatherAndForecastCurrentCloudiness.state instanceof Number) (LocalWeatherAndForecastCurrentCloudiness.state as Number).intValue else 100
val fAzimuthMin = if(Azimuth.state instanceof Number) (Azimuth.state as Number).floatValue else 270.0
val fElevationMin = if(Rolloautomatik_elevation_ende.state instanceof Number) (Rolloautomatik_elevation_ende.state as Number).floatValue else 90.0
val fTempMin = if(Rolloautomatik_temp_min.state instanceof Number) (Rolloautomatik_temp_min.state as Number) else 23.0
val iCloudMax = if(Rolloautomatik_wolken_max.state instanceof Number) (Rolloautomatik_wolken_max.state as Number).intValue else 0
val iZiel = if(Rolloautomatik_zielwert.state instanceof Number) (Rolloautomatik_zielwert.state as Number).intValue else 0
// Prüfen der Bedingungen für ab
if(Rolloautomatik.state != ON) {
logInfo('autoshutter', 'Rolloautomatik (West) - kein Abwärts, da Automatik generell nicht aktiv')
bNoAutoZu = true
}
if(bAutoZu && !bNoAutoZu) {
logInfo('autoshutter', 'Rolloautomatik (West) - kein Abwärts, da bereits ausgeführt')
bNoAutoZu = true
}
if(fAzimuthMin > fAzimuthIs && !bNoAutoZu) {
logInfo('autoshutter', 'Rolloautomatik (West) - kein Abwärts, Azimuth ({}) hat noch nicht Schwellwert ({}) erreicht', fAzimuthIs, fAzimuthMin)
bNoAutoZu = true
}
if(fTempIs <= fTempMin && !bNoAutoZu) {
logInfo('autoshutter', 'Rolloautomatik (West) - kein Abwärts, Mindest-Temperatur ({}°C) wurde nicht erreicht; aktuelle Temperatur: {}°C',fTempMin, fTempIs)
bNoAutoZu = true
}
if(iCloudIs > iCloudMax && !bNoAutoZu) {
logInfo('autoshutter', 'Rolloautomatik (West) - kein Abwärts, Maximalbewölkung ({}%) wurde überschritten ({}%)', iCloudMax, iCloudIs)
bNoAutoZu = true
}
if(fElevationIs >= fElevationMin && !bNoAutoZu) {
logInfo('autoshutter', 'Rolloautomatik (West) - kein Abwärts, Elevation für abfahren ({}°) ist kleiner als aktuelle ({}°)', fElevationMin, fElevationIs)
bNoAutoZu = true
}
if(!bNoAutoZu) { // Rollos runterfahren
logInfo('autoshutter', 'Rolloautomatik (West ab) - Rollos werden abgefahren')
gruppeRolladen_West.members.forEach[i|
if((i.state as Number) <= iZiel) {
logInfo('autoshutter', 'Rolloautomatik (West ab) - Fahre Rollladen auf {}%: {}', Rolloautomatik_zielwert.state, i.name)
i.sendCommand(iZiel)
} else
logInfo('autoshutter', 'Rolloautomatik (West ab) - Rollladen ist bereits weiter geschlossen ({}%) als er geschlossen werden sollte und wird daher ignoriert', i.state)
]
sendBroadcastNotification("Verschattung Westseite aktiv") //Pushnachricht
bAutoZu = true
return;
}
// prüfen der Bedingungen für hoch
if(Rolloautomatik_oeffnen.state != ON) {
logInfo('autoshutter', 'Rolloautomatik (West) - kein Aufwärts, da Automatik generell nicht aktiv')
bNoAutoAuf = true
}
if(fElevationIs > fElevationMin && !bNoAutoAuf) {
logInfo('autoshutter', 'Rolloautomatik (West) - kein Aufwärts, da Elevation ({}°) nicht kleiner als eingestellte Elevation ({}°) war',fElevationIs,fElevationMin)
bNoAutoAuf = true
}
if(!bAutoZu && !bNoAutoAuf) {
logInfo('autoshutter', 'Rolloautomatik (West) - kein Aufwärts, da heute noch kein Abwärts stattfand. Demzufolge kann auch kein automatisches Öffnen gewollt sein')
bNoAutoAuf = true
}
if(bAutoAuf && !bNoAutoAuf) {
logInfo('autoshutter', 'Rolloautomatik (West) - kein Aufwärts, da heute bereits ein automatisches Wiederhochfahren stattfand')
bNoAutoAuf = true
}
if(!bNoAutoAuf) { // Rollos wieder hoch
logInfo('autoshutter', 'Rolloautomatik (West hoch) - Rollos werden hochgefahren')
gruppeRolladen_West.members.forEach[i|
val iPosRel = Math.abs((i.state as Number).intValue - iZiel) // Abweichung des aktuellen Ladens von Zielwert
if(iPosRel <= 5) {
logInfo('autoshutter', 'Rolloautomatik (West hoch) - Fahre Rollladen {} auf 0%', i.name)
i.sendCommand(0)
} else
logInfo('autoshutter', 'Rolloautomatik (West hoch) - Fahre Rollladen {} nicht auf 0%, da dieser zwischenzeitlich manuell verändert wurde', i.name)
]
sendBroadcastNotification("Verschattung Westseite beendet") //Pushnachricht
bAutoAuf = true
}
end
rule "Reset globale Variablen"
when
Time cron "1 0 0 * * ?"
then
bAutoAuf = false
bAutoZu = false
end
Ich habe in diesem Thread genau die angesprochenen Probleme schon mehrfach erläutert
Bei so langen Threads ist es oft keine gute Idee, den Inhalt des ersten Post zu nutzen (ja, das wird in anderen Foren gerne anders gehandhabt, da werden solche Posts immer mal wieder auf den neuesten Stand gebracht - hier aber eher nicht)
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet