Initial commit: полный проект my_speaker
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
# app/core/config.py
|
||||
import os
|
||||
import logging
|
||||
from typing import Dict, Any, Optional
|
||||
from pydantic import BaseModel, Field
|
||||
from ruamel.yaml import YAML
|
||||
from functools import lru_cache
|
||||
|
||||
# Инициализация логгера
|
||||
logger = logging.getLogger('VADApp')
|
||||
|
||||
# Путь к файлу конфигурации
|
||||
CONFIG_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'config.yaml')
|
||||
class AuthConfig(BaseModel):
|
||||
username: str = "admin"
|
||||
password: str = "admin"
|
||||
|
||||
class VADConfig(BaseModel):
|
||||
mode: int = 1
|
||||
sample_rate: int = 16000
|
||||
frame_duration_ms: int = 30
|
||||
ring_buffer_size: int = 20
|
||||
speech_threshold: float = 0.5
|
||||
energy_threshold: int = 1000
|
||||
min_speech_duration_ms: int = 300
|
||||
record_stop_delay_sec: float = 1.0
|
||||
prebuffer_duration_sec: float = 1.0
|
||||
max_record_duration_sec: float = 5.0
|
||||
target_rms: float = 2000.0
|
||||
max_gain: float = 5.0
|
||||
noise_reduction_factor: float = 1.5
|
||||
noise_update_alpha: float = 0.05
|
||||
min_rms_threshold_factor: float = 2.0
|
||||
gain_smoothing_alpha: float = 0.1
|
||||
adaptive_energy_std_factor: float = 2.5
|
||||
adaptive_energy: bool = True
|
||||
noise_reduction_enabled: bool = True
|
||||
auto_gain_enabled: bool = True
|
||||
record_on_speech: bool = True
|
||||
|
||||
class SystemConfig(BaseModel):
|
||||
history_maxlen: int = 100
|
||||
polling_interval_ms: int = 500
|
||||
logging_level: str = "INFO"
|
||||
log_file: str = "logs/app.log"
|
||||
log_save_file: bool = True
|
||||
|
||||
class STTConfig(BaseModel):
|
||||
model_path: str = ""
|
||||
|
||||
class CommandsConfig(BaseModel):
|
||||
commands_file: str = ""
|
||||
|
||||
class SessionConfig(BaseModel):
|
||||
session_timeout_seconds: int = 30
|
||||
|
||||
class TTSConfig(BaseModel):
|
||||
host: str = "192.168.200.81"
|
||||
port: int = 10200
|
||||
timeout: int = 30
|
||||
pause_duration: float = 0.5
|
||||
post_stop_wait: float = 1.0
|
||||
voice: str = "ru_RU-ruslan-medium"
|
||||
save_TTS_files: bool = False
|
||||
|
||||
class AudioSettingsConfig(BaseModel):
|
||||
playback_device: int = 0
|
||||
capture_device: int = 0
|
||||
playback_volume: int = 80
|
||||
capture_volume: int = 90
|
||||
|
||||
class Settings(BaseModel):
|
||||
auth: AuthConfig = Field(default_factory=AuthConfig)
|
||||
vad: VADConfig = Field(default_factory=VADConfig)
|
||||
system: SystemConfig = Field(default_factory=SystemConfig)
|
||||
stt: STTConfig = Field(default_factory=STTConfig)
|
||||
commands: CommandsConfig = Field(default_factory=CommandsConfig)
|
||||
session: SessionConfig = Field(default_factory=SessionConfig)
|
||||
tts: TTSConfig = Field(default_factory=TTSConfig)
|
||||
audio_settings: AudioSettingsConfig = Field(default_factory=AudioSettingsConfig)
|
||||
|
||||
def setup_logging(logging_level='INFO'):
|
||||
"""Настройка уровня логирования"""
|
||||
logger.debug(f"Установка уровня логирования: {logging_level}")
|
||||
try:
|
||||
logger.setLevel(getattr(logging, logging_level.upper(), logging.INFO))
|
||||
logger.info(f"Уровень логирования установлен: {logging_level}")
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка настройки логирования: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
def load_yaml_config() -> Dict[str, Any]:
|
||||
"""Загрузка конфигурации из YAML файла"""
|
||||
logger.debug("Загрузка конфигурации из YAML")
|
||||
try:
|
||||
yaml = YAML()
|
||||
yaml.preserve_quotes = True
|
||||
if not os.path.exists(CONFIG_PATH):
|
||||
logger.error(f"Файл конфигурации не найден: {CONFIG_PATH}")
|
||||
raise FileNotFoundError(f"Файл конфигурации не найден: {CONFIG_PATH}")
|
||||
with open(CONFIG_PATH, 'r', encoding='utf-8') as f:
|
||||
config = yaml.load(f) or {}
|
||||
|
||||
# Проверяем и адаптируем пути для текущей ОС
|
||||
if 'commands' in config and 'commands_file' in config['commands']:
|
||||
commands_file = config['commands']['commands_file']
|
||||
# Преобразуем путь для текущей ОС, если необходимо
|
||||
commands_file = os.path.normpath(commands_file)
|
||||
config['commands']['commands_file'] = commands_file
|
||||
logger.debug(f"Путь к файлу команд: {commands_file}")
|
||||
|
||||
if 'stt' in config and 'model_path' in config['stt']:
|
||||
model_path = config['stt']['model_path']
|
||||
# Преобразуем путь для текущей ОС, если необходимо
|
||||
model_path = os.path.normpath(model_path)
|
||||
config['stt']['model_path'] = model_path
|
||||
logger.debug(f"Путь к модели STT: {model_path}")
|
||||
|
||||
return config
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка загрузки конфигурации: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
@lru_cache()
|
||||
def get_settings() -> Settings:
|
||||
"""Получение настроек приложения (кэшируется)"""
|
||||
config = load_yaml_config()
|
||||
|
||||
# Создаем объект настроек
|
||||
settings = Settings(
|
||||
auth=AuthConfig(**config.get('auth', {})),
|
||||
vad=VADConfig(**config.get('vad', {})),
|
||||
system=SystemConfig(**config.get('system', {})),
|
||||
stt=STTConfig(**config.get('stt', {})),
|
||||
commands=CommandsConfig(**config.get('commands', {})),
|
||||
tts=TTSConfig(**config.get('tts', {})),
|
||||
audio_settings=AudioSettingsConfig(**config.get('audio_settings', {}))
|
||||
)
|
||||
|
||||
# Настраиваем логирование
|
||||
setup_logging(settings.system.logging_level)
|
||||
|
||||
return settings
|
||||
|
||||
def save_settings(settings: Settings) -> bool:
|
||||
"""Сохранение настроек в YAML файл"""
|
||||
logger.debug("Сохранение конфигурации")
|
||||
try:
|
||||
# Загружаем текущую конфигурацию
|
||||
yaml = YAML()
|
||||
yaml.indent(mapping=2, sequence=4, offset=2)
|
||||
yaml.preserve_quotes = True
|
||||
|
||||
if not os.path.exists(CONFIG_PATH):
|
||||
logger.error(f"Файл конфигурации не найден: {CONFIG_PATH}")
|
||||
raise FileNotFoundError(f"Файл конфигурации не найден: {CONFIG_PATH}")
|
||||
|
||||
with open(CONFIG_PATH, 'r', encoding='utf-8') as f:
|
||||
config = yaml.load(f) or {}
|
||||
|
||||
# Обновляем конфигурацию
|
||||
config['auth'] = settings.auth.dict()
|
||||
config['vad'] = settings.vad.dict()
|
||||
config['system'] = settings.system.dict()
|
||||
config['stt'] = settings.stt.dict()
|
||||
config['commands'] = settings.commands.dict()
|
||||
config['tts'] = settings.tts.dict()
|
||||
config['audio_settings'] = settings.audio_settings.dict()
|
||||
|
||||
# Сохраняем обновленную конфигурацию
|
||||
with open(CONFIG_PATH, 'w', encoding='utf-8') as f:
|
||||
yaml.dump(config, f)
|
||||
|
||||
# Сбрасываем кэш настроек
|
||||
get_settings.cache_clear()
|
||||
|
||||
logger.info("Конфигурация сохранена")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка сохранения конфигурации: {e}", exc_info=True)
|
||||
return False
|
||||
Reference in New Issue
Block a user