From efebd0e63c134572266f0b45bc3ceb8f0e7f3510 Mon Sep 17 00:00:00 2001 From: "info@pi-farm.de" Date: Wed, 4 Mar 2026 16:56:12 +0000 Subject: [PATCH] main.py aktualisiert --- main.py | 81 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 23 deletions(-) diff --git a/main.py b/main.py index 85689cd..3bd27f9 100644 --- a/main.py +++ b/main.py @@ -224,40 +224,75 @@ async def terminal_websocket(websocket: WebSocket, ip: str): # --- WEBSOCKET CHAT UPDATE --- @app.websocket("/ws/chat") -async def websocket_chat(websocket: WebSocket): +async def chat_endpoint(websocket: WebSocket): await websocket.accept() try: while True: - data = await websocket.receive_text() - # Hole Antwort von der gewählten KI - ai_msg = await get_ai_response(data) - await websocket.send_text(ai_msg) + user_msg = await websocket.receive_text() + + # 1. Dynamischen Prompt laden + sys_prompt = get_system_prompt() + + # 2. KI fragen + ai_response = await get_ai_response(user_msg, sys_prompt) + + # 3. XML-Tags auslesen (Befehl) + commands_to_run = re.findall(r'(.*?)', ai_response, re.IGNORECASE | re.DOTALL) + + # 4. XML-Tags für das UI ausblenden, damit der Chat sauber aussieht + clean_chat_msg = re.sub(r'.*?', '', ai_response, flags=re.IGNORECASE | re.DOTALL).strip() + + if clean_chat_msg: + await websocket.send_text(clean_chat_msg) + + # 5. Gefundene Befehle an den Pi schicken! + for target_ip, cmd in commands_to_run: + target_ip = target_ip.strip() + cmd = cmd.strip() + + conn = get_db() + node = conn.execute('SELECT * FROM nodes WHERE ip = ? OR name = ?', (target_ip, target_ip)).fetchone() + conn.close() + + if node: + # Leite Aufgabe an die System Logs weiter + asyncio.create_task(run_remote_task(node['ip'], node['user'], cmd, "KI-Kommando")) + else: + await websocket.send_text(f"⚠️ Konnte Node {target_ip} in DB nicht finden.") + except Exception as e: - print(f"Chat Error: {e}") + print(f"Chat Fehler: {e}") -# --- Status in DB aktualisieren Helper --- -def update_node_status(ip, new_status): - conn = get_db() - conn.execute('UPDATE nodes SET status = ? WHERE ip = ?', (new_status, ip)) - conn.commit() - conn.close() - -# --- Erweiterter Remote-Task --- async def run_remote_task(ip, user, cmd, task_name): - await manager.broadcast(f"🚀 KI-Task: {task_name} auf {ip}") + await manager.broadcast(f"🚀 KI-Task gestartet: {cmd} auf {ip}") + ssh_cmd = f"ssh -o StrictHostKeyChecking=no {user}@{ip} '{cmd}'" - process = subprocess.Popen(ssh_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) - for line in process.stdout: - await manager.broadcast(f"🛠️ {line.strip()[:80]}") + # Asynchroner Subprozess, damit das restliche Dashboard nicht einfriert + process = await asyncio.create_subprocess_shell( + ssh_cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.STDOUT + ) - # WICHTIG: Wenn Docker installiert wurde, Status ändern! - if "docker" in task_name.lower(): + # Lese die Logs Zeile für Zeile, während sie entstehen + while True: + line = await process.stdout.readline() + if not line: + break + decoded_line = line.decode('utf-8', errors='ignore').strip() + if decoded_line: + await manager.broadcast(f"🛠️ {decoded_line}") + + await process.wait() + + # Falls es ein Docker-Befehl war, Status updaten + if "docker" in cmd.lower(): update_node_status(ip, "Docker Aktiv") - await manager.broadcast(f"✨ Datenbank aktualisiert: {ip} ist nun 'Docker Aktiv'") + await manager.broadcast(f"✨ {ip} ist nun 'Docker Aktiv'") + + await manager.broadcast(f"✅ Befehl auf {ip} abgeschlossen.") - await manager.broadcast(f"✅ {task_name} fertig.") - # --- Neuer Endpunkt: Manueller Refresh-Check --- @app.get("/refresh_status/{node_id}") async def refresh_status(node_id: int):