ground_
Posts: 17
Joined: Tue Oct 14, 2014 6:13 am

scheduled functions

Mon Oct 27, 2014 12:50 am

hello all,

today i wanted to write a program which execute a few functions at a given date/time, and i can't figure out how. here is what Iwant to achieve:

I would like to let a python script run for a week, and i want it to do 3 functions every day (at a given time):
- every day at 8:00 print(" good morning")
- every day at 13:00 print (" good evening")
- every day at 19:00 print("good night")
at the end of the week I want it to end the script or shutdown the PI (anything as long as the script stops)

I looked into it all day, but i couldn't find a good solution.

I know i can set the rpi up so it starts a python script at a given time (with crontab), but i don't want that.

I also puzzled a lot with APScheduler, but it throws me a bunch of errors after I start it. (errors below if anyone interested)

Code: Select all

Traceback (most recent call last):
  File "start.py", line 64, in <module>
    menu()
  File "start.py", line 35, in menu
    options.run()
  File "/home/pi/options.py", line 243, in run
    schedulerun()
  File "/home/pi/options.py", line 122, in schedulerun
    schedule = BackgroundScheduler()
  File "/usr/local/lib/python3.2/dist-packages/APScheduler-3.0.1-py3.2.egg/apscheduler/schedulers/base.py", line 61, in __init__
    self.configure(gconfig, **options)
  File "/usr/local/lib/python3.2/dist-packages/APScheduler-3.0.1-py3.2.egg/apscheduler/schedulers/base.py", line 95, in configure
    self._configure(config)
  File "/usr/local/lib/python3.2/dist-packages/APScheduler-3.0.1-py3.2.egg/apscheduler/schedulers/background.py", line 27, in _configure
    super(BackgroundScheduler, self)._configure(config)
  File "/usr/local/lib/python3.2/dist-packages/APScheduler-3.0.1-py3.2.egg/apscheduler/schedulers/base.py", line 576, in _configure
    self.timezone = astimezone(config.pop('timezone', None)) or get_localzone()
  File "/usr/local/lib/python3.2/dist-packages/tzlocal-1.1.2-py3.2.egg/tzlocal/unix.py", line 108, in get_localzone
  File "/usr/local/lib/python3.2/dist-packages/tzlocal-1.1.2-py3.2.egg/tzlocal/unix.py", line 61, in _get_localzone
  File "/usr/local/lib/python3.2/dist-packages/pytz-2014.7-py3.2.egg/pytz/__init__.py", line 173, in timezone
  File "/usr/local/lib/python3.2/dist-packages/pytz-2014.7-py3.2.egg/pytz/lazy.py", line 150, in _lazy
  File "/usr/local/lib/python3.2/dist-packages/pytz-2014.7-py3.2.egg/pytz/lazy.py", line 97, in _lazy
  File "/usr/local/lib/python3.2/dist-packages/pytz-2014.7-py3.2.egg/pytz/__init__.py", line 1073, in <genexpr>
  File "/usr/local/lib/python3.2/dist-packages/pytz-2014.7-py3.2.egg/pytz/__init__.py", line 102, in resource_exists
  File "/usr/local/lib/python3.2/dist-packages/pytz-2014.7-py3.2.egg/pytz/__init__.py", line 95, in open_resource
  File "/home/pi/di/pkg_resources.py", line 949, in resource_stream
    self, resource_name
  File "/home/pi/di/pkg_resources.py", line 1379, in get_resource_stream
    return StringIO(self.get_resource_string(manager, resource_name))
  File "/home/pi/di/pkg_resources.py", line 1956, in StringIO
    return StringIO(*args,**kw)
TypeError: initial_value must be str or None, not bytes
Another idea is to input the start date as a string and compare it to the current date. As long as it doesn't match the current date then sleep for a second and do it again. As soon as it is the same as the current date execute another function. But I have the idea this could be done easier, am I correct?

thanks in advance!

User avatar
DougieLawson
Posts: 39126
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: scheduled functions

Mon Oct 27, 2014 8:39 am

Why not use crontab to drive a python program at various times during the day.

crontab -e

0 8 * * * /home/pi/python/saygoodmorning.py
0 13 * * * /home/pi/python/saygoodafternoon.py
0 19 * * * /home/pi/python/saygoodnight.py
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

ground_
Posts: 17
Joined: Tue Oct 14, 2014 6:13 am

Re: scheduled functions

Mon Oct 27, 2014 10:11 am

Well, i know that is possible, but as i said i dont like that for my script, mainly becausethe following reason:

When the program is running, it will also keep a log file (where is prints some variables in a text file, and one of the variable is changing at 8:00 every day). I already got this working fine.

User avatar
paddyg
Posts: 2541
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: scheduled functions

Mon Oct 27, 2014 3:57 pm

It's cropped up on this forum before. The most recent thing I commented on was this http://www.raspberrypi.org/forums/viewt ... p625521but search around.
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

ground_
Posts: 17
Joined: Tue Oct 14, 2014 6:13 am

Re: scheduled functions

Mon Oct 27, 2014 7:09 pm

thanks a lot!,

well i have decided to do it with a combination of the datetime, time.sleep and thread module. Basicly have a function which will shutdown the rpi after a time.sleep(n) (where n is the timedifference between now and the given end date). if anybody is interested here is the code:

Code: Select all

def end():
        time.sleep(endtimer)
        os.system("shutdown -r now")

Code: Select all

endtimer = int((datetime.datetime(eyear,emonth,eday,ehour,eminute)-datetime.datetime.now()).total_seconds())
         starttimer = int((datetime.datetime(syear,smonth,sday,shour,sminute)-datetime.datetime.now()).total_seconds())

    if starttimer > 0:
        print("the test start at %s/%s/%s - %s:%s f"%(smonth,sday,syear,shour,sminute,))
        threading.Thread(target = end).start()
        time.sleep(starttimer)
        runled()

klintkrossa
Posts: 81
Joined: Tue Nov 10, 2015 3:06 pm

Re: scheduled functions

Sun Apr 23, 2017 6:37 pm

Hello,
The others will be smaller. I like python3 I find that it will not return until the out side job is done I did have a cple problems with bash doing that.
here is my program modified for you.

Code: Select all

import time
import datetime

AddDay = False
ChangeTime = False
try:
    while True:
        ts = time.time()        
        date_time = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
        Y = int(datetime.datetime.fromtimestamp(ts).strftime('%Y'))
        m = int(datetime.datetime.fromtimestamp(ts).strftime('%m'))
        H = int(datetime.datetime.fromtimestamp(ts).strftime('%H'))
        if ChangeTime == True:#8:00 13:00 19:00
            if H > 8 and H < 1:
                H = 13
                print(date_time)
                print('print(" good morning")')
                pass
            elif H > 13 and H < 19:
                H = 19
                print(date_time)
                print('13:00 print (" good evening")')
                pass
            elif H > 19:
                H = 8
                AddDay = True
                print(date_time)
                print('19:00 print("good night")')
                pass
            else:
                time.sleep(60)
                pass
        d = int(datetime.datetime.fromtimestamp(ts).strftime('%d'))
        if AddDay == True:
            d = d + 1
            pass
        M = int(datetime.datetime.fromtimestamp(ts).strftime('%M'))
        S = int(datetime.datetime.fromtimestamp(ts).strftime('%S'))
        Date = datetime.datetime(Y,m,d,H,M,S)
        unixtime = time.mktime(Date.timetuple())
        diference = unixtime - ts
        if diference < 0:
            ChangeTime = True
            print('do Work')
            time.sleep(6)
            pass
        else:
            AddDay = False
            time.sleep(diference)
except KeyboardInterrupt:
    pass

The first run will not be accurate. I have not run it for 24 hours either, so there will be bugs that you will have to sort out.
Thanks
This is not like any other bulletin boards that I have been on. Been flamed on other BB's so bad I was afraid to ask.

All my Raspberry Pi's are like the Hessian artilleryman of Sleepy Hollow.

User avatar
paddyg
Posts: 2541
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: scheduled functions

Sun Apr 23, 2017 10:22 pm

You can actually use the time module on its own with struct_time in a more compact way by extracting and feeding in tuples, like this

Code: Select all

import time

AddDay = False
ChangeTime = False
try:
    while True:
        (Y, m, d, H, M, S, _, _, _) = time.localtime()
        if ChangeTime:
            if H > 8 and H < 1:
                H = 13
...
            else:
                time.sleep(60)
        if AddDay:
            d += 1
        diff = time.mktime(time.struct_time((Y, m, d, H, M, S, -1, -1, -1))) - time.time()
PS also you only need 'pass' where there is no other statement in that block.
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

klintkrossa
Posts: 81
Joined: Tue Nov 10, 2015 3:06 pm

Re: scheduled functions

Mon Apr 24, 2017 2:06 pm

Thanks that should cut some of the fat.
Yes I do know that "pass " is not needed, I use it to make the editor check my indents.

paddyg wrote:You can actually use the time module on its own with struct_time in a more compact way by extracting and feeding in tuples, like this

Code: Select all

import time

AddDay = False
ChangeTime = False
try:
    while True:
        (Y, m, d, H, M, S, _, _, _) = time.localtime()
        if ChangeTime:
            if H > 8 and H < 1:
                H = 13
...
            else:
                time.sleep(60)
        if AddDay:
            d += 1
        diff = time.mktime(time.struct_time((Y, m, d, H, M, S, -1, -1, -1))) - time.time()
PS also you only need 'pass' where there is no other statement in that block.
Thanks
This is not like any other bulletin boards that I have been on. Been flamed on other BB's so bad I was afraid to ask.

All my Raspberry Pi's are like the Hessian artilleryman of Sleepy Hollow.

Return to “Python”