client.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. from logging import config
  4. import socket
  5. import json
  6. import threading
  7. import time
  8. import uuid
  9. import os
  10. from update import update_model
  11. class Client:
  12. def __init__(self, config):
  13. self.server_host = config["server_host"]
  14. self.server_port = config["server_port"]
  15. self.device_id = config["device_id"]
  16. self.mac_address = self.get_mac_address()
  17. self.room_name = config["room_name"]
  18. self.audio_output_port = config["audio_output_port"]
  19. self.audio_input_port = config["audio_input_port"]
  20. self.connected = False
  21. self.socket = None
  22. self.command_socket = None
  23. self.audio_output_socket = None
  24. self.audio_input_socket = None
  25. self.setup_audio_streams()
  26. self.config = config
  27. def get_mac_address(self):
  28. mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
  29. return ":".join([mac[e:e+2] for e in range(0, 12, 2)])
  30. def connect_to_server(self):
  31. try:
  32. self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  33. self.socket.connect((self.server_host, self.server_port))
  34. self.connected = True
  35. self.command_socket = self.socket
  36. self.validate_with_server()
  37. except Exception as e:
  38. print(f"Failed to connect to server: {e}")
  39. self.connected = False
  40. def validate_with_server(self):
  41. if self.connected:
  42. try:
  43. validation_data = {
  44. "device_id": self.device_id,
  45. "mac_address": self.mac_address,
  46. "room_name": self.room_name,
  47. "audio_output_port": self.audio_output_port,
  48. "audio_input_port": self.audio_input_port
  49. }
  50. self.command_socket.send(json.dumps(validation_data).encode('utf-8'))
  51. response = self.command_socket.recv(1024).decode('utf-8')
  52. if response == "Validation successful":
  53. print("Client validated successfully with server.")
  54. self.update_model_if_needed()
  55. else:
  56. print("Validation failed.")
  57. self.command_socket.close()
  58. self.connected = False
  59. except Exception as e:
  60. print(f"Validation error: {e}")
  61. self.command_socket.close()
  62. self.connected = False
  63. def setup_audio_streams(self):
  64. try:
  65. self.audio_output_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  66. self.audio_output_socket.bind(('', self.audio_output_port))
  67. self.audio_output_socket.listen(1)
  68. print("Audio output stream ready.")
  69. self.audio_input_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  70. self.audio_input_socket.bind(('', self.audio_input_port))
  71. self.audio_input_socket.listen(1)
  72. print("Audio input stream ready.")
  73. except Exception as e:
  74. print(f"Error setting up audio streams: {e}")
  75. self.connected = False
  76. def update_model_if_needed(self):
  77. if self.connected:
  78. update_model(self.command_socket, self.config)
  79. def send_hotword_detected(self):
  80. if self.connected:
  81. try:
  82. self.command_socket.send("Hotword detected".encode('utf-8'))
  83. except Exception as e:
  84. print(f"Failed to send hotword detected message: {e}")
  85. self.connected = False
  86. def send_audio_input(self, audio_data):
  87. if self.connected:
  88. try:
  89. conn, addr = self.audio_input_socket.accept()
  90. conn.sendall(audio_data)
  91. conn.close()
  92. except Exception as e:
  93. print(f"Failed to send audio input: {e}")
  94. self.connected = False
  95. def start(self):
  96. while True:
  97. if not self.connected:
  98. print("Attempting to connect to server...")
  99. self.connect_to_server()
  100. if self.connected:
  101. # Start listening for hotword detection
  102. hotword_thread = threading.Thread(target=self.listen_for_hotword)
  103. hotword_thread.start()
  104. # Start listening for audio streams
  105. audio_thread = threading.Thread(target=self.listen_for_audio_streams)
  106. audio_thread.start()
  107. time.sleep(10)
  108. def listen_for_hotword(self):
  109. from hotword_detection import HotwordDetector
  110. detector = HotwordDetector("model/hotword/"+self.config["hotword"]+".keras")
  111. self.listen_hotword = True
  112. print("Listen for hooword...")
  113. while self.connected and self.listen_hotword == True:
  114. try:
  115. if detector.detect_hotword():
  116. print("Hotword detected!")
  117. self.send_hotword_detected()
  118. # Start sending audio input
  119. self.send_audio_input(b"Audio input data...")
  120. except Exception as e:
  121. print(f"Error in hotword detection: {e}")
  122. self.connected = False
  123. def listen_for_audio_streams(self):
  124. from audio_handler import AudioHandler
  125. while self.connected:
  126. try:
  127. conn, addr = self.audio_output_socket.accept()
  128. handler = AudioHandler(conn)
  129. handler.start()
  130. except Exception as e:
  131. print(f"Error in audio stream handling: {e}")
  132. self.connected = False