Hi, community!
I’m switching from OH2 to 3 and try to implement my rules in the new UI The rules were written in DSL but I think I might rewrite them in Javascript. Those rules require two functionalities:
- a variable (counter) which retains its value between each execution of the rule
- a timer which I can reschedule.
Now, as far as my research goes global variables in DSL aren’t supported by the new UI but in Javascript I could use the “this.” keyword to create variables that aren’t destroyed after execution.
On the other hand, it is easily possible to reschedule a timer in DSL but I haven’t found any example how to do that in Javascript. So my question is, is it possible in any of the two languages to have both features?
This is the code as it worked on OH2. It is meant to recognise double/triple/+ presses of a button and worked fine in OH2:
var int buttonPresses = 0
var Timer buttonTimer = null
rule "personal Philips Hue ButtonO"
when
Channel 'zigbee:philips_rwl021:05000770:00178801086ca275:buttonO' triggered SHORT_PRESSED
then
// keep track of the amount of presses
buttonPresses ++
// for second and onward presses: reschedule to wait for subsequent presses
if (buttonPresses > 1){
buttonTimer.reschedule(now.plusMillis(500))
}
// after the first press: start a timer after which the rules content is executed
if(buttonPresses == 1){
buttonTimer = createTimer(now.plusMillis(500), [|
// reset the counter to avoid error when you press a button during execution of the rule
var tempPresses = buttonPresses
buttonPresses = 0;
switch(tempPresses){
case 1:{
// code for single button press
}
case 2:{
// code for double button press
}
default:{
// code for 3+ button presses
}
])
}
end
I think I could use two dummy items, one for the counter and one with expire as timer but I think expire doesn’t support less than a second (and I liked the 500ms). Also I have 5 of those switches with 4 button each so it would need a total of 40 dummy items which I would rather avoid. Is there another way I haven’t considered?
Thank you very much for your help!
EDIT:
I found a solution myself. I can simplify the code by cancelling the timer instead of reschedulling. This is the result in javascript:
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
var ScriptExecution = Java.type("org.openhab.core.model.script.actions.ScriptExecution");
var ZonedDateTime = Java.type("java.time.ZonedDateTime");
this.buttonPresses = (this.buttonPresses === undefined) ? 0 : this.buttonPresses;
this.timer = (this.timer === undefined) ? null : this.timer;
var payload = function(){
switch(this.buttonPresses){
case 1:{
// code for single button press
break;
}
case 2:{
// code for double button press
break;
}
default:{
// code for 3+ button presses
}
}
this.buttonPresses=0;
}
this.buttonPresses++;
if(timer!=null){
this.timer.cancel();
}
this.timer = ScriptExecution.createTimer(ZonedDateTime.now().plusNanos(500000000),payload)