Like with createTimer, setTimeout and setInterval return a reference to the created timer. The big difference is these both just return a number and not an Object. But, you need that number to clear it out later same as you’d need to save a reference to an openHAB Timer created with createTimer.
If you’ve already logic like this in Rule DSL, the overall approach will be the same. You need to save what setTimeout returns as the reference to the timer and pass that to clearTimeout later on when you want to cancel it. I’m not sure it’s required to call clearTimeout on a timer that’s already run.
let myTimerRef = setTimeout(myFunc, 120000);
...
clearTimeout(myTimerRef);
Looking at the code
Having said all of that, it looks like you are trying to create a timed sequence of events. The Gatekeeper in my openHAB Rules Tools Announcements (installable through openhabian-config) would probably be a lot easier way to achieve this. One of the main purposes of almost all of openhab_rules_tools is to get people out of the business of managing timers in the first place.
The code would look something like:
const {gatekeeper} = require('openhab_rules_tools');
rules.JSRule({
name: "Actions - Execute Daystart",
description: "execute daystart when sleepstate changed to awake",
triggers: [triggers.ItemStateChangeTrigger("SleepState", "ASLEEP", "AWAKE")],
execute: (data) => {
const gk = cache.private.get('gatekeeper', () => new gatekeeper.Gatekeeper('Daystart')); // uses the private cache instead of a global variable
const presence = items.getItem("PresenceSwitch");
const overridelock = items.getItem("OverrideLock");
const bedtime = items.getItem("Bedtime");
const player = items.getItem("SqueezePlayer");
const bedroomaudio = items.getItem("Smartplug03Switch");
const kitchenaudio = items.getItem("Smartplug07Switch");
const daystartpl = items.getItem("DaystartPlaylist");
const power = items.getItem("SqueezeBedroomPower");
const volume = items.getItem("SqueezeBedroomVolume");
const shuffle = items.getItem("SqueezeBedroomShuffle");
const favorite = items.getItem("SqueezeBedroomPlayFavorite");
const play = items.getItem("SqueezeBedroomPlaypause");
let event;
(function (event) {
if (presence.state === "OFF" || overridelock.state === "ON") {
return;
}
if (bedtime.state !== "OFF") {
bedtime.sendCommand("OFF");
}
player.sendCommandIfDifferent("Bedroom");
bedroomaudio.sendCommandIfDifferent("ON");
kitchenaudio.sendCommandIfDifferent("ON");
// Gatekeeper will immediately run a command and then the timeout comes into play, so we'll schedule a noop before calling bootupTimer
gk.addCommand('PT2M', () => { }); // run a function that doesn't do anything and wait 2 minutes
gk.addCommand('PT1M', () => {
console.log("Good Morning!");
if (overridelock.state !== "OFF") {
manualoverride.sendCommandIfDifferent("OFF");
power.sendCommandIfDifferent("ON");
volume.sendCommandIfDifferent("5");
shuffle.sendCommandIfDifferent("1");
favorite.sendCommand(daystartpl);
play.sendCommandIfDifferent("ON");
console.log("Squeeze - Start playing Music in Bedroom");
}
}); // execute the anonymous function and wait one minute
gk.addCommand(0, () => {
if (volume.state < "20") {
vol = volume.state;
increase = vol + 1;
volume.sendCommand(increase);
}
}); // execute the passed in anonymous function and wait 0 msec before letting gk run the next.
})(event);
},
tags: [],
});
Without Gatekeeper, you’ll have to do the book keeping involved to keep the reference to the Timers you create if you want to clear them later. However, in this code, as written, *you don’t need to call clearInterval at all. Just get rid of all the lines that call clearInterval and it should be OK. Of course, if you decide later you need to be able to cancel this sequence of timers you won’t be able to but that doesn’t appear to be a requirement.