Initial commit
This commit is contained in:
+168
@@ -0,0 +1,168 @@
|
||||
# commands.py
|
||||
import logging
|
||||
import time
|
||||
from datetime import datetime
|
||||
from piper_TTS import synthesize_text
|
||||
from app.core.config import get_settings
|
||||
from volume import get_volume
|
||||
|
||||
def speak_text(text, voice_name=None):
|
||||
"""
|
||||
Синтезирует речь из текста и возвращает путь к аудиофайлу
|
||||
|
||||
Args:
|
||||
text (str): Текст для синтеза
|
||||
voice_name (str, optional): Имя голоса
|
||||
|
||||
Returns:
|
||||
str: Путь к созданному аудиофайлу или None в случае ошибки
|
||||
"""
|
||||
logger = logging.getLogger('VADApp')
|
||||
try:
|
||||
logger.info(f"Синтезирую текст: '{text}'")
|
||||
audio_path = synthesize_text(text, voice_name)
|
||||
logger.info(f"Синтез завершен, файл: {audio_path}")
|
||||
return audio_path
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка синтеза речи: {e}")
|
||||
return None
|
||||
|
||||
def handle_command(command, commands, session_manager=None):
|
||||
"""
|
||||
Обрабатывает распознанную команду на основе commands.yaml и возвращает action
|
||||
|
||||
Args:
|
||||
command (str): Распознанная команда
|
||||
commands (dict): Словарь команд из commands.yaml
|
||||
session_manager (SessionManager, optional): Менеджер сессий
|
||||
|
||||
Returns:
|
||||
str: Действие, которое нужно выполнить, или None
|
||||
"""
|
||||
logger = logging.getLogger('VADApp')
|
||||
try:
|
||||
if not commands:
|
||||
logger.warning("Команды не загружены")
|
||||
return None
|
||||
|
||||
# Создаем список всех возможных совпадений с их приоритетами
|
||||
matches = []
|
||||
session_active = session_manager.is_session_active() if session_manager else True
|
||||
min_priority = 0 if session_active else 90
|
||||
|
||||
# Проверяем wakewords (всегда проверяем, независимо от статуса сессии)
|
||||
for wakeword_group in commands.get('Wakewords', []):
|
||||
if isinstance(wakeword_group, dict):
|
||||
phrases = wakeword_group.get('phrases', [])
|
||||
action = wakeword_group.get('action', 'wake_assistant')
|
||||
priority = wakeword_group.get('priority', 0)
|
||||
if command.lower() in [p.lower() for p in phrases]:
|
||||
matches.append({
|
||||
'action': action,
|
||||
'priority': priority
|
||||
})
|
||||
# Если обнаружено wakeword и сессия не активна, активируем её
|
||||
if session_manager and not session_active and action == 'wake_assistant':
|
||||
logger.info("Обнаружено wakeword, активируем сессию")
|
||||
session_manager.start_session()
|
||||
|
||||
# Проверяем команды громкости (всегда проверяем, независимо от статуса сессии)
|
||||
for volume_group in commands.get('Volume', []):
|
||||
if isinstance(volume_group, dict):
|
||||
volume_commands = volume_group.get('commands', {})
|
||||
priority = volume_group.get('priority', 0)
|
||||
if command.lower() in volume_commands:
|
||||
action = volume_commands[command.lower()]
|
||||
matches.append({
|
||||
'action': action,
|
||||
'priority': priority
|
||||
})
|
||||
|
||||
# Обработка команды "какая громкость"
|
||||
if action == 'get_volume':
|
||||
config = get_settings()
|
||||
playback_device = config.audio_settings.playback_device
|
||||
capture_device = config.audio_settings.capture_device
|
||||
playback_volume = get_volume(playback_device, mixer_type='Playback')
|
||||
capture_volume = get_volume(capture_device, mixer_type='Capture')
|
||||
|
||||
if playback_volume is not None and capture_volume is not None:
|
||||
logger.info(f"Текущая громкость: воспроизведение={playback_volume}%, запись={capture_volume}%")
|
||||
# Здесь можно добавить код для озвучивания громкости, если есть такая возможность
|
||||
else:
|
||||
logger.error("Не удалось получить информацию о громкости")
|
||||
|
||||
# Если сессия активна или команда имеет высокий приоритет, проверяем остальные команды
|
||||
if session_active:
|
||||
# Проверяем команды сессии
|
||||
for session_group in commands.get('Session', []):
|
||||
if isinstance(session_group, dict):
|
||||
phrases = session_group.get('phrases', [])
|
||||
action = session_group.get('action', 'session_stop')
|
||||
priority = session_group.get('priority', 0)
|
||||
if command.lower() in [p.lower() for p in phrases]:
|
||||
matches.append({
|
||||
'action': action,
|
||||
'priority': priority
|
||||
})
|
||||
# Если обнаружена команда завершения сессии
|
||||
if session_manager and action == 'session_stop':
|
||||
logger.info("Обнаружена команда завершения сессии")
|
||||
session_manager.end_session()
|
||||
|
||||
# Проверяем текстовые команды
|
||||
for text_group in commands.get('Text', []):
|
||||
if isinstance(text_group, dict):
|
||||
text_commands = text_group.get('commands', {})
|
||||
priority = text_group.get('priority', 0)
|
||||
if command.lower() in text_commands:
|
||||
matches.append({
|
||||
'action': text_commands[command.lower()],
|
||||
'priority': priority
|
||||
})
|
||||
|
||||
# Проверяем плагины
|
||||
for plugin_group in commands.get('Plugin', []):
|
||||
if isinstance(plugin_group, dict):
|
||||
priority = plugin_group.get('priority', 0)
|
||||
action = plugin_group.get('action', 'speak_plugins')
|
||||
# Добавляем действие плагина только если не нашли других совпадений
|
||||
# и сессия активна
|
||||
if not matches and session_active:
|
||||
matches.append({
|
||||
'action': action,
|
||||
'priority': priority
|
||||
})
|
||||
|
||||
# Фильтруем совпадения по минимальному приоритету
|
||||
matches = [m for m in matches if m['priority'] >= min_priority]
|
||||
|
||||
# Если есть совпадения, выбираем действие с наивысшим приоритетом
|
||||
if matches:
|
||||
# Сортируем по приоритету (от высшего к низшему)
|
||||
matches.sort(key=lambda x: x['priority'], reverse=True)
|
||||
action = matches[0]['action']
|
||||
logger.info(f"Выполняется действие: {action} с приоритетом {matches[0]['priority']}")
|
||||
# Тестовая пауза на выполение действия
|
||||
session_manager.pause_session()
|
||||
|
||||
# Имитируем выполнение действия с использованием TTS
|
||||
|
||||
print("Выполняем синтез речи...")
|
||||
audio_path = speak_text(f"Выполняю команду: {action}")
|
||||
print(f"Синтез завершен, файл: {audio_path}")
|
||||
time.sleep(2) # Пауза на 2 секунды
|
||||
|
||||
# Возобновляем сессию после паузы
|
||||
session_manager.resume_session()
|
||||
# Сбрасываем таймер сессии, если действие не завершает сессию
|
||||
if session_manager and session_manager.is_session_active() and action != 'session_stop':
|
||||
|
||||
session_manager.reset_timer()
|
||||
return action
|
||||
else:
|
||||
logger.warning(f"Команда не найдена в commands.yaml: {command}")
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка обработки команды: {e}")
|
||||
return None
|
||||
Reference in New Issue
Block a user