Another stupid Q...
dmurray14
Posts: 80
This is probably embarrassing, but I couldn't find the answer on my own (I probably just don't know what I'm looking for). Anyway, where's the timer functionality in NetLinx? For instance, lights on at 8pm? Button events are easy, but are there time-based events? I am sure this is a common task, just not sure how to do it. Bear with the stupid questions, I'm learning as I go!
Thanks,
Dan
Thanks,
Dan
0
Comments
This is my code to trigger a system cleanup at 4 in the morning:
Testing for time is something that I will normally put in the define_program section. Something like:
if(time = '23:59:59')
{
do_something_at_midnight()
}
I can't really think of a better place to put something like this than in define_program.
I don't know for certain that define_program will be executed during every distinct TIME value, but it seems to work.
That code could execute twice or many times.
Dan
As for using the TIME variable, that suffices for simple timer operations. As mentioned, you have to be careful it won't trip multiple times. What I do is set a flag, and the first time the event fires, set the flag, then put a test in the event not to fire if the flag is set. Resetting the flag is simple; I use a persistent variable that I name sToday, and put this little routine in mainline: This makes use of the other built in variable DATE. The routine will only fire when it changes, at midnight. If the sToday variable is not persistent, it will also fire when your code is updated; there are times when this behavior may be desired, but mostly, it's not.
This is sort of a long winded inside out version of what NMarkRoberts provided:
I don't see why you think it's not easy - it's only two lines of code, and the "wait one minute" line you probably already have in your mainline define_program for any number of other reasons.
BTW a timeline is the "correct" way to do it but that's considerably more than one line of code.
Yep, the owners of homes and boardrooms and lecture theatres have lots of good ideas about things that they want to automagically happen at certain absolute or relative times, until the second or third time that happens post installation, and then they want you to take out that damn silly code right now please.
eg (1) Projector timeout 60 minutes after last system activity:
Have you heard the one about the CEO who droned on for 60 minutes at the company AGM and was a bit upset when it took 5 minutes to get his powerpoint back?
And the one about the keen AV assistant who got the projector going 45 minutes before the meeting started, because no-one trusts their AV gear to start when the On button is pressed, and everyone knows CEOs can't press On buttons themselves?
eg (2) Lights out 60 minutes after last PIR movement detection:
Have you heard the one about running an examination with hundreds of students in a lecture theatre? Guess what, nobody moves for an hour!
8^)
It depends upon how you look at it. We do several flavors of automation /control systems around here.
The 'in the box' do something at such-and-so time, check-box type control systems end up not being used much because you can't put much customization into them.
With an open code system, you can pretty much dream up anything you want.
A good example of this is sunrise/sunset. With the Netlinx programming model you can really tweak what happens. Other's it's pretty much "when the sun hits the horizon it's going to happen plus or minus some minutes."
I typically use a timeline for timed events. However, here's a down-and-dirty way to trap the example from above so it'll only happen once.
I'll avoid shorthand to keep it simple.
mpullin wrote:
In the above example how the processor handle the wait? Being that it is not named does it create a seperate wait on each pass so that after the 1st 60 second delay in affect the code happens every pass of the processor with a 60 second delay. Basically creating a seperate wait 600 every pass of the program which would then evaluate the statement the number of waits held while the statement is true. Or is the processor smart enough to know that it's the same wait and ignore it. That doesn't seem likely.
pdabrowski wrote: What if it was named wait? If a named wait is pending is it ignored or re-written so that in the above example the last wait is the one executed while the if statement is true as opposed to the first wait when the statement first became true.
Hope these questions make sense to someone!
You already have a complete solution to the problems, if not to these questions, so why bother asking them again? What is the actual problem?
See this post for more information on how waits are hanlded in this situation:
http://www.amxforums.com/showthread.php?t=1592&highlight=mainline+wait
--D
Does this sound reasonable?
My understanding of unnamed WAIT's is they act like a single named one with the same name. If there is already an unnamed wait active, a call for the next one is ignored until the first is done. So, if this is all that is going on, an unnamed and a named will act identically. It's only if there is another in the program that there may be an issue, and, of course, you can't cancel it if it's unnamed.
My impression of unnamed waits is that the compiler assigns come kind of ID to each one at compile time, so an unnamed wait on a certain line cannot be started if an instance of the exact same wait is already going... which is the reason you can put WAIT 20 foo() in DEFINE_PROGRAM to do foo() every 2 seconds (poor man's timeline!)
That's along the same lines as I was thinking to 3 post ago. Essentially if a wait isn't named by us it's named by the system and everytime the system comes across a wait it checks a table or queue to see if it's if the wait name is active or not.
This seems reasonable!
Not quite - the same unnamed wait will be blocked, but a different unnamed wait isn't. They are implicitly named.
For the action I proposed the use of a wait in that instance is to make the "if(time = '23:59:59')" a oneshot instead of being run potentially multiple times..
for instance, I only want an after hours powerdown to be activated once in one second
An unnamed wait is uniquely identified by the processor internally. The same wait will not be re-stacked until its current instance has expired.
define_program
wait 10 {do something}
wait 10 {do something else}
Neither of these waits will be re-stacked until each has expired. They are absolutely discrete and the wait value is unimportant.
To return to the timer issue.....
Placing a logic flag in the time expression would be the safest way to stop re-triggering as explained below. I haven't considered a timeline here...
The following expression will potentially drive the system nuts. x is used to track the behavior.
define_program
if (time= '23:59:00')
{
x++
// Your shutdown routine would go here
}
This will result in one whole second's worth of incrementing x at processor speed (on my ni3000, x = 1984). There is an obvious problem for running the shutdown routine here.
whereas
define_program
if ((time= '23:59:00') && (!triggererd))
{
on[triggered]
x++
// Your shutdown routine would go here
wait 50 'plenty of time' off[triggered]
}
x will increment only once. The shutdown routine will obviously only execute once only and the routine waits 5 seconds then reset the [triggered] flag to re-enable tomorrow nights shutdown procedure.
Mathematically, the following should also produce a single increment, but most likely won't!
On paper, 23:59:00 will not be true any longer by the time the wait 10 has expired, therefore there should be no re-entry
if (time= '23:59:00')
{
wait 10
{
x++
// Your shutdown routine would go here
}
}
The basic maths here assumes no processing etc. and the reality is that x can indeed increment further - in my case with the ni3000 (and only with this routine running) x = 2.
If you make the wait 10 into wait 11, all is well in this case, but it a large code would most likely make this value unworkable again!
My two cents worth
I vote for this one; works perfectly.
Just to verify, any and all unnamed waits are treated exactly like a named wait, except they can not be cancelled. Only one instance of a wait (named or unnamed) can be pending in the wait queue at a time. Unnamed waits are assigned explicit names.
In the example above it does not matter how many times the program loops in one second. The shutdown routine only executes once.
This code pulses 4 relays in one second intervals.
This code pulses relay 1 only because all waits have the same name.
This code pulses 4 relays in one second intervals becasue the named waits are nested.