131 lines
4.3 KiB
Python
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']) |