Python - Schedule: Run function every hour + "on the hour" - python

I'm trying to use the schedule module to do some basic scheduling in a continuously updating script.
Is there a way to set a schedule to run every "x" hours, 'on the hour'?
For example, I'd like to have a function that runs at: [1:02pm, 2:02pm, 3:02pm, 4:02pm] regardless of when I run the script in the first place. In other words, simply doing "schedule.every(1).hours.' doesn't work because I can't guarantee what time the script is run in the first place.
Thanks!

Here you can find examples for case you trying to achieve.
schedule.every().hour.at(":02").do(job)

Here is a simple script:
from datetime import datetime
import time
# scheduled hours in 24-hour format
hours = ["13:2", "14:2", "15:2", "16:2"]
# your function
def foo():
pass
while True:
now = datetime.now() # gets current datetime
hour = str(now.hour) # gets current hour
minute = str(now.minute) # gets current minute
current_time = f"{hour}:{minute}" # combines current hour and minute
# checks if current time is in the hours list
if current_time in hours:
foo()
time.sleep(60) # waits a minute until it repeats
Please note that it will check every minute at the same time when you ran it, and not when the new minute starts. (For instance, if you run it in the middle of the minute, it will check again in the middle of the next minute)

Related

How do I activate a python program at exact whole hours? (12:00:00pm, 04:00:00am)

I want to write a program that keeps running in the background and performs a certain task at each hour of the day. How do I achieve this?
for production i would add cron or schedule
# Schedule Library imported
import schedule
import time
# Functions setup
def sudo_placement():
print("Get ready for Sudo Placement at Geeksforgeeks")
def good_luck():
print("Good Luck for Test")
def work():
print("Study and work hard")
def bedtime():
print("It is bed time go rest")
def geeks():
print("Shaurya says Geeksforgeeks")
# Task scheduling
# After every 10mins geeks() is called.
schedule.every(10).minutes.do(geeks)
# After every hour geeks() is called.
schedule.every().hour.do(geeks)
# Every day at 12am or 00:00 time bedtime() is called.
schedule.every().day.at("00:00").do(bedtime)
# After every 5 to 10mins in between run work()
schedule.every(5).to(10).minutes.do(work)
# Every monday good_luck() is called
schedule.every().monday.do(good_luck)
# Every tuesday at 18:00 sudo_placement() is called
schedule.every().tuesday.at("18:00").do(sudo_placement)
# Loop so that the scheduling task
# keeps on running all time.
while True:
# Checks whether a scheduled task
# is pending to run or not
schedule.run_pending()
time.sleep(1)
You can write a if condition in a infinite while loop to check if current time is equals to your time say (12:00:00pm, 04:00:00am) or you can make use of the sleep method, it stops the exexution of your code for the specified amount of time, you must find that by calculating the difference between your time and the current time and this method does not consume much memory and cpu cycles like the previous method.
I'd advise setting up a cron job to run your python program at specific time
Try this:
from datetime import datetime # Import datetime
def schedule(time, function): # Syntax:
cur_time = datetime.strftime("%T") # time: 24 hour time hh:mm:ss (09:00:00 or 21:00:00)
if cur_time == time: # function: lampda: to_execute()
function()
def scheduled_function():
print("TEST")
while True:
schedule("15:00:00", lampda:scheduled_function()) # Schedule scheduled_function() to execute at 3:00 pm

Run python script every 5 minutes on the clock

I'm busy with an python script on a raspberry pi for a rain gauge.
The script need to count the tips of the bucket and write the total rain amount every 5 minutes to a csv file. The script does the writing now every 299.9 seconds but I want it to write every exact 5 minutes, for example: 14:00, 14:05, 14:10 and so on.
Is there anyone who could help me out?
Thanks in advance!
Use a cronjob, for raspberry pi go with crontab
https://www.raspberrypi.org/documentation/linux/usage/cron.md
You will find lots of helpful functions in the datetime module:
from datetime import datetime, timedelta
# Bootstrap by getting the most recent time that had minutes as a multiple of 5
time_now = datetime.utcnow() # Or .now() for local time
prev_minute = time_now.minute - (time_now.minute % 5)
time_rounded = time_now.replace(minute=prev_minute, second=0, microsecond=0)
while True:
# Wait until next 5 minute time
time_rounded += timedelta(minutes=5)
time_to_wait = (time_rounded - datetime.utcnow()).total_seconds()
time.sleep(time_to_wait)
# Now do whatever you want
do_my_thing()
Note that when do_my_thing() is called it will actually be fractionally after the exact time in time_to_round, because obviously computers can't do work in precisely zero time. It's guaranteed not to wake up before that time though. If you want to refer to the "current time" in do_my_thing(), pass in the time_rounded variable so that you get neat timestamps in your log file.
In the code above I've deliberately recomputed time_to_wait each time, rather than just setting it to 5 minutes after the first time. That's so that the slight delay I just mentioned don't gradually snowball after you've been running the script for a long time.

How to use Schedule module with a conditional while loop in Python

I'm trying to use the Schedule module to run a task during specific days of the week and specific hours, basically business hours. The while loop will work when the condition is true but once it's false it will not run again to see if the time frame still applies. I would have to restart the script for it to work.
I'm pretty new to Python and self taught. This is my first time posting here so please correct me if I've formatted this badly or haven't included enough information. I've tried scouring the forums to get around this particular issue I'm having but haven't found an answer; I'm probably searching wrong. It may be a simple issue but I've been wracking my brain for a few days. This is a small test portion of code that I'm trying to use for another script. Other people have recommended Cron but since this is going into a larger script, I only need a section of it to run on a task and not the whole thing.
from datetime import datetime as dt
import schedule
import time
def weekdayJob(x, i=None):
week = dt.today().weekday()
if i is not None and week < 5 and dt.now().hour in range(9,17):
schedule.every(i).minutes.do(x)
def printJob():
timestamp = time.strftime("%Y%m%d-%H%M")
print(f"test {timestamp}\n")
weekdayJob(printJob, 5)
while True:
schedule.run_pending()
time.sleep(5)
I've also tried
from datetime import datetime as dt
import schedule
import time
def weekdayJob(x, i=None):
week = dt.today().weekday()
if i is not None and week < 5 and dt.now().hour in range(9,17):
schedule.every(i).minutes.do(x)
def printJob():
timestamp = time.strftime("%Y%m%d-%H%M")
print(f"test {timestamp}\n")
x = 1
while x == 1:
weekdayJob(printJob, 1)
time.sleep(5)
while True:
schedule.run_pending()
time.sleep(5)
I figured that putting the scheduled job in the while loop would make it constantly check to see if the conditional statement was true but that doesn't seem the case. How would I make it so this script is constantly checking if weekdayJob is within the desired time frame so I don't have to restart the script.
Move the conditional statement into the printjob function, and do not use nested while loop (code here switches between business hours and non business hours). schedule tasks run continuously, but your function if-statement only runs during your defined business hours. Here running at 1minute interval (testing odd vs even minutes), you can spec your own business hours:
import datetime as dt
import schedule, time
from datetime import datetime
def printJob():
week = dt.datetime.today().weekday()
timestamp = time.strftime("%Y%m%d-%H%M")
if week < 5 and datetime.now().minute % 2 ==0: # in range(9,17):
print(f"business hours test...EVEN minutes... {timestamp}\n")
# your business hours function here...
else:
print(f'go home...test... ODD minutes... {timestamp}\n')
schedule.every(1).minute.do(printJob)
while True:
schedule.run_pending()

How to sleep my python script every hour

I want to pause my code every hour mark, i.e 11:00pm, 12:00am, 1:00am, etc.
How do I go about doing this?
You have two ways to do this:
cron method
Add a cron job for your script that gets executed every hour:
#hourly python /path/to/script
code method
Create an infinite loop within your code that runs every hour (have it sleep for 60 minutes). Or, create an infinite loop within your code that sleeps every minute, have it periodically check what time it is, and if it's on the hour with different delta hour than the current hour, have it run the job.
import datetime
import time
delta_hour = 0
while:
now_hour = datetime.datetime.now().hour
if delta_hour != now_hour:
# run your code
delta_hour = now_hour
time.sleep(60) # 60 seconds
# add some way to exit the infinite loop

Calculating the remaining time to a repeating event in Python

The scenario is as follows: given a totally arbitrary starting date in UTC there is an event that repeats every 24 hours. I need to calculate, given the current local time, how much time is left before the next event.
Ideally an ideal function would do:
time_since_start = now - start_time
remaining_seconds = time_remaining(time_since_start)
EDIT: Some clarifications. start_time defines the "epoch", the global start time since the event started repeating. Secondly, now is an arbitrary time occurring after start_time, local.
The issue is not calculating the occurrence of the next event (which would be simply adding 24 hours to start_time) but if I pick a time that falls between one event and the other, how much time is left before the next event.
I'd opt seconds as they can be quickly parsed into days, minutes and hours. Usage of datetime would be preferred (but not required) over other third-party modules as I am trying to reduce the number of dependencies.
I tried using datetime and timedelta, but the difference is always incorrect. What is the best way to proceed there?
What you want is start_time - now + (one day)

Categories

Resources