Reschedule timer / global variables

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)

It’s exactly the same

Rules DSL

buttonTimer.reschedule(now.plusNanos(500000))

JavaScript

this.buttonTimer.reschedule(now.plusNanos(500000));

ZonedDateTime doesn’t support plusMillis (for JavaScript or Rules DSL) so those will have to change anyway.

I should have just tried it instead of searching for examples. Sometimes it’s simpler than I think. So, sorry to have bothered you but thank you very much for your help!