Jython - timed function refuses to run

I have this rule that controls a fan in my bathroom based on humidity. The logic is to run the fan as long as FM_Kj_Badrom_Vegg > 40 and when it drops below 40 run a timer (600 seconds) and then stop the fan. The reason for the timer is to prevent flapping.
Now for some reason the function “def ventiler_kj_badrom_stopp()” never executes and I have absolutely no idea why :thinking:
The debug log shows that the timer is started and after that I only get the log that the timer is already running. There’s no errors or anything in openhab.log either.
I have timers running in other scripts just fine, but this one refuses completely! :crazy_face:

autoTimers = {} 

@rule("ventiler badrom nede ved hoey luftfuktighet")
@when("Item FM_Kj_Badrom_Vegg changed")
def ventiler_kj_badrom(event):
    if str(items.HouseAutoMode) == "ON":
        if items.FM_Kj_Badrom_Vegg > DecimalType(40) and str(items.VV_Kj_Badrom) != "ON":
            if "ventiler_kj_badrom" in autoTimers.keys(): # Reset running timer
                del autoTimers["ventiler_kj_badrom"]
            la.logDebug("jsrAutoRules",u"ventiler_kj_badrom: High humidity Kj_Badrom: {}, starting fan".format(items.FM_Kj_Badrom_Vegg))
            events.sendCommand("VV_Kj_Badrom", "ON")
        elif items.FM_Kj_Badrom_Vegg < DecimalType(40) and str(items.VV_Kj_Badrom) == "ON":
            if not "ventiler_kj_badrom" in autoTimers.keys():
                la.logDebug("jsrAutoRules",u"ventiler_kj_badrom: Low humidity, stopping fan in 600 seconds")
                autoTimers["ventiler_kj_badrom"] = Timer(600, lambda: ventiler_kj_badrom_stopp())
                la.logDebug("jsrAutoRules",u"ventiler_kj_badrom: Low humidity, stoptimer already running, ignoring")

def ventiler_kj_badrom_stopp():
    la.logDebug("jsrAutoRules",u"ventiler_kj_badrom: DEBUG REMOVING TIMER")
    del autoTimers["ventiler_kj_badrom"] # Cleanup
    if items.FM_Kj_Badrom_Vegg < DecimalType(40) and str(items.VV_Kj_Badrom) == "ON":
        events.sendCommand("VV_Kj_Badrom", "OFF")
        la.logDebug("jsrAutoRules",u"ventiler_kj_badrom: Humidity normalised, ventilation stopped")

Log output:

04-Apr-2020 08:09:11.876 [DEBUG] [org.eclipse.smarthome.model.script.jsrAutoRules   ] - ventiler_kj_badrom: Low humidity, stopping fan in 600 seconds
04-Apr-2020 08:13:19.878 [DEBUG] [org.eclipse.smarthome.model.script.jsrAutoRules   ] - ventiler_kj_badrom: Low humidity, stoptimer already running, ignoring
04-Apr-2020 08:24:41.897 [DEBUG] [org.eclipse.smarthome.model.script.jsrAutoRules   ] - ventiler_kj_badrom: Low humidity, stoptimer already running, ignoring # <-THE TIMER/FUNCTION SHOULD HAVE RUN BY NOW

change this to:

autoTimers["ventiler_kj_badrom"] = Timer(600, ventiler_kj_badrom_stopp)

(remove “lambda” AND remove the brackets)

cannot explain why but for example when you want to send a postupdate then you would have to write:

autoTimers["ventiler_kj_badrom"] = Timer(600, lambda: postUpdate("your_item", "your_command"))

Thanks for helping, but I tried that now and it made no difference, same behavior. :thinking:

oh sorry, now i see you use the python-timer. i did not get this work, too. so i use the scriptexecution-timer. this would look like:

autoTimers["ventiler_kj_badrom"] = ScriptExecution.createTimer(600, ventiler_kj_badrom_stopp)

and on top of file you need

from core.actions import ScriptExecution

what i do different is i put the body-function (def ventiler_kj_badrom_stopp()) over the function that calls it

and i think it could be necessary to declare at beginning of both functions:

global autoTimers

found it:
cange your timer command like this AND add the start-command in next line :slight_smile:

                autoTimers["ventiler_kj_badrom"] = Timer(600, ventiler_kj_badrom_stopp)

1 Like

Aaaah, of course! I’ve forgotten the .start! Thanks, I was completely blind to it! :grin: :+1: