add socket management
This commit is contained in:
110
mixer_agent.py
110
mixer_agent.py
@@ -30,14 +30,74 @@ CACHE_DURATION = 3600 # 60 minuti in secondi
|
||||
|
||||
|
||||
class TF5MixerController:
|
||||
"""Controller per il mixer Yamaha TF5 con sistema di caching."""
|
||||
|
||||
def __init__(self, host=DEFAULT_HOST, port=DEFAULT_PORT):
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.socket = None
|
||||
self._ensure_cache_dir()
|
||||
self._cache = self._load_cache()
|
||||
|
||||
def _connect(self):
|
||||
"""Stabilisce la connessione se non già connesso."""
|
||||
if self.socket is None:
|
||||
print('Inizializzazione socket...')
|
||||
try:
|
||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.socket.settimeout(5)
|
||||
self.socket.connect((self.host, self.port))
|
||||
except socket.error as e:
|
||||
self.socket = None
|
||||
raise ConnectionError(f"Impossibile connettersi al mixer: {e}")
|
||||
|
||||
def _disconnect(self):
|
||||
"""Chiude la connessione."""
|
||||
if self.socket:
|
||||
print('Chiusura socket...')
|
||||
try:
|
||||
self.socket.close()
|
||||
print('Socket chiuso!')
|
||||
except:
|
||||
print('Errore durante chiusura socket!')
|
||||
pass
|
||||
finally:
|
||||
self.socket = None
|
||||
|
||||
def _send_command(self, command: str) -> str:
|
||||
"""Invia un comando al mixer e restituisce la risposta."""
|
||||
max_retries = 2
|
||||
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
print(f'Tentativo di connessione {attempt} per {command}')
|
||||
self._connect()
|
||||
self.socket.sendall((command + '\n').encode('utf-8'))
|
||||
response = self.socket.recv(4096)
|
||||
decoded = response.decode('utf-8', errors='ignore').strip()
|
||||
print(f'Risposta {decoded}')
|
||||
return decoded
|
||||
|
||||
except socket.error as e:
|
||||
print(f'Errore di connessione dopo {max_retries} tentativi: {e}')
|
||||
self._disconnect() # Forza riconnessione al prossimo tentativo
|
||||
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep(0.1)
|
||||
continue
|
||||
else:
|
||||
return f"Errore di connessione dopo {max_retries} tentativi: {e}"
|
||||
|
||||
def close(self):
|
||||
"""Chiude la connessione (da chiamare alla fine)."""
|
||||
self._disconnect()
|
||||
|
||||
def __enter__(self):
|
||||
"""Context manager entry."""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
"""Context manager exit."""
|
||||
self.close()
|
||||
|
||||
def _ensure_cache_dir(self):
|
||||
"""Crea la directory di cache se non esiste."""
|
||||
CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
@@ -67,19 +127,6 @@ class TF5MixerController:
|
||||
cache_age = time.time() - self._cache.get("timestamp", 0)
|
||||
return cache_age < CACHE_DURATION
|
||||
|
||||
def _send_command(self, command: str) -> str:
|
||||
"""Invia un comando al mixer e restituisce la risposta."""
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.settimeout(5)
|
||||
s.connect((self.host, self.port))
|
||||
s.sendall((command + '\n').encode('utf-8'))
|
||||
response = s.recv(4096)
|
||||
s.close()
|
||||
return response.decode('utf-8', errors='ignore').strip()
|
||||
except socket.error as e:
|
||||
return f"Errore di connessione: {e}"
|
||||
|
||||
def _parse_name(self, response: str) -> str:
|
||||
"""Estrae il nome tra virgolette dalla risposta."""
|
||||
try:
|
||||
@@ -540,6 +587,18 @@ Esempi di comandi che puoi gestire:
|
||||
- "Aggiorna i dati dal mixer" (refresh_cache)
|
||||
"""
|
||||
|
||||
def __enter__(self):
|
||||
"""Context manager entry."""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
"""Context manager exit."""
|
||||
self.controller.close()
|
||||
|
||||
def close(self):
|
||||
"""Chiude le connessioni."""
|
||||
self.controller.close()
|
||||
|
||||
def chat(self, user_message: str) -> str:
|
||||
"""Invia un messaggio all'agente e riceve la risposta.
|
||||
|
||||
@@ -631,19 +690,14 @@ def main():
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
agent = TF5AIAgent(args.host, args.port)
|
||||
|
||||
# Refresh cache se richiesto
|
||||
if args.refresh_cache:
|
||||
agent.controller.refresh_cache()
|
||||
|
||||
if args.message:
|
||||
# Modalità singolo comando
|
||||
print(f"🎛️ Comando: {args.message}")
|
||||
print(f"\n🤖 Risposta: {agent.chat(args.message)}")
|
||||
else:
|
||||
# Modalità interattiva
|
||||
agent.interactive_mode()
|
||||
with TF5AIAgent(args.host, args.port) as agent:
|
||||
if args.refresh_cache:
|
||||
agent.controller.refresh_cache()
|
||||
|
||||
if args.message:
|
||||
print(f"🤖 Risposta: {agent.chat(args.message)}")
|
||||
else:
|
||||
agent.interactive_mode()
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Errore fatale: {e}")
|
||||
|
||||
Reference in New Issue
Block a user