Die geschweiften Klammern fassen mehrere Zeilen Code zu einer Gruppe zusammen. wenn ein Befehl sich auf einen anderen Befehl bezieht, wird immer nur ein Befehl als zugehörig betrachtet, es sei denn man gruppiert ihn:
Code: Alles auswählen
rule test
when
Item blah reveived command
then
if (test)
foo
else
bar
end
führt foo aus, falls test wahr ist, und bar falls test nicht wahr ist.
Code: Alles auswählen
rule test
when
Item blah reveived command
then
if (test){
foo
foo2
}
else
bar
bar2
end
foo und foo2 werden nur ausgeführt, wenn test wahr ist,
bar wird nur ausgeführt, wenn test nicht wahr ist.
bar2 wird immer ausgeführt, und zwar nach foo2 oder bar. bar2 gehört also eigentlich auf die erste Ebene, nicht auf die zweite Ebene.
Zu a: Wie von hr3 erwähnt, sollte der Code eigentlich so funktionieren, wie von Dir geplant. Man müsste halt mal schauen, was das Log so über die Zustandsänderungen von SchlafzimmerDecke erzählt.
Zu b: vermutlich sendet Alexa hier zuerst einen ON-Befehl. Auch da hilft sicher ein Blick in das Log. Du kannst versuchen, den Trigger auf received command zu ändern. Dazu sorgst Du dafür, dass der Status von Vent_DIM nicht automatisch geändert wird. Das Schalten erfolgt über ein Number Item.
Code: Alles auswählen
Dimmer Vent_DIM "Ventilator" <fan_ceiling> (gDevices) ["Lighting"] {autoupdate="false"}
Number Vent_Level "Ventilator" <fan_ceiling> (gDevices)
Code: Alles auswählen
rule "Ventilator_Dimming"
when
Item Vent_DIM received command
then
var Number ventLevel = Vent_Level.state as Number
if(receivedCommand instanceof Number){ //der Befehl ist eine Zahl
if ( receivedCommand == 0 ) ventLevel = 0
if ( receivedCommand > 0 && receivedCommand <= 33 ) ventLevel = 1
if ( receivedCommand > 33 && receivedCommand <= 66 ) ventLevel = 2
if ( receivedCommand > 66 ) ventLevel = 3
}
else // der Befehl kommt als Befehl
switch receivedCommand {
case INCREASE : {
ventLevel += 1 // oder ventLevel = ventLevel + 1
if (ventLevel > 3) ventLevel = 3
}
case DECREASE : {
ventLevel -= 1 // oder ventLevel = ventLevel - 1
if (ventLevel < 0) ventLevel = 0
}
case OFF : ventLevel = 0
case ON : {
if (ventLevel == 0) ventLevel = 1
else ventLevel = 3
}
}
if (ventLevel != (Vent_Level.state as Number)) {
switch ventLevel {
case 0 : VentilatorCom.sendCommand("PowerOff")
case 1 : VentilatorCom.sendCommand("FanLow")
case 2 : VentilatorCom.sendCommand("FanMed")
case 3 : VentilatorCom.sendCommand("FanHigh")
}
Vent_Level.postUpdate(ventLevel)
Vent_DIM.postUpdate(33 * ventLevel)
}
end
Der Code sieht jetzt erheblich länger aus, was aber vor allem daran liegt, dass ich nicht weiß, was nun wirklich als Befehl von Alexa kommt (ich habe keines).
Die Rule deckt alle Möglichkeiten ab. Kommt eine Zahl als Befehl, wird die Ventilatorstufe entsprechend gesetzt. Kommen die Befehle ON/OFF/INCREASE/DECREASE wird die passende Stufe gesetzt. Im Fall von ON habe ich es so definiert, dass, falls der Ventilator aus war, er auf niedriger Stufe gestartet wird. Falls erneut ein ON-Befehl erfolgt, schaltet er direkt in die höchste Stufe.
Am ende der Rule wird der eigentliche Befehl gesendet.
Schau im Log nach, was Alexa als Befehl schickt. Falls nur die Befehle ON/OFF/INCREASE/DECREASE kommen, kannst Du den ersten Teil der Rule weg lassen. Ein Vent_DIM.postUpdate() ist dann auch nicht zwingend notwendig. Falls nur konkrete Zahlen kommen, kannst Du den mittleren Teil der Rule weg lassen.
PS: Die Ventilatorstufe als Zahl zwischen 0 und 3 abzubilden erleichtert das Errechnen der zu wählenden Stufe. Damit alles konsistent bleibt, sollte man dann auf der Sitemap als item Vent_Level mit einem Selection oder Switch Widget mit mapping verwenden (vier Schaltflächen sollten hin passen).
Code: Alles auswählen
Switch item = Vent_Level mappings=[0="Off",1="Low",2="Med",3="High"] // entweder oder
Selection item = Vent_Level mappings=[0="Off",1="Low",2="Med",3="High"] // entweder oder
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet