diff --git a/init.py b/init.py index 0763475..98210c0 100644 --- a/init.py +++ b/init.py @@ -50,27 +50,45 @@ def isSunUp() -> bool: now = datetime.now(city.tzinfo) return s["sunrise"] <= now <= s["sunset"] -def playAudio(filePath: str) -> None: +def playAudio(filePath: str, loop: bool = False) -> Callable[[], None]: """ Play an audio file through the Raspberry Pi's standard aux output. Args: filePath: Path to the audio file (.wav, .mp3, .ogg, etc.) + loop: Whether to loop the audio playback until stopped (default: False) + Returns: + A callable that stops the audio playback when invoked. """ if filePath.endswith(".wav"): - subprocess.Popen(["aplay", filePath], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + if loop: + # Use sox's play command with repeat for looping wav files + process = subprocess.Popen(["play", filePath, "repeat", "-"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + else: + process = subprocess.Popen(["aplay", filePath], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) else: - # Use mpg123 for mp3, or ffplay/mpv as fallback for other formats - subprocess.Popen(["mpg123", "-q", filePath], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + # Use mpg123 for mp3 + if loop: + process = subprocess.Popen(["mpg123", "-q", "--loop", "-1", filePath], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + else: + process = subprocess.Popen(["mpg123", "-q", filePath], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + + def stop(): + process.terminate() + + return stop + class WakeUpAction: offsetSeconds: int # how many seconds before alarm time to trigger action: Callable[[], None] + dismissAction: Callable[[], None] | None = None triggered: bool = False - def __init__(self, offsetSeconds: int, action: Callable[[], None]): + def __init__(self, offsetSeconds: int, action: Callable[[], None], dismissAction: Callable[[], None] | None): self.offsetSeconds = offsetSeconds self.action = action + self.dismissAction = dismissAction self.triggered = False @@ -100,9 +118,9 @@ class AlarmClock: self.addWakeUpAction(0, lambda: self.triggerAlarm()) # Activate alarm state self.setLcdText("AlarmClock Init") - def addWakeUpAction(self, offsetSeconds: int, action: Callable[[], None]): + def addWakeUpAction(self, offsetSeconds: int, action: Callable[[], None], dismissAction: Callable[[], None] | None = None): """Add a wakeup action to be triggered offsetSeconds before alarm time""" - self.wakeupActions.append(WakeUpAction(offsetSeconds, action)) + self.wakeupActions.append(WakeUpAction(offsetSeconds, action, dismissAction)) def resetWakeUpActions(self): for action in self.wakeupActions: @@ -120,6 +138,9 @@ class AlarmClock: if not self.alarmActive: return self.alarmActive = False + for action in self.wakeupActions: + if action.dismissAction: + action.dismissAction() print("Alarm dismissed") def checkWakeUpActions(self):