diff --git a/src/accessiclock/app.py b/src/accessiclock/app.py index b61a465..c4f4e51 100644 --- a/src/accessiclock/app.py +++ b/src/accessiclock/app.py @@ -59,6 +59,9 @@ def __init__(self, portable_mode: bool = False): self.chime_hourly: bool = True self.chime_half_hour: bool = False self.chime_quarter_hour: bool = False + self.quiet_hours_enabled: bool = False + self.quiet_start: str = "22:00" + self.quiet_end: str = "07:00" super().__init__() @@ -118,6 +121,19 @@ def _sync_service_settings(self) -> None: self.clock_service.chime_hourly = self.chime_hourly self.clock_service.chime_half_hour = self.chime_half_hour self.clock_service.chime_quarter_hour = self.chime_quarter_hour + + # Sync quiet hours + if self.quiet_hours_enabled: + from datetime import time as dt_time + start_parts = self.quiet_start.split(":") + end_parts = self.quiet_end.split(":") + self.clock_service.set_quiet_hours( + dt_time(int(start_parts[0]), int(start_parts[1])), + dt_time(int(end_parts[0]), int(end_parts[1])), + ) + else: + self.clock_service.quiet_hours_enabled = False + logger.debug("Clock service settings synced with config") def _init_audio(self) -> None: @@ -157,6 +173,11 @@ def _load_config(self) -> None: self.chime_half_hour = self.config.get("chime_half_hour", False) self.chime_quarter_hour = self.config.get("chime_quarter_hour", False) + # Quiet hours + self.quiet_hours_enabled = self.config.get("quiet_hours_enabled", False) + self.quiet_start = self.config.get("quiet_start", "22:00") + self.quiet_end = self.config.get("quiet_end", "07:00") + logger.info(f"Configuration loaded from {config_file}") except Exception as e: logger.warning(f"Failed to load config: {e}") @@ -172,6 +193,9 @@ def save_config(self) -> None: "chime_hourly": self.chime_hourly, "chime_half_hour": self.chime_half_hour, "chime_quarter_hour": self.chime_quarter_hour, + "quiet_hours_enabled": self.quiet_hours_enabled, + "quiet_start": self.quiet_start, + "quiet_end": self.quiet_end, } ) diff --git a/src/accessiclock/services/clock_service.py b/src/accessiclock/services/clock_service.py index 1f99e84..575a59e 100644 --- a/src/accessiclock/services/clock_service.py +++ b/src/accessiclock/services/clock_service.py @@ -29,6 +29,7 @@ def __init__(self): self.chime_quarter_hour: bool = False # Quiet hours (None = disabled) + self.quiet_hours_enabled: bool = False self.quiet_start: time | None = None self.quiet_end: time | None = None @@ -100,6 +101,18 @@ def get_hour_12h(self, current_time: time) -> int: hour = current_time.hour % 12 return 12 if hour == 0 else hour + def set_quiet_hours(self, start: time, end: time) -> None: + """ + Configure quiet hours. + + Args: + start: Start time for quiet hours. + end: End time for quiet hours. + """ + self.quiet_hours_enabled = True + self.quiet_start = start + self.quiet_end = end + def _is_quiet_time(self, current_time: time) -> bool: """ Check if the given time falls within quiet hours. @@ -110,6 +123,8 @@ def _is_quiet_time(self, current_time: time) -> bool: Returns: True if within quiet hours, False otherwise. """ + if not self.quiet_hours_enabled: + return False if self.quiet_start is None or self.quiet_end is None: return False diff --git a/tests/test_clock_service.py b/tests/test_clock_service.py index 04520ed..9c164af 100644 --- a/tests/test_clock_service.py +++ b/tests/test_clock_service.py @@ -195,8 +195,7 @@ def test_no_chime_during_quiet_hours(self): service = ClockService() service.chime_hourly = True - service.quiet_start = time(23, 0) # 11 PM - service.quiet_end = time(7, 0) # 7 AM + service.set_quiet_hours(time(23, 0), time(7, 0)) # 2 AM - within quiet hours assert service.should_chime_now(time(2, 0, 0)) is None @@ -210,8 +209,7 @@ def test_chime_outside_quiet_hours(self): service = ClockService() service.chime_hourly = True - service.quiet_start = time(23, 0) - service.quiet_end = time(7, 0) + service.set_quiet_hours(time(23, 0), time(7, 0)) # 10 AM - outside quiet hours assert service.should_chime_now(time(10, 0, 0)) == "hour" @@ -232,8 +230,7 @@ def test_same_day_quiet_hours(self): service = ClockService() service.chime_hourly = True - service.quiet_start = time(9, 0) - service.quiet_end = time(17, 0) + service.set_quiet_hours(time(9, 0), time(17, 0)) # 12 PM - within quiet hours assert service.should_chime_now(time(12, 0, 0)) is None @@ -242,14 +239,38 @@ def test_same_day_quiet_hours(self): # 6 PM - after quiet hours assert service.should_chime_now(time(18, 0, 0)) == "hour" + def test_set_quiet_hours_enables_and_configures(self): + """set_quiet_hours should enable quiet hours and set start/end.""" + from accessiclock.services.clock_service import ClockService + + service = ClockService() + assert service.quiet_hours_enabled is False + + service.set_quiet_hours(time(22, 0), time(7, 0)) + assert service.quiet_hours_enabled is True + assert service.quiet_start == time(22, 0) + assert service.quiet_end == time(7, 0) + + def test_quiet_hours_disabled_attribute(self): + """Setting quiet_hours_enabled to False should allow chimes.""" + from accessiclock.services.clock_service import ClockService + + service = ClockService() + service.chime_hourly = True + service.set_quiet_hours(time(0, 0), time(23, 59)) + # Should be quiet + assert service.should_chime_now(time(12, 0, 0)) is None + # Disable via attribute + service.quiet_hours_enabled = False + assert service.should_chime_now(time(12, 0, 0)) == "hour" + def test_overnight_quiet_hours_boundaries(self): """Quiet hours should be inclusive of start and exclusive of end.""" from accessiclock.services.clock_service import ClockService service = ClockService() service.chime_hourly = True - service.quiet_start = time(23, 0) - service.quiet_end = time(7, 0) + service.set_quiet_hours(time(23, 0), time(7, 0)) # Exactly at start - within quiet hours assert service.should_chime_now(time(23, 0, 0)) is None