ECMA 2021 script - Motion Sensor On/Off delay switch lights OFF

Working ECMA 2021 script.

  • Define ItemNames for variable ItemToSwitch and MotionSensor.
  • Trigger should be when you motion sensor change its state.
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleID);
//var ScriptExecution = Java.type("org.openhab.core.model.script.actions.ScriptExecution");  
//var ZonedDateTime   = Java.type("java.time.ZonedDateTime");  

// Timer delay value minutes
var TimerMinutes = 3;
// Init timer if not already active
this.timer = (this.timer === undefined) ? null : this.timer;

// Item name in registry to switch
var ItemToSwitch = 'Steckdose_F_schalter';
// Motion Sensor name in registry that detects motion
var MotionSensor = 'IKEABewegungmelder1_Bewegung'

// Will be called when timer reached the timer delay value of TimerMinutes
function turnOff() {
    return function () {
		items.getItem(ItemToSwitch).sendCommand('OFF');
		sleep(200);
		console.info(`Status of "${ItemToSwitch}" is "${items.getItem(ItemToSwitch).state}"`);
		this. Timer = null;
	};
}

function sleep(msec) {
  const e = time.toZDT(msec);
  while(time.toZDT().isBefore(e)) { }
}

switch (event.itemState.toString().toLowerCase()) {
	case "on": {
      console.info(`Motion detected from "${event.itemName.toString()}" status is "${items.getItem(MotionSensor).state}"`);
      if (items.getItem(ItemToSwitch).state != 'ON') {
        items.getItem(ItemToSwitch).sendCommand('ON');
        sleep(200);
        console.info(`Status of "${ItemToSwitch}" is "${items.getItem(ItemToSwitch).state}"`);
      }
      else{
        console.info(`Status of "${ItemToSwitch}" is already "${items.getItem(ItemToSwitch).state}"`);    
      }
      // Cancel a defined timer that would call the turnOff() function if motion has been detected.
      if (this.timer != null) {
        this.timer.cancel();
        console.info(`Timer "${this.timer}" canceled: "${this.timer.isCancelled()}"`);
        this.timer = null;
      } 
      break;
	}
	case "off": {
      if (this.timer == null ) {
        // create timer to delay the turn off sendcommand for additional TimerMinutes.
        this.timer = actions.ScriptExecution.createTimer(time.ZonedDateTime.now().plusMinutes(TimerMinutes), turnOff());
		sleep(200);
        logger.info("Timer ExecTime: {}", this.timer.getExecutionTime());
        console.info(`No motion anymore from "${event.itemName.toString()}" status is "${items.getItem(MotionSensor).state}"`);
        console.info(`Switching "${ItemToSwitch}" in "${TimerMinutes}" minute(s) off.`);
      }
      break;
	}
}