diff --git a/src/unitdev01/unitdev01/gui.py b/src/unitdev01/unitdev01/gui.py index 6ff9a2c..a227321 100644 --- a/src/unitdev01/unitdev01/gui.py +++ b/src/unitdev01/unitdev01/gui.py @@ -41,49 +41,83 @@ class DroneMonitor(Node): # 定義需要過濾的模式 self.filtered_modes = ['Mode(0x000000c0)'] - # 啟動 WebSocket client 執行緒 - threading.Thread(target=self.start_ws_client, daemon=True).start() + # 定義多個 WebSocket 連接配置 + self.websocket_connections = [ + { + 'name': 'local_1', + 'url': 'ws://192.168.137.1:5163', + 'enabled': True + }, + { + 'name': 'local_2', + 'url': 'ws://0.0.0.0:8756', + 'enabled': True # 新增的端口 + }, + { + 'name': 'remote_8756', + 'url': 'ws://192.168.50.48:8756', + 'enabled': False # 可選擇啟用 + } + ] + + # 啟動多個 WebSocket client 執行緒 + for connection in self.websocket_connections: + if connection['enabled']: + threading.Thread( + target=self.start_ws_client, + args=(connection,), + daemon=True, + name=f"WebSocket-{connection['name']}" + ).start() # 主题检测定时器 self.create_timer(1.0, self.scan_topics) - def start_ws_client(self): + def start_ws_client(self, connection_config): + """啟動單個 WebSocket 客戶端""" asyncio.set_event_loop(asyncio.new_event_loop()) - asyncio.get_event_loop().run_until_complete(self.ws_client_loop()) + asyncio.get_event_loop().run_until_complete( + self.ws_client_loop(connection_config) + ) - async def ws_client_loop(self): + async def ws_client_loop(self, connection_config): + """單個 WebSocket 連接的主循環""" retry_count = 0 max_retries = 5 base_delay = 1.0 - local = "ws://0.0.0.0:8765" # 本地 WebSocket 地址 - remote = "ws://192.168.50.48:8756" + connection_name = connection_config['name'] + url = connection_config['url'] + + print(f"Starting WebSocket client for {connection_name} at {url}") + while retry_count < max_retries: try: - async with websockets.connect(local) as websocket: - print("WebSocket connected") + async with websockets.connect(url) as websocket: + print(f"WebSocket {connection_name} connected to {url}") retry_count = 0 # 重置重試計數 async for message in websocket: try: data = json.loads(message) + # 添加連接來源信息 + data['_connection_source'] = connection_name self.process_websocket_message(data) except json.JSONDecodeError as e: - print(f"WebSocket JSON decode error: {e}") + print(f"WebSocket {connection_name} JSON decode error: {e}") except Exception as e: - print(f"WebSocket message processing error: {e}") + print(f"WebSocket {connection_name} message processing error: {e}") except websockets.exceptions.ConnectionClosedError: - print("WebSocket connection closed") + print(f"WebSocket {connection_name} connection closed") break except Exception as e: retry_count += 1 delay = base_delay * (2 ** min(retry_count, 4)) # 指數退避 - print(f"WebSocket connection error: {e}, retrying in {delay}s (attempt {retry_count}/{max_retries})") + print(f"WebSocket {connection_name} connection error: {e}, retrying in {delay}s (attempt {retry_count}/{max_retries})") await asyncio.sleep(delay) - print("WebSocket client stopped after maximum retries") - - + print(f"WebSocket client {connection_name} stopped after maximum retries") + def process_websocket_message(self, data): try: drone_id = data.get('system_id') @@ -446,7 +480,7 @@ class ControlStationUI(QMainWindow): scroll = QScrollArea() scroll.setWidget(self.drone_panel_container) scroll.setWidgetResizable(True) - self.left_tab.addTab(scroll, "無人機") + self.left_tab.addTab(scroll, "無人載具") # 底部控制按鈕區域 bottom_control = QWidget() @@ -594,35 +628,57 @@ class ControlStationUI(QMainWindow):
+