I’m getting my head around timers using Jython. Some time back @5iver recommended I use the ScriptExecution.createTimer method, rather than the native Jython threading.Timer. Naturally, therefore, I’ve started my experiments by using threading.Timer…
- Dim lights over a long period of time…
- Using a re-useable python function that can be called from within a ‘normal’ rule…
- With a timer…
- And be able to cancel the dimming at any time.
I can do 1, 2 and 3. I’m kind of stuck on 4.
Here’s what I currently have (abridged) that addresses goals 1, 2, 3 and 4 (sort of):
From within a rule, I call the function
toggle_dimming. Into the function I pass the name of the Item that I want to dim, and the length of time over which dimming should occur.
import personal.personal_functions reload(personal.personal_functions) from personal.personal_functions import toggle_dimming ... toggle_dimming(dimmer_item_name, t)
personal_functions includes the following:
from core.jsr223.scope import ir from core.jsr223.scope import events from threading import Timer ... #Initialise a timer dimming_timer = None ... def toggle_dimming(item_name, interval): global dimming_timer if dimming_timer is None: #if timer is None: start_dimming(item_name, interval) else: stop_dimming() ... def start_dimming(item_name, interval): #Grab current dimming level current_dimmer_level = int(str(ir.getItem(item_name).state)) global dimming_timer if current_dimmer_level is not 0: #Adjust dimmer events.sendCommand(ir.getItem(item_name), str(current_dimmer_level-1)) #Start timer dimming_timer = Timer(interval, start_dimming, [item_name, interval]) dimming_timer.start() ... def stop_dimming(): global dimming_timer if dimming_timer is not None and dimming_timer.isAlive(): dimming_timer.cancel() dimming_timer = None
This is all great. It’s not particularly robust, but I can start and stop the dimming process.
However, I have to lights that I want to dim, independently, using this same python function. Currently, the timer is attached to the global variable
dimming_timer, which means I can’t start a second dimming process without interfering with the first (I think).
What I’d like to do is create a timer handle back in the rules file, which I then pass through to
toggle_dimming as an argument. The
toggle_dimming function would then use this argument to check whether the timer exists or not.
- If it doesn’t, continue on to
start_dimming, passing the handle through once more as an argument.
start_dimmingwould then use that handle for the timer itself.
- If it does, continue on to
stop_dimming, passing the handle through once more as an argument to enable stopping of the timer.
I’ve tried creating a handle in the rules file. I’ve tried importing a handle from the module file (
personal_functions). Neither work - I guess the handle only becomes a timer when inside of
start_dimming, and because it’s no longer a global variable, nothing else knows about it, or can access it. Additionally, when creating the timer, I can’t add the handle argument into the lambda because it doesn’t yet exist as a timer object - it will only exist once the timer is created, but then it’s too late to pass an argument to the lambda (or is it?)
So I guess the question is: how can I transfer a timer handle between rules and functions, without using a global variable?
(For completeness, and to put @5iver at ease, I am also experimenting with the ScriptExecution.createTimer method. This topic is more to improve my understanding of the underlying basics, I guess…)