🎉 Feature: Enhanced Admin Guest Requests API & Startup Initialization Documentation 📚
This commit is contained in:
281
backend/scripts/diagnose_tapo.py
Normal file
281
backend/scripts/diagnose_tapo.py
Normal file
@ -0,0 +1,281 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Tapo Steckdosen Diagnose-Tool
|
||||
============================
|
||||
|
||||
Dieses Script hilft bei der Diagnose von Verbindungsproblemen mit Tapo-Steckdosen.
|
||||
|
||||
Autor: Till Tomczak
|
||||
Datum: 2025-06-20
|
||||
"""
|
||||
|
||||
import sys
|
||||
import socket
|
||||
import subprocess
|
||||
import time
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
# Farben für Terminal-Ausgabe
|
||||
class Colors:
|
||||
GREEN = '\033[92m'
|
||||
YELLOW = '\033[93m'
|
||||
RED = '\033[91m'
|
||||
BLUE = '\033[94m'
|
||||
ENDC = '\033[0m'
|
||||
BOLD = '\033[1m'
|
||||
|
||||
def print_header(text):
|
||||
"""Druckt eine formatierte Überschrift"""
|
||||
print(f"\n{Colors.BOLD}{Colors.BLUE}{'=' * 60}{Colors.ENDC}")
|
||||
print(f"{Colors.BOLD}{Colors.BLUE}{text:^60}{Colors.ENDC}")
|
||||
print(f"{Colors.BOLD}{Colors.BLUE}{'=' * 60}{Colors.ENDC}\n")
|
||||
|
||||
def print_success(text):
|
||||
"""Druckt eine Erfolgsmeldung"""
|
||||
print(f"{Colors.GREEN}✅ {text}{Colors.ENDC}")
|
||||
|
||||
def print_warning(text):
|
||||
"""Druckt eine Warnung"""
|
||||
print(f"{Colors.YELLOW}⚠️ {text}{Colors.ENDC}")
|
||||
|
||||
def print_error(text):
|
||||
"""Druckt eine Fehlermeldung"""
|
||||
print(f"{Colors.RED}❌ {text}{Colors.ENDC}")
|
||||
|
||||
def print_info(text):
|
||||
"""Druckt eine Info-Meldung"""
|
||||
print(f"{Colors.BLUE}ℹ️ {text}{Colors.ENDC}")
|
||||
|
||||
def test_port_connection(ip, port, timeout=3):
|
||||
"""
|
||||
Testet die Verbindung zu einem bestimmten Port.
|
||||
|
||||
Args:
|
||||
ip: IP-Adresse
|
||||
port: Port-Nummer
|
||||
timeout: Timeout in Sekunden
|
||||
|
||||
Returns:
|
||||
bool: True wenn Verbindung möglich
|
||||
"""
|
||||
try:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(timeout)
|
||||
result = sock.connect_ex((ip, port))
|
||||
sock.close()
|
||||
return result == 0
|
||||
except Exception as e:
|
||||
print_error(f"Socket-Fehler: {e}")
|
||||
return False
|
||||
|
||||
def test_icmp_ping(ip):
|
||||
"""
|
||||
Führt einen ICMP Ping durch.
|
||||
|
||||
Args:
|
||||
ip: IP-Adresse
|
||||
|
||||
Returns:
|
||||
bool: True wenn Ping erfolgreich
|
||||
"""
|
||||
try:
|
||||
# Windows und Linux kompatibel
|
||||
param = '-n' if os.name == 'nt' else '-c'
|
||||
command = ['ping', param, '1', '-w', '2000', ip]
|
||||
result = subprocess.run(command, capture_output=True, text=True, timeout=5)
|
||||
return result.returncode == 0
|
||||
except Exception as e:
|
||||
print_error(f"Ping-Fehler: {e}")
|
||||
return False
|
||||
|
||||
def test_dns_resolution(hostname):
|
||||
"""
|
||||
Testet die DNS-Auflösung eines Hostnamens.
|
||||
|
||||
Args:
|
||||
hostname: Hostname zum Auflösen
|
||||
|
||||
Returns:
|
||||
str: Aufgelöste IP oder None
|
||||
"""
|
||||
try:
|
||||
ip = socket.gethostbyname(hostname)
|
||||
return ip
|
||||
except Exception as e:
|
||||
print_error(f"DNS-Auflösung fehlgeschlagen: {e}")
|
||||
return None
|
||||
|
||||
def test_tapo_connection(ip, username="admin", password="admin"):
|
||||
"""
|
||||
Testet die Tapo-Verbindung.
|
||||
|
||||
Args:
|
||||
ip: IP-Adresse der Steckdose
|
||||
username: Tapo-Benutzername
|
||||
password: Tapo-Passwort
|
||||
|
||||
Returns:
|
||||
dict: Ergebnis der Tests
|
||||
"""
|
||||
results = {
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"ip": ip,
|
||||
"tests": {}
|
||||
}
|
||||
|
||||
# Test 1: ICMP Ping
|
||||
print_info(f"Teste ICMP Ping zu {ip}...")
|
||||
ping_result = test_icmp_ping(ip)
|
||||
results["tests"]["icmp_ping"] = ping_result
|
||||
if ping_result:
|
||||
print_success(f"ICMP Ping zu {ip} erfolgreich")
|
||||
else:
|
||||
print_warning(f"ICMP Ping zu {ip} fehlgeschlagen (kann durch Firewall blockiert sein)")
|
||||
|
||||
# Test 2: Port 80 (HTTP)
|
||||
print_info(f"Teste Port 80 (HTTP) auf {ip}...")
|
||||
port80_result = test_port_connection(ip, 80)
|
||||
results["tests"]["port_80"] = port80_result
|
||||
if port80_result:
|
||||
print_success(f"Port 80 auf {ip} ist erreichbar")
|
||||
else:
|
||||
print_error(f"Port 80 auf {ip} ist NICHT erreichbar")
|
||||
|
||||
# Test 3: Port 9999 (Tapo-spezifisch)
|
||||
print_info(f"Teste Port 9999 (Tapo) auf {ip}...")
|
||||
port9999_result = test_port_connection(ip, 9999)
|
||||
results["tests"]["port_9999"] = port9999_result
|
||||
if port9999_result:
|
||||
print_success(f"Port 9999 auf {ip} ist erreichbar")
|
||||
else:
|
||||
print_warning(f"Port 9999 auf {ip} ist nicht erreichbar")
|
||||
|
||||
# Test 4: PyP100 Verbindung
|
||||
try:
|
||||
print_info("Teste PyP100 Bibliothek...")
|
||||
from PyP100.PyP100 import P100
|
||||
|
||||
print_info(f"Versuche Tapo-Handshake mit {ip}...")
|
||||
p100 = P100(ip, username, password)
|
||||
|
||||
# Handshake
|
||||
p100.handshake()
|
||||
print_success("Tapo-Handshake erfolgreich")
|
||||
results["tests"]["tapo_handshake"] = True
|
||||
|
||||
# Login
|
||||
p100.login()
|
||||
print_success("Tapo-Login erfolgreich")
|
||||
results["tests"]["tapo_login"] = True
|
||||
|
||||
# Device Info
|
||||
device_info = p100.getDeviceInfo()
|
||||
if device_info and 'error_code' in device_info and device_info['error_code'] == 0:
|
||||
print_success("Tapo-Geräteinformationen erfolgreich abgerufen")
|
||||
results["tests"]["tapo_device_info"] = True
|
||||
results["device_info"] = device_info.get('result', {})
|
||||
|
||||
# Status anzeigen
|
||||
device_on = device_info.get('result', {}).get('device_on', False)
|
||||
print_info(f"Steckdosen-Status: {'EIN' if device_on else 'AUS'}")
|
||||
else:
|
||||
print_error("Konnte Geräteinformationen nicht abrufen")
|
||||
results["tests"]["tapo_device_info"] = False
|
||||
|
||||
except ImportError:
|
||||
print_error("PyP100 Bibliothek nicht installiert!")
|
||||
print_info("Installiere mit: pip install PyP100")
|
||||
results["tests"]["pyp100_available"] = False
|
||||
except Exception as e:
|
||||
print_error(f"Tapo-Verbindung fehlgeschlagen: {e}")
|
||||
results["tests"]["tapo_connection"] = False
|
||||
results["error"] = str(e)
|
||||
|
||||
return results
|
||||
|
||||
def diagnose_network():
|
||||
"""Führt eine allgemeine Netzwerk-Diagnose durch"""
|
||||
print_header("Netzwerk-Diagnose")
|
||||
|
||||
# Lokale IP-Adresse ermitteln
|
||||
try:
|
||||
hostname = socket.gethostname()
|
||||
local_ip = socket.gethostbyname(hostname)
|
||||
print_info(f"Lokaler Hostname: {hostname}")
|
||||
print_info(f"Lokale IP-Adresse: {local_ip}")
|
||||
except Exception as e:
|
||||
print_error(f"Konnte lokale IP nicht ermitteln: {e}")
|
||||
|
||||
# Gateway ermitteln (nur Linux/Unix)
|
||||
if os.name != 'nt':
|
||||
try:
|
||||
result = subprocess.run(['ip', 'route', 'show'], capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
lines = result.stdout.strip().split('\n')
|
||||
for line in lines:
|
||||
if 'default' in line:
|
||||
gateway = line.split()[2]
|
||||
print_info(f"Standard-Gateway: {gateway}")
|
||||
break
|
||||
except:
|
||||
pass
|
||||
|
||||
# DNS-Test
|
||||
print_info("Teste DNS-Auflösung...")
|
||||
google_ip = test_dns_resolution("google.com")
|
||||
if google_ip:
|
||||
print_success(f"DNS funktioniert (google.com -> {google_ip})")
|
||||
else:
|
||||
print_error("DNS-Auflösung fehlgeschlagen")
|
||||
|
||||
def main():
|
||||
"""Hauptfunktion"""
|
||||
print_header("Tapo Steckdosen Diagnose-Tool")
|
||||
print_info(f"Start: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
|
||||
# Argumente prüfen
|
||||
if len(sys.argv) < 2:
|
||||
print_error("Verwendung: python diagnose_tapo.py <IP-Adresse> [username] [password]")
|
||||
print_info("Beispiel: python diagnose_tapo.py 192.168.1.100")
|
||||
print_info("Beispiel: python diagnose_tapo.py 192.168.1.100 admin admin")
|
||||
sys.exit(1)
|
||||
|
||||
ip_address = sys.argv[1]
|
||||
username = sys.argv[2] if len(sys.argv) > 2 else "admin"
|
||||
password = sys.argv[3] if len(sys.argv) > 3 else "admin"
|
||||
|
||||
# Netzwerk-Diagnose
|
||||
diagnose_network()
|
||||
|
||||
# Tapo-Diagnose
|
||||
print_header(f"Teste Tapo-Steckdose: {ip_address}")
|
||||
results = test_tapo_connection(ip_address, username, password)
|
||||
|
||||
# Zusammenfassung
|
||||
print_header("Diagnose-Zusammenfassung")
|
||||
|
||||
successful_tests = sum(1 for test, result in results["tests"].items() if result is True)
|
||||
total_tests = len(results["tests"])
|
||||
|
||||
print_info(f"Erfolgreiche Tests: {successful_tests}/{total_tests}")
|
||||
|
||||
# Empfehlungen
|
||||
if not results["tests"].get("port_80", False):
|
||||
print_warning("\nEmpfehlungen:")
|
||||
print_warning("1. Stelle sicher, dass die Steckdose eingeschaltet ist")
|
||||
print_warning("2. Prüfe, ob die IP-Adresse korrekt ist")
|
||||
print_warning("3. Stelle sicher, dass sich die Steckdose im gleichen Netzwerk befindet")
|
||||
print_warning("4. Prüfe Firewall-Einstellungen")
|
||||
print_warning("5. Versuche die Steckdose zurückzusetzen (Reset-Knopf)")
|
||||
|
||||
if results["tests"].get("port_80", False) and not results["tests"].get("tapo_login", False):
|
||||
print_warning("\nAuthentifizierungsproblem:")
|
||||
print_warning("1. Prüfe Benutzername und Passwort")
|
||||
print_warning("2. Standard-Credentials sind meist 'admin'/'admin'")
|
||||
print_warning("3. Wurden die Credentials in der Tapo-App geändert?")
|
||||
|
||||
print_info(f"\nEnde: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Reference in New Issue
Block a user