Prevent setTimeout function from being run

I want the lights in the hallway to go out after two minutes. But if in the meantime, someone turns off the lights and then on again manually, I of course want the light to go out two minutes after the last time it was switched on, and not two minutes after the first time it was switched on.

But I clearly misunderstand how clearTimeout works…

This Javascript code:

var triggering_item = items.getItem(event.itemName)


function lampUit(lampinkwestie) {
    lampinkwestie.sendCommand("OFF")
}

if (event.newState == "ON") {
    if (event.itemName.contains("boven")) {
        try {
            clearTimeout(gangbovenuit)
        }
        catch {
            console.log('"gangbovenuit" niet kunnen vinden')
        }
        var gangbovenuit = setTimeout(lampUit, 120000, triggering_item)
        console.log(gangbovenuit)
    } else if (event.itemName.contains("gelijkvloers")) {
        try {
            clearTimeout(ganggelijkvloersuit)
        }
        catch {
            console.log('"ganggelijkvloersuit" niet kunnen vinden')
        }
        var ganggelijkvloersuit = setTimeout(lampUit, 120000, triggering_item)
        console.log(ganggelijkvloersuit)
    }
}

… leads to these logs:

22:15:34.272 [INFO ] [openhab.event.ItemStateChangedEvent  ] - Item 'verlichting_gang_gelijkvloers_switch' changed from ON to OFF
22:15:36.446 [INFO ] [openhab.event.ItemStateChangedEvent  ] - Item 'verlichting_dressing_switch' changed from OFF to ON
22:15:40.524 [INFO ] [openhab.event.ItemStateChangedEvent  ] - Item 'verlichting_gang_gelijkvloers_switch' changed from OFF to ON
22:15:40.527 [INFO ] [mation.script.file.verlichtingGang.js] - "ganggelijkvloersuit" niet kunnen vinden
22:15:40.528 [INFO ] [mation.script.file.verlichtingGang.js] - 1
22:16:13.642 [INFO ] [openhab.event.ItemStateChangedEvent  ] - Item 'verlichting_gang_gelijkvloers_switch' changed from ON to OFF
22:16:15.224 [INFO ] [openhab.event.ItemStateChangedEvent  ] - Item 'verlichting_gang_gelijkvloers_switch' changed from OFF to ON
22:16:15.226 [INFO ] [mation.script.file.verlichtingGang.js] - "ganggelijkvloersuit" niet kunnen vinden
22:16:15.229 [INFO ] [mation.script.file.verlichtingGang.js] - 2

So when logging ganggelijkvloersuit right after it’s created, we get an integer; and there are eventually two timeouts created. But when the switch is switch on a second time, variable ganggelijkvloersuit is undefined. That makes sense, because the entire rule is run “from scratch” again. But since the second run created timeoutId 2, somewhere, openHAB keeps track of the timeouts (obviously, otherwise it all wouldn’t work, I assume).

So how do I get the timeoutId from the first run into the second (and later possibly the timeoutId from the second run into the third and so on)?

You can use the cache to store values for later runs. See JavaScript Scripting - Automation | openHAB

1 Like

I find the built in openHAB timers to be a lot more flexible and has a lot more ways to determine if it’s running, has terminated, is scheduled to run, etc. But even with openHAB timers you have to save the timer and as @jswim788 points out, that’s what the cache is for. If it’s only something used by this one script, use cache.private. If it’s something that needs to be used across two or more scripts use cache.shared but be careful of what name you use as the shared cache is shared across all rules.

Thanks, that did the trick. I could/should’ve thought of that myself, I suppose. :slight_smile:

For future reference: for this simple setup, I use metadata Expiration Timer in the item now (which I was made aware of yesterday), and deleted the rule.