receivedCommand ist eine implizite Variable, die nur in Rules zur Verfügung steht, die auf received command getriggert haben. Deine Rule triggert jedoch auf ein Channel Event LONG_PRESSED.
Punkt 1: Woher soll die Rule wissen, in welche Richtung gedimmt werden soll?
Punkt 2: Ich gehe ganz stark davon aus, dass Du eigentlich möchtest, dass der Dimmer kontinuiertlich dimmt, solange Du die Taste festhältst. Das bedeutet, Du brauchst zwei verschiedene Events, nämlich LONG_PRESSED und RELEASED (Also Taste wurde losgelassen).
Also Punkt 3: Steht RELEASED (oder ein anderes Event, welches diese Bedeutung hat) zur Verfügung? Falls nicht, kannst Du den Versuch sofort abbrechen und Dir etwas anderes überlegen...
Sollte es aber ein Event RELEASED geben, so müsste Deine Rule immer noch dafür sorgen, dass das einmalige Ereignis LONG_PRESSED in eine kontinuierliche Aktion mündet, welche dann eben abgebrochen werden muss, sobald RELEASED empfangen wird. Das sähe z.B. so aus:
Code: Alles auswählen
// Globale Variablen müssen vor der ersten Rule definiert werden!
var Boolean bDimDir = false // false = dunkler, true = heller
var Timer tDim = null // ein Schleifentimer
rule "LED_WZ_Indirekt dimmen"
when
Channel "shelly:shelly1:e8db84d44d7d:relay#button" triggered // egal welches Ereignis
then
tDim?.cancel // laufenden Timer abbrechen
if(receivedEvent != LONG_PRESSED) // falls nicht LONG_PRESSED
return; // Rule beenden
bDimDir = !bDimDir // Dimrichtung beim Dimstart umkehren
tDim = createTimer(now.plusNanos(10000000), [| // lege einen Timer 10 mSec in der Zukunft an
var Integer iLevel = 0 // erzeuge ein lokalea Integer Objekt
if(LED_WZ_Indirekt_ColorWhite.state instanceof Number) // Falls der Status vom Typ Number ist
nLevel = (LED_WZ_Indirekt_ColorWhite.state as Number).intValue // fülle das Objekt mit dem Integerwert
if(bDimDir) // falls heller dimmen
iLevel += 2 // erhöhe den Level
else // ansonsten
iLevel -= 2 // verringere den Level
if(iLevel > 100) { // Prüfe auf Überschreiten, falls ja
iLevel = 100 // setze auf Maximum
bDimDir = false // und setze Dimmrichtung auf dunkler
} else if(iLevel < 0) { // ansonsten prüfe auf Unterschreiten, falls ja
iLevel = 0 // setze Minimum
bDimDir = true // und setze Dimmrichtung auf heller
}
LED_WZ_Indirekt_ColorWhite.sendCommand(iLevel) // Sende Befehl an die Lampe
tDim.reschedule(now.plusNanos(100000000)) // und plane den Timer erneut in 100 mSec
])
end
Die Rule ist für openHAB3 bestimmt. Wegen der globalen Variablen muss sie zwingend über eine *.rules Datei angelegt werden.
a += x und a -= x sind Abkürzungen für a = a + x und a = a - x. Diese stehen nur beim Typ Integer zur Verfügung. Da der Dimmer ohnehin ein Integer erwartet, bietet es sich an, von Anfang an ein Integer zu nutzen.
Die Rule triggert auf jedes Ereignis des Schalters. In jedem Fall wird ein eventuell gerade laufender Timer abgebrochen. Falls das Ereignis nicht LONG_PRESSED heißt, ist die Rule schon wieder vorbei (man könnte hier aber durchaus auch noch auf weitere Ereignisse verzweigen, z.B. SHORT_PRESSED)
Anschließend wird die Boolean Variable bDimDir negiert, sie wechselt also von true nach false oder umgekehrt.
Danach wird ein Timer mit einem Codeblock erzeugt und die Rule ist beendet. Es ist ganz wichtig, zu verstehen, dass die Rule den Code nicht ausführt! Sie trägt den Codeblock lediglich im Scheduler ein und setzt einen Startzeitpunkt, 10 Millisekunden in der Zukunft.
Nach 10 Millisekunden startet der Scheduler den Codeblock. Zunächst wird eine lokale Integer Variable erzeugt, in der anschließend der aktuelle Level gespeichert wird. Nun wird abhängig von bDimDir entweder addiert oder subtrahiert. Anschließend prüft der Code auf Über- oder Unterschreiten der Grenzwerte, korrigiert den Wert gegebenenfalls und setzt auch gleich die logische Dimmrichtung - Wenn der obere Grenzwert erreicht wurde, will man wieder abdimmen und umgekehrt (ansonsten lässt man natürlich die Taste einfach los).
Anschließend wird der Befehl an die Lampe geschickt. Ein postUpdate ändert lediglich den Wert des Items, hat aber auf die Lampe keinen Einfluss!
Zum Schluss plant der Timer sich selbst erneut ein, und zwar 100 Millisekunden in der Zukunft. Das heißt, pro Sekunde wird der Timer etwa 10 mal durchlaufen (etwa, weil die Abarbeitung der Befehle ja auch Zeit kostet), bei einer Schrittweite von 2 ergeben sich 5 Sekunden für einen vollständgigen Dimmvorgang in einer Richtung.
Das Ganze funktioniert, wie oben erwähnt, nur, falls beim Loslassen auch ein Event ausgelöst wird. Das .plusNanos() ist leider die einzige Möglichkeit, einen Timer unterhalb einer Sekunde zu planen. Unter openHAB2.5 kannst Du stattdessen auch .plusMillis(100) schreiben.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet