#!/usr/bin/env python3 # -*- coding: utf-8 -*- from logging import config import socket import json import threading import time import uuid import os from update import update_model class Client: def __init__(self, config): self.server_host = config["server_host"] self.server_port = config["server_port"] self.device_id = config["device_id"] self.mac_address = self.get_mac_address() self.room_name = config["room_name"] self.audio_output_port = config["audio_output_port"] self.audio_input_port = config["audio_input_port"] self.connected = False self.socket = None self.command_socket = None self.audio_output_socket = None self.audio_input_socket = None self.setup_audio_streams() self.config = config def get_mac_address(self): mac = uuid.UUID(int=uuid.getnode()).hex[-12:] return ":".join([mac[e:e+2] for e in range(0, 12, 2)]) def connect_to_server(self): try: self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.connect((self.server_host, self.server_port)) self.connected = True self.command_socket = self.socket self.validate_with_server() except Exception as e: print(f"Failed to connect to server: {e}") self.connected = False def validate_with_server(self): if self.connected: try: validation_data = { "device_id": self.device_id, "mac_address": self.mac_address, "room_name": self.room_name, "audio_output_port": self.audio_output_port, "audio_input_port": self.audio_input_port } self.command_socket.send(json.dumps(validation_data).encode('utf-8')) response = self.command_socket.recv(1024).decode('utf-8') if response == "Validation successful": print("Client validated successfully with server.") self.update_model_if_needed() else: print("Validation failed.") self.command_socket.close() self.connected = False except Exception as e: print(f"Validation error: {e}") self.command_socket.close() self.connected = False def setup_audio_streams(self): try: self.audio_output_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.audio_output_socket.bind(('', self.audio_output_port)) self.audio_output_socket.listen(1) print("Audio output stream ready.") self.audio_input_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.audio_input_socket.bind(('', self.audio_input_port)) self.audio_input_socket.listen(1) print("Audio input stream ready.") except Exception as e: print(f"Error setting up audio streams: {e}") self.connected = False def update_model_if_needed(self): if self.connected: update_model(self.command_socket, self.config) def send_hotword_detected(self): if self.connected: try: self.command_socket.send("Hotword detected".encode('utf-8')) except Exception as e: print(f"Failed to send hotword detected message: {e}") self.connected = False def send_audio_input(self, audio_data): if self.connected: try: conn, addr = self.audio_input_socket.accept() conn.sendall(audio_data) conn.close() except Exception as e: print(f"Failed to send audio input: {e}") self.connected = False def start(self): while True: if not self.connected: print("Attempting to connect to server...") self.connect_to_server() if self.connected: # Start listening for hotword detection hotword_thread = threading.Thread(target=self.listen_for_hotword) hotword_thread.start() # Start listening for audio streams audio_thread = threading.Thread(target=self.listen_for_audio_streams) audio_thread.start() time.sleep(10) def listen_for_hotword(self): from hotword_detection import HotwordDetector detector = HotwordDetector("model/hotword/"+self.config["hotword"]+".keras") self.listen_hotword = True print("Listen for hooword...") while self.connected and self.listen_hotword == True: try: if detector.detect_hotword(): print("Hotword detected!") self.send_hotword_detected() # Start sending audio input self.send_audio_input(b"Audio input data...") except Exception as e: print(f"Error in hotword detection: {e}") self.connected = False def listen_for_audio_streams(self): from audio_handler import AudioHandler while self.connected: try: conn, addr = self.audio_output_socket.accept() handler = AudioHandler(conn) handler.start() except Exception as e: print(f"Error in audio stream handling: {e}") self.connected = False