Skip to content
Snippets Groups Projects
simple_alarm_clock.py 3.55 KiB
Newer Older
  • Learn to ignore specific revisions
  • SurajSSingh's avatar
    SurajSSingh committed
    from dataclasses import dataclass
    from enum import Enum, auto
    from datetime import time, datetime
    from typing import Optional, Any
    from time import sleep
    
    from pynput import keyboard
    from pynput.keyboard import Key, Controller
    
    SurajSSingh's avatar
    SurajSSingh committed
    
    # 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 = time(19, 13, 0)
    SNOOZE_SEC = 5
    SNOOZE_KEY = keyboard.Key.up
    ALARM_OFF_KEY = keyboard.Key.esc
    
    SurajSSingh's avatar
    SurajSSingh committed
    
    
    class AlarmState(Enum):
        SET = auto(),
    
        RUNNING = auto(),
    
    SurajSSingh's avatar
    SurajSSingh committed
        PLAYING = auto(),
        SNOOZED = auto(),
        DEACTIVATED = auto(),
    
    
    @dataclass
    
    class BaseAlarmClock:
        # player: Optional
    
    SurajSSingh's avatar
    SurajSSingh committed
        wake_time: time
        current_state: AlarmState = AlarmState.DEACTIVATED
    
        def set_alarm(self, wake_time: time) -> time:
            print(f"SETTING ALARM to: {wake_time}")
            self.current_state = AlarmState.SET
            self.wake_time = wake_time
            return self.wake_time
    
    
        def start_alarm(self, check_frequency: int = 1):
            print("STARTING ALARM")
            self.current_state = AlarmState.RUNNING
            # now = datetime.now().time()
            # if now >= self.wake_time:
            #     return False
            # sleep_time_amount = max(check_frequency, 1)
            # while now < self.wake_time:
            #     # Sleep for some time
            #     sleep(sleep_time_amount)
            #     now = datetime.now().time()
            # self.sound_alarm()
            # return True
    
        def sound_alarm(self):
            print("SOUNDING ALARM")
    
    SurajSSingh's avatar
    SurajSSingh committed
            self.current_state = AlarmState.PLAYING
    
            # if sound is not None:
            #     self.player.set_media(sound)
            # self.player.audio_set_volume(volume)
            # self.player.play()
    
    SurajSSingh's avatar
    SurajSSingh committed
    
    
        def snooze_alarm(self, snooze_time: int = SNOOZE_SEC):
            print("SNOOZING ALARM")
    
    SurajSSingh's avatar
    SurajSSingh committed
            self.current_state = AlarmState.SNOOZED
    
            # self.player.pause()
    
    SurajSSingh's avatar
    SurajSSingh committed
            # Maybe make this async later
            sleep(snooze_time)
    
            # self.player.play()
    
    SurajSSingh's avatar
    SurajSSingh committed
            if self.current_state is AlarmState.SNOOZED:
                self.sound_alarm()
    
        def stop_alarm(self, deactivate: bool = True):
    
            print("STOPPING ALARM")
    
    SurajSSingh's avatar
    SurajSSingh committed
            if self.current_state is AlarmState.PLAYING:
    
                print("STOPPED PLAYING ALARM")
                # self.player.stop()
    
    SurajSSingh's avatar
    SurajSSingh committed
            self.current_state = AlarmState.DEACTIVATED if deactivate else AlarmState.SET
    
    
        def alarm_check_reached(self, current_time = datetime.now().time()) -> bool:
            result = current_time >= self.wake_time if self.current_state is AlarmState.RUNNING else False
            print(f"{result = }")
            return result
    
    
    def simple_alarm_mode(alarm_time):
        alarm_clock = BaseAlarmClock(alarm_time)
        alarm_clock.start_alarm()
        while not alarm_clock.alarm_check_reached():
            print(f"ALARM SLEEPING @: {datetime.now().time()}")
            sleep(1)
        alarm_clock.sound_alarm()
        while alarm_clock.current_state is not AlarmState.DEACTIVATED:
            with keyboard.Events() as events:
                for event in events:
                    if event.key == ALARM_OFF_KEY:
                        alarm_clock.stop_alarm()
                        break
                    elif event.key == SNOOZE_KEY:
                        alarm_clock.snooze_alarm()
                        break
    
    SurajSSingh's avatar
    SurajSSingh committed
    
    
    if __name__ == '__main__':
    
        simple_alarm_mode(ALARM_TIME)