Active alarms almost work.

This commit is contained in:
Kalzu Rekku
2025-01-26 22:02:23 +02:00
parent f3dabc1116
commit 6fd172ce2e
6 changed files with 174 additions and 63 deletions

View File

@@ -3,26 +3,33 @@ import time
from datetime import datetime, date, timedelta
import threading
import logging
import queue
# Import drawing methods from the new module
from ncurses_ui_draw import (
_draw_main_clock,
_draw_add_alarm,
_draw_list_alarms,
_draw_active_alarms,
_draw_error
)
# class AlarmClockUI:
class UI:
def __init__(self, alarm_system_manager):
def __init__(self, alarm_system_manager, control_queue):
# UI State Management
self.alarm_system = alarm_system_manager
self.stop_event = alarm_system_manager.stop_event
self.storage = alarm_system_manager.storage
# Control queue for interacting with AlarmSiren
self.control_queue = control_queue
# Logging
self.logger = logging.getLogger(__name__)
# Active alarm tracking
self.active_alarms = {}
# UI State
self.reset_ui_state()
@@ -54,10 +61,17 @@ class UI:
# Weekday names (to match specification)
self.weekday_names = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
# Clear active alarms
self.active_alarms.clear()
def run(self):
"""Start the ncurses UI in a separate thread"""
def ui_thread():
try:
# Start a thread to monitor control queue
monitor_thread = threading.Thread(target=self._monitor_control_queue, daemon=True)
monitor_thread.start()
curses.wrapper(self._main_loop)
except Exception as e:
self.logger.error(f"UI Thread Error: {e}")
@@ -68,6 +82,66 @@ class UI:
ui_thread_obj.start()
return ui_thread_obj
def _monitor_control_queue(self):
"""Monitor the control queue for alarm events"""
while not self.stop_event.is_set():
try:
# Non-blocking check of control queue
try:
control_msg = self.control_queue.get(timeout=1)
# Handle different types of control messages
if control_msg['type'] == 'trigger':
# Store triggered alarm
alarm_id = control_msg['alarm_id']
self.active_alarms[alarm_id] = control_msg['info']
# If not already in alarm view, switch to it
if self.current_view != 'ACTIVE_ALARMS':
self.current_view = 'ACTIVE_ALARMS'
except queue.Empty:
pass
time.sleep(0.1)
except Exception as e:
self.logger.error(f"Error monitoring control queue: {e}")
time.sleep(1)
def _handle_active_alarms_input(self, key):
"""Handle input for active alarms view"""
if not self.active_alarms:
# No active alarms, return to clock view
self.current_view = 'CLOCK'
return
# Get the first (or only) active alarm
alarm_id = list(self.active_alarms.keys())[0]
if key == ord('s'): # Snooze
# Send snooze command to control queue
self.control_queue.put({
'type': 'snooze',
'alarm_id': alarm_id
})
# Remove from active alarms
del self.active_alarms[alarm_id]
# Optional: show a snooze confirmation
self._show_error("Alarm Snoozed")
elif key == ord('d'): # Dismiss
# Send dismiss command to control queue
self.control_queue.put({
'type': 'dismiss',
'alarm_id': alarm_id
})
# Remove from active alarms
del self.active_alarms[alarm_id]
# Return to clock view
self.current_view = 'CLOCK'
def _handle_clock_input(self, key):
"""Handle input on the clock view"""
if key == ord('a'):
@@ -199,6 +273,9 @@ class UI:
'alarms': self.alarm_list or [],
'weekday_names': self.weekday_names
})
elif self.current_view == 'ACTIVE_ALARMS':
# Draw active alarm view
_draw_active_alarms(stdscr, {'active_alarms': self.active_alarms })
# Render error if exists
if self.error_message:
@@ -225,6 +302,8 @@ class UI:
self._handle_add_alarm_input(key)
elif self.current_view == 'LIST_ALARMS':
self._handle_list_alarms_input(key)
elif self.current_view == 'ACTIVE_ALARMS':
self._handle_active_alarms_input(key)
time.sleep(0.2)