Files
my_speaker_RPi3/session_manager.py
T
2025-12-25 12:01:35 +03:00

170 lines
7.3 KiB
Python

# session_manager.py
import time
import logging
import threading
from datetime import datetime
class SessionManager:
"""Класс для управления сессией голосового помощника"""
def __init__(self, timeout_seconds=30):
"""
Инициализация менеджера сессий
Args:
timeout_seconds (int): Время таймаута сессии в секундах
"""
self.logger = logging.getLogger('VADApp')
self.timeout_seconds = timeout_seconds
self.session_active = False
self.session_paused = False
self.pause_start_time = None
self.session_start_time = None
self.session_end_time = None
self.last_reset_time = None
self.timer = None
self.lock = threading.Lock()
self.logger.info(f"SessionManager инициализирован с таймаутом {timeout_seconds} секунд")
def start_session(self):
"""Начать новую сессию"""
with self.lock:
if self.session_active:
self.logger.info("Сессия уже активна, сбрасываем таймер")
self.last_reset_time = datetime.now()
self._reset_timer()
else:
self.session_active = True
self.session_start_time = datetime.now()
self.last_reset_time = self.session_start_time
self.session_end_time = None
self._start_timer()
self.logger.info(f"Сессия начата в {self.session_start_time}")
def end_session(self):
"""Завершить текущую сессию"""
with self.lock:
if self.session_active:
self.session_active = False
self.session_paused = False
self.pause_start_time = None
self.session_end_time = datetime.now()
if self.timer:
self.timer.cancel()
self.timer = None
self.logger.info(f"Сессия завершена в {self.session_end_time}")
return True
return False
def pause_session(self):
"""Поставить текущую сессию на паузу"""
with self.lock:
if self.session_active and not self.session_paused:
self.session_paused = True
self.pause_start_time = datetime.now()
# Останавливаем таймер на время паузы
if self.timer:
self.timer.cancel()
self.timer = None
self.logger.info(f"Сессия поставлена на паузу в {self.pause_start_time}")
return True
return False
def resume_session(self):
"""Возобновить сессию после паузы"""
with self.lock:
if self.session_active and self.session_paused:
pause_duration = 0
if self.pause_start_time:
# Вычисляем длительность паузы
pause_duration = (datetime.now() - self.pause_start_time).total_seconds()
# Обновляем время последнего сброса с учетом паузы
if self.last_reset_time:
self.last_reset_time = datetime.now()
self.session_paused = False
self.pause_start_time = None
# Запускаем таймер заново
self._start_timer()
self.logger.info(f"Сессия возобновлена после паузы длительностью {pause_duration:.1f} секунд")
return True
return False
def reset_timer(self):
"""Сбросить таймер сессии"""
with self.lock:
if self.session_active:
self.last_reset_time = datetime.now()
self._reset_timer()
self.logger.info("Таймер сессии сброшен")
return True
return False
def _start_timer(self):
"""Запустить таймер сессии"""
if self.timer:
self.timer.cancel()
self.timer = None
self.timer = threading.Timer(self.timeout_seconds, self._timeout_callback)
self.timer.daemon = True
self.timer.start()
def _reset_timer(self):
"""Сбросить и перезапустить таймер сессии"""
self._start_timer()
def _timeout_callback(self):
"""Обработчик истечения таймера сессии"""
with self.lock:
if self.session_active:
self.session_active = False
self.session_end_time = datetime.now()
self.logger.info(f"Сессия завершена по таймауту в {self.session_end_time}")
def is_session_active(self):
"""Проверить, активна ли сессия"""
with self.lock:
return self.session_active
def get_session_status(self):
"""Получить статус сессии"""
with self.lock:
if not self.session_active:
return {
"active": False,
"paused": False,
"time_left": 0,
"start_time": self.session_start_time.isoformat() if self.session_start_time else None,
"end_time": self.session_end_time.isoformat() if self.session_end_time else None
}
# Вычисляем оставшееся время
# Используем время последнего сброса таймера, если оно есть
reference_time = self.last_reset_time if self.last_reset_time else self.session_start_time
# Если сессия на паузе, не вычисляем оставшееся время
if self.session_paused:
time_left = self.timeout_seconds
if reference_time and self.pause_start_time:
# Вычисляем время, прошедшее до паузы
elapsed_before_pause = (self.pause_start_time - reference_time).total_seconds()
time_left = max(0, self.timeout_seconds - elapsed_before_pause)
else:
if reference_time:
elapsed = (datetime.now() - reference_time).total_seconds()
time_left = max(0, self.timeout_seconds - elapsed)
else:
time_left = 0
return {
"active": True,
"paused": self.session_paused,
"time_left": time_left,
"start_time": self.session_start_time.isoformat() if self.session_start_time else None,
"pause_time": self.pause_start_time.isoformat() if self.pause_start_time else None,
"end_time": None
}