There may be a misconception here on what is a scene (if not, my apologies).
A scene will run only for a brief moment in time, long enough to execute any LUA code associated with the scene, set the lights/devices as specified in the scene, and to set timers for any delayed actions. Then the scene terminates.
So it does not make sense to “abort” a scene, since it is not actually running anymore. And unfortunately, there is no way to abort the timers that were set for the delayed actions.
(Note that returning false in the LUA code stops the scene from executing at all.)
So a more detailed explanation of what your are trying to do, along with a complete listing of the LUA code associated with the scene in question may help us.
I tried to test the code and it failed.
But... I'm beginning to think that all the code I write fails. For instance the following code also fails:
Code: [Select]
return luup.is_night()
Can someone poitn me in the right direction?
If you are testing your code using Apps → Develop apps → Test Luup code (Lua), it will report a failure if your code returns false. Just one of those things.
The main problem with your code is that you are using a device-type instead of a serviceId in your luup.variable_get(…) statement.
Thnx guys.
I figured it out. I was using the wrong service name.
I thought I could copy paste it from my advanced tab in my device, but now I use the tool from RexBeckett this makes thing a lot easier.
I am also new to cresting scenes, new z-wave setup also. I now have z-wave controlling all lighting in my house and want to start setting up some sime automation. I know Pleg is there but i would rather learn how To do it the hard way.
Anyway, from the previous comments i see that you cannot cancel a scene delay whilst timing so the obvious question is what is the best way.
Should i ignore the time delay and build this into the luup instead. That way it could be inteupted.
My first scene is really simple. If i turn on the garage light it starts a 30 min timer. If the light is turned off the timer cancels and the scene stops. If the light is left on the timer completes and the light s turned off.
What is the best way to do something simple like this? If i start using good programming, hopefully i will keep using it.
i used to program in c++ but that ways lifetimes ago and i am now worse than rusty.
My first scene is really simple. If i turn on the garage light it starts a 30 min timer. If the light is turned off the timer cancels and the scene stops. If the light is left on the timer completes and the light s turned off.
What is the best way to do something simple like this? If i start using good programming, hopefully i will keep using it.
You cannot cancel a programmed timer but you can just do nothing when you get the callback. For example, if the light is already off, don’t turn it off again.
A slightly more sophisticated approach is to keep track of the timer calls that you make. Each call can have a string argument which is provided to the callback function. If you use an incrementing number in this argument, you can ignore any callbacks other than the most recent.
There is some more detail and example code in Delayed Actions.
If you use Scene with delayed action … or luup.call_delay without implementing some persistence model … than if Vera restarts during the interval
the timed functions will be lost.
PLEG has built-in persistence for timed events (using schedules and delayed actions) so they survive a Vera Restart.
The longer the delay the more likely you will get hit by this!
Richard,
So far I do not know of any vera restarts but either way I get the point and it is something to beware of.
Rex,
Can I have a public timer function which can be retriggered every time the light goes on an use this to turn off lights when it times out. Or is this basically what you said. I will read up on different timer calls to try to understand it all.
Cheers.
You can have a public timer in LUA … But you have to deal with the issue of restarting it.
LUA timers can’t be canceled or restarted … so you need to reference count the timer.
On trigger start the timer and increment the reference count.
When timer finishes decrement the reference count … it’s actually finished when the reference count goes to zero.
I wanted to do something similar with my Garage light. I also wanted to be able to extend the time with subsequent pushes of the scene on button. So I came up with this:
function GarageTimer(stuff)
gGarageTimer = gGarageTimer - 1
if (gGarageTimer > 0) then
luup.call_timer("GarageTimer", 1, "15", "", "")
elseif (gGarageTimer == 0) then
luup.call_action("urn:upnp-org:serviceId:SwitchPower1","SetTarget",{ newTargetValue="0" },37)
end
end
if (gGarageTimer == nil) then
gGarageTimer = 0
end
if (gGarageTimer <= 0) then
luup.call_timer("GarageTimer", 1, "15", "", "")
end
if (gGarageTimer < 20) then
gGarageTimer = 20
elseif (gGarageTimer < 40) then
gGarageTimer = 40
elseif (gGarageTimer < 120) then
gGarageTimer = 120
else
gGarageTimer = 0
end
You will notice that the garage timer restarts itself every 15 seconds. Because it is a short duration loop, it won’t run long if you kill the light prior to the actual timeout.
Push the on button again within 15 seconds, and you extend the time the light is on. Push the on button after the 15 seconds will reset the time to the beginning. The above code uses 5 minutes, 10 minutes, and 30 minutes for the light duration.
If you want to turn the light off in other code, rather than explicitly turning off the light, your just set the global gGarageTimer to 1, so that the next iteration of the loop will turn off the light (and stop looping)
Best Home Automation shopping experience. Shop at Ezlo!