Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repeat a sound/action every certain time

I'm trying to write a Python program that reproduces a sound every certain hour, but it doesn't really work. When I test the code and the specified time comes, it will keep repeating the sound forever.

Here is the code:

import os
from datetime import datetime

now = datetime.now()
currentHour = now.hour
currentMin = now.minute

#I also tested with if but it didn't work
while currentHour==15 and currentMin==33:
    os.system("aplay /home/pi/sound.wav") #Plays the sound thru aplay
like image 859
user3348491 Avatar asked May 22 '26 20:05

user3348491


2 Answers

Your logic is wrong.

First of all, the while loop will most likely end in the first iteration and you want the program to continue till you tell it to.

In addition to that, you don't update the now variable inside the loop, which is basically a bad idea.

For example, this code will continue running and when it is 15:33, a sound will be played only once.

myHour = 15
myMin = 33
is_played = False
while True:
    now = datetime.now()
    currentHour = now.hour
    currentMin = now.minute
    if currentHour == myHour and currentMin == myMin and not is_played:
        is_played = True
        os.system("aplay /home/pi/sound.wav")
    if currentHour != myHour or currentMin != myMin:
        is_played = False

Xiaotian Pei suggested a great idea, to efficiently use your CPU resource, lets use the Timer module:

def to_play_sound(hour, min):
    now = datetime.now()
    currentHour = now.hour
    currentMin = now.minute
    if currentHour == hour and currentMin == min and not is_played:
        is_played = True
        os.system("aplay /home/pi/sound.wav")
    if currentHour != myHour or currentMin != myMin:
        is_played = False
while True:
    t = Timer(30.0, to_play_sound, [15, 33])
    t.start()

J.F. Sebastian has also suggested a great idea:

import datetime
import subprocess
while True:
    now = datetime.now()
    # compute `deadline`
    while True:
        deadline = now.replace(hour=hour, minute=min)
        if deadline > now:
            break
        else:
            deadline += datetime.timedelta(1)
    sleep_until(deadline) # sleep
    subprocess.check_call(['aplay', '/home/pi/sound.wav']) # play the sound!

Read how sleep_until was implemented here.

like image 56
boaz_shuster Avatar answered May 25 '26 08:05

boaz_shuster


It's a complement to @bshuster13 's answer.

What you need is actually a timer. Using a busy loop and detect if it's the right time to do something is not a good idea. Take a look at Timer in python. I think you will come up with a better solution.

like image 33
Xiaotian Pei Avatar answered May 25 '26 08:05

Xiaotian Pei



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!