import subprocess from typing import Optional from alarm import BaseAlarmClock, AlarmState from datetime import time, datetime, timezone, timedelta from time import sleep # from pynput import keyboard import keyboard as kb # SONG = ".model/Viennese_Poets.mp3" # Simple Alarm Clock has 5 functionalities: # 1. Set Alarm Time - Set the time for the alarm to sound, does NOT make the alarm active # 2. Start Alarm - Make the alarm active, which will run the timer until it reaches the specified time # 3. Sound Alarm - Play the sound for the alarm # 4. Snooze Alarm - Stop the alarm sound and wait for some time to play the alarm again # 5. Stop Alarm - If the alarm is active or is playing, stop the alarm (deactivate state) # ALARM_TIME = datetime.combine( # datetime.today(), # # (datetime.today() + timedelta(days=1)).date(), # time(16, 40, 0) # ).astimezone(tz=timezone.utc) # SNOOZE_KEY = keyboard.Key.up # ALARM_OFF_KEY = keyboard.Key.esc SNOOZE_SEC = 5 class SimpleAlarmClock(BaseAlarmClock): def __init__(self, wake_time: Optional[datetime] = None): super().__init__(wake_time) # self._alarm = None def set_alarm(self, wake_time: datetime) -> datetime: print(f"SETTING ALARM to: {wake_time}") return super(SimpleAlarmClock, self).set_alarm(wake_time) def start_alarm(self) -> None: print("STARTING ALARM") super(SimpleAlarmClock, self).start_alarm() def sound_alarm(self) -> None: print("SOUNDING ALARM") # if not self._alarm: # self._alarm = subprocess.Popen(["omxplayer", "--no-keys", SONG, "&"]) super(SimpleAlarmClock, self).sound_alarm() def snooze_alarm(self) -> None: if self.current_state is AlarmState.PLAYING: print("SNOOZING ALARM") # print(f"{self._alarm.pid}") # if self._alarm is not None: # subprocess.Popen(["sudo", "kill", f"{self._alarm.pid}"]) # self._alarm = None super(SimpleAlarmClock, self).snooze_alarm() sleep(SNOOZE_SEC) print("UN-SNOOZING ALARM") self.sound_alarm() def stop_alarm(self, deactivate: bool = True) -> None: print("STOPPING ALARM") # if self._alarm is not None: # subprocess.Popen(["sudo", "kill", f"{self._alarm.pid}"]) # self._alarm = None if self.current_state is AlarmState.PLAYING: print("STOPPED PLAYING ALARM") super(SimpleAlarmClock, self).stop_alarm() def alarm_check_reached(self, current_time: datetime) -> bool: # print(f"{self.wake_time}") # print(f"{current_time}") return super(SimpleAlarmClock, self).alarm_check_reached(current_time) def run_simple_alarm_mode(self): self.start_alarm() kb.add_hotkey("esc", lambda: self.stop_alarm()) kb.add_hotkey("space", lambda: self.snooze_alarm()) while not self.alarm_check_reached(datetime.now(tz=timezone.utc)): print(f"ALARM SLEEPING @: {datetime.now(tz=timezone.utc)}") sleep(1) self.sound_alarm() while self.current_state is not AlarmState.DEACTIVATED: pass # with keyboard.Events() as events: # for event in events: # if event.key == ALARM_OFF_KEY: # self.stop_alarm() # break # elif event.key == SNOOZE_KEY: # self.snooze_alarm() # break if __name__ == '__main__': alarm_hour = int(input("What hour do you want the alarm to go off at? ")) alarm_minute = int(input("What minute do you want the alarm to go off at? ")) run_alarm_today = map( lambda response: response.lower() in ["y", "yes", "t", "true"], input("Will the alarm run today? [y/N]") ) alarm_time = datetime.combine( datetime.today() if run_alarm_today else (datetime.today() + timedelta(days=1)).date(), time(alarm_hour, alarm_minute, 0) ).astimezone(tz=timezone.utc) alarm_clock = SimpleAlarmClock(alarm_time) alarm_clock.run_simple_alarm_mode()