Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute program at specific times

I have a program that I need to execute at certain intervals. For instance, I may want it to execute it every five minutes. I have several coordinators that communicate with several end nodes devices. The code below is on the coordinators. I need it so that if the interval is set to 5 then it runs and records information at for example: 9:05, 9:10, 9:15, 9:20, 9:25 and etc. The code I have so far is as follows:

if __name__ == '__main__':
    while True:
        try:
            r = json.read(rqst_command())
            interval = r.get('intvl')
            collect_time = r.get('c_time')
            command = r.get('cmd')
            send_stats(cmd_nodes(command, collect_time))
            time.sleep(interval)
        except Exception, e:
            print e
            print "**Top Level Exception"
            pass

The problem is that if I set the interval to 5 minutes it does not record exactly every 5 minutes. The execution time seems to slowly increase that time. So for example the above code may record as 9:05:09, 9:10:19, 9:15:29, 9:20:41, 9:25:50. The time it takes for the program to run depends on how fast the nodes communicate back.

Does anybody have any ideas on how I can change my code so that the program will execute exactly every 5 minutes?

EDIT/UPDATE

I think I have figured out a way to handle my problem. I grab the current datetime and then check to see if it is on the 5 minute mark. If it is then record the datetime and send it to the send_stats function. That way the datetime will always be exactly what I want it to be. If it is not on the 5 minute mark then sleep for awhile and then check again. I have the code mostly completed. However, I am getting the following error when I run the program: 'builtin_function_or_method' object has no attribute 'year'.

What am I doing incorrectly?

Here is my new code:

import os
import json
import datetime
from datetime import datetime
import urllib2
from urllib import urlencode
from socket import *
import time
import zigbee
import select

if __name__ == '__main__':
        while True:
            try:
                r = json.read(rqst_command())
                interval = r.get('intvl')
                collect_time = r.get('c_time')
                command = r.get('cmd')

                tempTest = True

                while tempTest == True:
                    start_time = datetime.now
                    compare_time = datetime(start_time.year, start_time.month, start_time.day, start_time.hour, 0, 0)
                    difff = int((start_time - compare_time).total_seconds() / 60)

                    if((difff % interval) == 0):
                        c_t = datetime(start_time.year, start_time.month, start_time.day, start_time.hour, start_time.minute, 0)
                        send_stats(cmd_nodes(command, collect_time), c_t)
                        tempTest = False
                    else:
                        time.sleep(30)              
            except Exception, e:
                print e
                print "**Top Level Exception"
                pass
like image 350
Linger Avatar asked Dec 26 '22 18:12

Linger


1 Answers

The below code is what ended up solving my problem. Now no matter what the interval is, it will always use the datetime starting at the beginning of each hour and incrementing by the interval. So, if the interval is 5 then the datetime shows up as for instance: 9:00:00, 9:05:00, 9:10:00, 9:15:00, 9:20:00, 9:25:00, and etc. If the interval is 3 then the datetime shows up as for instance: 5:00:00, 5:03:00, 5:06:00, 5:09:00, 5:12:00, 5:15:00, and etc. The coordinator gets the data from the end nodes and then sends the data to a remote server along with the datetime.

if __name__ == '__main__':
    last_minute = -1

    while True:
        try:
            r = json.read(rqst_command())
            print r
            command = r.get('cmd')
            interval = r.get('intvl')
            collect_time = r.get('c_time')

            tempTest = True

            while tempTest == True:
                start_time = datetime.now()
                s_minute = start_time.minute

                if(((s_minute % interval) == 0) and (s_minute != last_minute)):
                    tempTest = False
                    c_t = datetime(start_time.year, start_time.month, start_time.day, start_time.hour, start_time.minute, 0)
                    last_minute = c_t.minute

                    send_stats(cmd_nodes(command, collect_time), c_t)
                    time.sleep(1)
                else:
                    time.sleep(1)
        except Exception, e:
            print e
            print "**Top Level Exception"
            pass
like image 116
Linger Avatar answered Dec 29 '22 09:12

Linger