proyecto-global-psp/logica/T2/alarm.py

131 lines
4.3 KiB
Python

# Módulo: logica/T2/alarm.py
import tkinter as tk
from datetime import datetime
import os
import sys
try:
from logica.T2.musicReproductor import MusicReproductor
except ImportError:
class MusicReproductor:
def __init__(self, *args, **kwargs): pass
def ajustar_volumen(self, valor): pass
def cargar_y_reproducir(self, url): print(f"🎶 SIMULANDO PLAY: {url}")
def detener(self): print("🔇 SIMULANDO STOP")
class AlarmManager:
"""
Gestiona la creación, seguimiento y disparo de múltiples alarmas (temporizadores).
"""
def __init__(self, root, trigger_callback):
self.root = root
self.active_alarms = {}
self.next_id = 1
self.trigger_callback = trigger_callback
self.alarm_sound_player = MusicReproductor()
self.ALARM_SOUND_PATH = os.path.join(os.path.dirname(__file__), '..', '..', 'res', 'alarm.mp3')
# === MODIFICACIÓN CLAVE: Acepta total_seconds en lugar de minutes ===
def set_alarm(self, total_seconds):
"""
Programa una nueva alarma para sonar después de un número de segundos.
:param total_seconds: Número de segundos hasta que suena la alarma.
:return: ID único de la alarma.
"""
if total_seconds <= 0:
raise ValueError("El tiempo de alarma debe ser positivo.")
alarm_id = self.next_id
self.next_id += 1
ms_delay = total_seconds * 1000
ms_delay_int = int(ms_delay)
tiempo_disparo_ts = datetime.now().timestamp() + total_seconds
tiempo_disparo_dt = datetime.fromtimestamp(tiempo_disparo_ts)
name = f"{tiempo_disparo_dt.strftime('%H:%M:%S')}"
alarm_data = {
'nombre': name,
'total_seconds': total_seconds, # Almacenamos el tiempo total en segundos
'tiempo_creacion': datetime.now(),
'tiempo_disparo': tiempo_disparo_ts,
'after_id': None,
'sonada': False
}
after_id = self.root.after(ms_delay_int, lambda: self._trigger_alarm(alarm_id))
alarm_data['after_id'] = after_id
self.active_alarms[alarm_id] = alarm_data
print(f"🔔 Alarma '{name}' ({alarm_id}) programada para sonar en {total_seconds} segundos.")
return alarm_id
def _trigger_alarm(self, alarm_id):
# ... (código sin cambios aquí) ...
if alarm_id in self.active_alarms:
alarm = self.active_alarms[alarm_id]
print(f"🚨 ¡ALARMA! La alarma '{alarm['nombre']}' ({alarm_id}) ha sonado.")
alarm['sonada'] = True
self.alarm_sound_player.cargar_y_reproducir(self.ALARM_SOUND_PATH)
self.trigger_callback(alarm['nombre'], alarm_id)
def stop_alarm_sound(self):
self.alarm_sound_player.detener()
def cancel_alarm(self, alarm_id):
# ... (código sin cambios aquí) ...
if alarm_id in self.active_alarms:
alarm = self.active_alarms[alarm_id]
if not alarm['sonada'] and alarm['after_id']:
self.root.after_cancel(alarm['after_id'])
print(f"❌ Alarma '{alarm['nombre']}' ({alarm_id}) cancelada.")
del self.active_alarms[alarm_id]
return True
return False
def get_active_alarms(self):
"""
Retorna una lista de las alarmas activas, incluyendo el tiempo restante.
"""
alarms_to_show = []
current_time = datetime.now().timestamp()
for alarm_id, alarm in list(self.active_alarms.items()):
if not alarm['sonada']:
time_diff = alarm['tiempo_disparo'] - current_time
if time_diff > 0:
remaining_sec = int(time_diff)
hours = remaining_sec // 3600
minutes = (remaining_sec % 3600) // 60
seconds = remaining_sec % 60
remaining_str = f"{hours:02d}h:{minutes:02d}m:{seconds:02d}s"
alarms_to_show.append({
'id': alarm_id,
'nombre': alarm['nombre'],
'restante': remaining_str,
'total_seconds': alarm['total_seconds'] # Usar total_seconds
})
return sorted(alarms_to_show, key=lambda x: x['restante'])