Warum schreibst Du eine vollkommen andere Regel und wunderst Dich dann, dass sie nicht wie vorgesehen funktioniert?
Du verwendest keine lokale Variable.
Das kann man machen, aber die oben vorgeschlagene Rule ist schon nicht ganz ohne Grund so definiert.
Jedes Item hat beim Systemstart den Wert NULL (ausnahmslos jedes Item). Jedes Item kann zu jedem Zeitpunkt den Zustand NULL annehmen, genauso wie den Zustand UNDEV (ausnahmslos).
Deshalb ist es best practice, sich davon zu überzeugen, dass ein Number Item auch einen gültigen Zahlenwert liefert, bevor man diesen Wert nach Number castet (... as Number).
Weiterhin schreibst Du eine Bedingung hin, ohne dazu zu schreiben, was denn passieren soll, wenn die Bedingung erfüllt ist (oder was passieren soll, wenn die Bedingung nicht erfüllt ist).
Möchtest Du, dass beide Bedingungen erfüllt sein müssen? Dann heißt das Zauberwort Bool'sche Algebra oder logische Verknüpfung.
Die DSL ist nicht Indentation aware, das heißt, Du kannst die Befehle auch in einer einzigen Zeile schreiben, das macht für den Interpreter keinen Unterschied. Der Code ist dadurch aber sehr schlecht lesbar. Die Umbrüche und Einrückungen sind also nur für das menschliche Auge gedacht.
Mit dem Design von oben, konsequent umgesetzt, wird die Rule deshalb wunderbar funktionieren.
Dein Code, anders formatiert:
Code: Alles auswählen
rule "Pool an wenn 23°C und mehr"
when
Time cron "0 30 12 * * ?"
then
if((localCurrentApparentTemperature.state as Number).floatValue < 23 )
if((localCurrentCloudiness.state as Number).floatValue > 50 )
return;
SpsDgk10RelayOutput.sendCommand(ON)
end
Die Rule wird genau das machen, was da steht: Starte täglich um 12:30:00 Uhr. Falls der als Zahl betrachtete Wert in localCurrentApparentTemperature unter 23 ist, prüfe ob der als Zahl betrachtete Wert in localCurrentCloudiness über 50 ist. Ist das der Fall, so beende die Rule.
Sende den Befehl ON an SpsDgk10RelayOutput.
Ich habe den letzten Befehl etwas abgerückt von den anderen Befehlen geschrieben, aber nur, um ihn optisch hervorzuheben. Dieser Befehl wird bei jedem vollständigen Ruledurchlauf ausgeführt.
Die Rule läuft vollständig durch, falls die Temperatur über 23 liegt.
Die Ruile läuft ebenfalls durch, falls die Temperatur unter 23 liegt, aber die Bewölkung unter 50 liegt.
Ich vermute, dass Du einen Abbruch sowohl bei zu niedriger Temperatur als auch bei Bewölkung haben möchtest. Dann musst Du lediglich ein return; einfügen.
Code: Alles auswählen
rule "Pool an wenn 23°C und mehr"
when
Time cron "0 30 12 * * ?"
then
if((localCurrentApparentTemperature.state as Number).floatValue < 23)
return;
if((localCurrentCloudiness.state as Number).floatValue > 50)
return;
SpsDgk10RelayOutput.sendCommand(ON)
end
Genauso kannst Du einen Schalter einbauen, der die Rule beendet, falls er nicht auf ON steht:
Code: Alles auswählen
rule "Pool an wenn 23°C und mehr"
when
Time cron "0 30 12 * * ?"
then
if(MeinSwitch.state != ON)
return;
if((localCurrentApparentTemperature.state as Number).floatValue < 23)
return;
if((localCurrentCloudiness.state as Number).floatValue > 50)
return;
SpsDgk10RelayOutput.sendCommand(ON)
end
Wieder sind die Leerzeilen nur zum besseren Verständnis des Codes gedacht. Man könnte das Ganze wie gesagt auch mit Bool'scher Algebra aufschreiben, aber die Zeile wird dann länglich, bzw. die Bedingung ist dann über mehrere Zeilen umgebrochen.
Code: Alles auswählen
rule "Pool an wenn 23°C und mehr"
when
Time cron "0 30 12 * * ?"
then
if(MeinSwitch.state != ON ||
(localCurrentApparentTemperature.state as Number).floatValue < 23 ||
(localCurrentCloudiness.state as Number).floatValue > 50
)
return;
SpsDgk10RelayOutput.sendCommand(ON)
end
Und wieder stehen die Umbrüche und Leerzeichen (also mehr als eines hintereinander) nur aus optischen Gründen da, das hier funktioniert genauso:
Code: Alles auswählen
rule "Pool an wenn 23°C und mehr" when Time cron "0 30 12 * * ?" then if(MeinSwitch.state != ON || (localCurrentApparentTemperature.state as Number).floatValue < 23 || (localCurrentCloudiness.state as Number).floatValue > 50) return; SpsDgk10RelayOutput.sendCommand(ON) end
Es ist nur nicht mehr gut lesbar.