Home AMX User Forum NetLinx Studio

Fire a command at a specific time.

I was wondering how to fire commands at specific times now. I used to put it in the define_program section as the IF(TIME = XX:XX:XX or ??), but now I am putting it in my feedback timeline. I feel like there is a more processor friendly approach here. I might be wrong of course :). How do you guys do it?


  • Options
    ericmedleyericmedley Posts: 4,177
    I use a timeline. The nice thing about using a timeline(s) is that you can narrow your code's precision down to what you need. I've seen many people create several timelines running at "every second", "every 5 seconds","every 15 seconds", "every minute", etc... and just put the time checks in the appropriate timeline event as needed.

    My preferred method is that I convert all times to an integer starting at midnight. it's basically minutes past midnight. (ex: 3:00 AM equals 180 minutes. there are 1440 minutes per day) I then do a quick check if current time equals the "do something" time - go do it. You can easily also just do the IF(TIME = XX:XX:XX or ??) thing as well.

    Obviously the timeline needs to be repeating. Also, there have been times I've seen timelines stall for no apparent reason. I've built in a little named wait in each timeline that gets cancelled upon entering the timeline but restarted when the code section completes. The named wait has code to restart the timeline if it's killed for some reason.

    I think they've fixed the bug in FW (this seemed to happen with the first NX series) but I'm probably a little superstitious and gun-shy. Once bitten, twice shy...
  • Options
    TonyAngeloTonyAngelo Posts: 315
    ericmedley wrote: »
    I think they've fixed the bug in FW (this seemed to happen with the first NX series) but I'm probably a little superstitious and gun-shy. Once bitten, twice shy...

    An early version of NX FW had a bug that would kill timelines after like 50 days (it had to do with transitioning from 32bit to 64bit).
  • Options
    Thanks Eric. The monitor to see if the timeline is running is something I will do also.
  • Options
    a_riot42a_riot42 Posts: 1,624
    This is the one thing I will use define_program for, since its so reliable. If the program is running you are pretty much guaranteed your code gets executed. Just have to make sure you have the correct time. The only thing done in define_program is setting a variable, and whatever needs to happen occurs in code outside define_program.
  • Options
    wunde005wunde005 Posts: 4
    Maybe someone here will say this is a bad idea, but I did an auto shutdown script that ran at 11pm using a timed wait. The program calculates the number of seconds until 11pm then creates a wait that calls the auto shutdown function after that many seconds. The called function then creates a new wait for 11pm the following day when it's done.
  • Options
    viningvining Posts: 4,368
    I use an include file to handle all my date and time stuff off a single timeline. This include will then trigger functions every second, every hour, every day etc and it calls functions I keep in my main. So my second, minute day, etc events in this include trigger the function in my main and nothing else. In the main functions I'll trigger anything else I need.

    in my main I'll have something like this:
    DEFINE_FUNCTION fnMain_EveryMinute(INTEGER iMinute)
         if(iMinute % 5 == 0 || iMinute == 0)//ever 5 minutes check
         if(iMinute == 15 && sMyTime.n24Hour == 6 && !nDisable_Auto_CAM_PIR)
          nDisable_Auto_CAM_PIR = 1;
         else if(iMinute == 10 && sMyTime.n24Hour == 8 && nDisable_Auto_CAM_PIR)
          nDisable_Auto_CAM_PIR = 0;
    DEFINE_FUNCTION fnMain_EverySecond(INTEGER iSecond)
    //not these
    //      nAway[AWAY_INDX_FH1] = [dvRelaysSys1,RELAY_CHNL_FLRHEAT_1] == 0;
    //      nAway[AWAY_INDX_FH2] = [dvRelaysSys1,RELAY_CHNL_FLRHEAT_2] == 0;
    //     SEND_LEVEL dvTP_Arry,LVL_AWAY_FH1,nAway[AWAY_INDX_FH1];
    //     SEND_LEVEL dvTP_Arry,LVL_AWAY_FH2,nAway[AWAY_INDX_FH2];
    //     [dvTP_Arry,I0_FBCHNL_BYP_FLRHT_1] = nIO_Array[IO_CHNL_BYP_FLRHT_1];
    //     [dvTP_Arry,I0_FBCHNL_BYP_FLRHT_2] = nIO_Array[IO_CHNL_BYP_FLRHT_2];
         [dvTP_HAIArray,nEXTPIR_BLOCK] = nDisable_Auto_CAM_PIR;
         [dvTP_HAIArray,nEXTPIR_BLOCK_5] = nDisable_Auto_CAM_PIR_5min;
    DEFINE_FUNCTION fnMain_250ms_Clock()//main feedback / called directly from the timeline time event every 250ms
         LOCAL_VAR INTEGER nTicToc;
         LOCAL_VAR INTEGER nIntLight;
         local_var integer nSBFBRunOnce
         local_var integer nVStatRunOnce
         nWaterSense_Wet = ([dv_IO,IO_WATER_SENSE] || nWaterSenseTmr);
         [dvUI_Arry,BTN_SNOW_MELT] = nSnowMelt_On;
         [dvUI_Arry,BTN_WATER_SENSE] = nWaterSense_Wet;
         [dvUI_Arry,CHNL_OFFICE_FAN_FB] = ![dvRelays,RLY_OFFICE_FAN];
         SEND_LEVEL dvUI_Arry,LVL_OFFICE_FAN,nOfficeFan;
         nTicToc++;//control timing.  Every count is 250ms
         SWITCH(nTicToc)//create and add other clocks as needed
          CASE 1:
          CASE 3:{}
          CASE 2:
          CASE 4://every 500ms
               nTicToc = 0;
               if(nTicToc > 4)
                nTicToc = 0;

    This also has a 250ms function call to trigger things faster than every second like FB routines or triggering send queues so this one include can be used for everything on the main side in you want. It also keeps track on everything else time related I could think of like day occurrence per month which is useful for some holiday calculations and DST stuff.

Sign In or Register to comment.