How to make simple alarms in Python
I'm trying to make a simple alarm with Python, but everything I've tried doesn't seem to work. I recently made a timer, but an alarm would be a little more helpful. I'm also pretty new to Python, so I don't know all the rules and syntax.
import datetime
import os
stop = False
while stop == False:
rn = str(datetime.datetime.now().time())
print(rn)
if rn == "18:00:00.000000":
stop = True
os.system("start BTS_House_Of_Cards.mp3")
When I run the file, it prints the time, but disappears completely when I want the alarm to go off.
source to share
The technical problem is that if you call datetime.now()
over and over, you cannot always call it fast enough to get all possible values. Therefore it ==
should be >=
. However, this is still not very good.
A much better way to do this is to use time.sleep()
a loop instead.
import datetime
import os
import time
now = datetime.datetime.now()
# Choose 6PM today as the time the alarm fires.
# This won't work well if it after 6PM, though.
alarm_time = datetime.datetime.combine(now.date(), datetime.time(18, 0, 0))
# Think of time.sleep() as having the operating system set an alarm for you,
# and waking you up when the alarm fires.
time.sleep((alarm_time - now).total_seconds())
os.system("start BTS_House_Of_Cards.mp3")
source to share
Use the following to round to the next minute (or adapt in seconds, etc.)
import datetime as dt
rn = dt.datetime.now()
# round to the next full minute
rn -= dt.timedelta( seconds = rn.second, microseconds = rn.microsecond)
rn += dt.timedelta(minutes=1)
To adapt to the seconds, remove seconds = rn.second
and then change minutes
on the next line toseconds
How it works
Removes seconds and microseconds from the current time, then adds 1 minute, so rounding to the next whole minute.
source to share
There is another alternative that was not mentioned that might work for you depending on your goals: signal.alarm .
signal.alarm
similar to calling the alarm (3) library on Unix, where setting the time will cause a SIGALRM signal to be sent to the parent process in the future to indicate when an asynchronous action should be performed (by default, with an unhandled signal, this is a dead process).
Example:
$ python
Python 2.7.16 (default, Mar 20 2019, 12:15:19)
[GCC 7.4.0] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import signal
>>> signal.alarm(1)
0
>>> Alarm clock
The key points when using signal.alarm (..) are as follows: - The solution is best suited for a single process application; it should not be used if you need timers for individual threads or multiprocessor systems. - You will need to set up a signal handler for the signal. signal.SIGALRM
...
The key point in signal processing is: - Asynchronous processing
This approach is pretty straightforward and very OS-centric, but it's a simple, clean approach to doing things. There are other alternatives that could potentially be used using the module kqueue
/ select
( poll
etc, on mind), other calls to the signal
module, concurrent.futures
/ multiprocessing
(some APIs have a timeout option).
Only one potential tool to use in your set of timers.
The complete solution using signal.alarm
can be found here (I adjusted the end time so I don't have to wait forever for it to complete).
$ date; python3 play_house_of_cards.py ; date
Wed 10 Jul 2019 04:54:16 PM PDT
would have run 'start BTS_House_Of_Cards.mp3'
Wed 10 Jul 2019 04:55:00 PM PDT
$
source to share