Home AMX User Forum NetLinx Studio

Basic Q: What's the most effic way to do time-of-day events?

I've got to do multiple time-of-day events - should I put an IF in mainline to start an absolute timeline at midnight? Seems fairly wasteful to run a constant IF test....

Apologies for the basic question.
-Bill

Comments

  • Why not using i!-Scedule? It can be configured for >200 different events, which can be launched individually by configuring time definitions (daily, weekly, every hour, every working day, if Christmas, Easter and February the 30st will be at the same day (ok, maybe THIS will not work ;))). It can be used with the Sceduling Engine standalone and doesn't need the user interface to configure. If a sceduled time is reached, the Scedule engine will give you PUSH(es) to execute the event(s) you have defined before.

    Time can be based on timeservers, but will also work fine with the NI master's internal clock.
  • Here is a good format
    youstra wrote:
    I've got to do multiple time-of-day events - should I put an IF in mainline to start an absolute timeline at midnight? Seems fairly wasteful to run a constant IF test....

    Apologies for the basic question.
    -Bill

    There is nothing wrong putting your time evaluations in mainline (Define_Program section.)

    I would use the following:
    Define_Program
    
    Select
    {
      Active(TIME=02:00:00):  // Run at 2AM
      {
        Wait 11
        {
          // Code to run here
        }
      }
      Active(TIME=12:00:00):  // Run at noon
      {
        Wait 11
        {
          // Code to run here
        }
      }
    }
    

    Make sure you put in the Wait 11 so that the timed event only runs once. This is because the Active statement will be evaluated many times over the course of a second and the Wait will only be started once. Without the Wait the code under the Active would run many many times depending how large your program is.

    Just for fun, try this.
    Define_Variable
    
    Integer nCount
    Integer nStart
    Integer nStop
    
    Define_Start
    
    nStart = ATOI(Right_String(TIME,1))
    
    Define_Program
    
    nStop = ATOI(Right_String(TIME,1))
    
    // This will run every 10 seconds
    If (nStop = nStart)
    {
      nCount++
    }
    
    If (nCount>0 and nStop=ATOI(Right_String(TIME,1))+9) // Reset counter
      nCount = 0
    

    Check the value of nCount to see how many times Define_Program loops in one second.
  • Spire_JeffSpire_Jeff Posts: 1,917
    B_Clements wrote:

    Make sure you put in the Wait 11 so that the timed event only runs once.

    I was under the impression that the Wait has to be named to avoid being run more than once. But, I might be mistaken as I haven't worked with this type of scenario lately.

    Jeff
  • DHawthorneDHawthorne Posts: 4,584
    i!-Schedule has a pretty serious overhead to it. If you have lots of headroom and memory space, it's fine. But it's often like killing mosquitos with a shotgun for simpler applications. I would use the i!-TimeManager instead, unless there is a need for the client to adjust scheduled events.

    I do it like this:

    I set a flag, first of all, for every event, and test a new day to reset them. Depending on the precision needed, I then run a flag checker on a timelijne. If I only need to-the-minute precision, the timeline fires every 60 seconds, for example. Inside the timeline is a function call that does something like this (this example uses to-the-minute precision):
    DEFINE_CONSTANT

    NUMBER_TIMED_EVENTS = 10 // Number of events we are tracking

    DEFINE_VARIABLE

    VOLATILE CHAR bEventTripped[NUMBER_TIMED_EVENTS] ;
    VOLATILE INTEGER nTimers[NUMBER_TIMED_EVENTS][2] ; // hour and minute for each event

    DEFINE_FUNCTION CHAR bTimedEvents()
    {
    LOCAL_VAR CHAR sToday[10] ;
    STACK_VAR CHAR nCount ;

    IF(sToday <> DATE) // Day has changed, reset all the flags
    {
    FOR(nCount = 1; nCount <= NUMBER_TIMED_EVENTS; nCount ++)
    bEventTripped[nCount] = FALSE ;

    sToday = DATE ; // update day tracking
    }

    FOR(nCount = 1; nCount <= NUMBER_TIMED_EVENTS; nCount ++)
    {
    IF((TIME_TO_HOUR(TIME) >= nTimers[nCount][1]) && (TIME_TO_MINUTE(TIME) >= nTimers[nCount][2]) && !bEventTripped[nCount])
    {
    // DO EVENT HERE - call whatever event the timer is for
    bEventTripped[nCount] = TRUE ; // set flag so it doesn't repeat forever
    }
    }
    }
    You can add whatever other handling is needed for manual resets or recurring events. This is a very simple code block, and has practically no overhead to maintain. You can even (and I have done this) make a way for the client to adjust the times from the panel simply by changing the values in nTimers, giving much more flexibility to it, and you can add another set of flags to turn events on and off semi-permanently.

    Edit: Pft! What happened to QUOTE blocks preserving whitespace??
  • GSLogicGSLogic Posts: 562
    I agree with Dave, i!-Schedule is a hog and not very flexable!
    I use a Timeline that triggers every 60 seconds with an array for the user defined days (selected_days[7]), if a day IS selected then I'll look at the user defined TIME.
  • Spire_Jeff wrote:
    I was under the impression that the Wait has to be named to avoid being run more than once. But, I might be mistaken as I haven't worked with this type of scenario lately.

    Jeff

    Jeff,

    A Wait does not need to be named unless you need to cancel it. Otherwise they both behave the same.

    Brian
Sign In or Register to comment.