steckdose timeout
This commit is contained in:
parent
2ab091b90c
commit
9502a9b3af
107
backend/app.py
107
backend/app.py
@ -654,8 +654,17 @@ def get_socket_uptime_events(socket_id=None, limit=100):
|
||||
|
||||
return [dict(row) for row in rows]
|
||||
|
||||
def check_socket_connection(socket_id):
|
||||
"""Überprüft die Verbindung zu einer Steckdose und aktualisiert den Status"""
|
||||
def check_socket_connection(socket_id, timeout=8):
|
||||
"""
|
||||
Überprüft die Verbindung zu einer Steckdose und aktualisiert den Status.
|
||||
|
||||
Args:
|
||||
socket_id: ID der Steckdose
|
||||
timeout: Timeout in Sekunden, nach dem die Verbindung als fehlgeschlagen gilt
|
||||
|
||||
Returns:
|
||||
True wenn die Steckdose online ist, sonst False
|
||||
"""
|
||||
socket = get_socket_by_id(socket_id)
|
||||
if not socket or not socket['ip_address']:
|
||||
return False
|
||||
@ -664,7 +673,8 @@ def check_socket_connection(socket_id):
|
||||
last_seen = socket.get('last_seen')
|
||||
|
||||
try:
|
||||
device = get_socket_device(socket['ip_address'])
|
||||
# Verwende den Timeout-Parameter für die Geräteverbindung
|
||||
device = get_socket_device(socket['ip_address'], timeout=timeout)
|
||||
if device:
|
||||
# Verbindung erfolgreich
|
||||
if previous_status != 'online':
|
||||
@ -672,14 +682,18 @@ def check_socket_connection(socket_id):
|
||||
duration = None
|
||||
if previous_status == 'offline' and last_seen:
|
||||
# Berechne die Dauer des Ausfalls
|
||||
try:
|
||||
offline_since = datetime.datetime.fromisoformat(last_seen)
|
||||
now = datetime.datetime.utcnow()
|
||||
duration = int((now - offline_since).total_seconds())
|
||||
except (ValueError, TypeError):
|
||||
# Wenn das Datum nicht geparst werden kann
|
||||
duration = None
|
||||
|
||||
log_socket_connection_event(socket_id, 'online', duration)
|
||||
return True
|
||||
else:
|
||||
# Keine Verbindung möglich
|
||||
# Keine Verbindung möglich oder Timeout
|
||||
if previous_status != 'offline':
|
||||
# Status hat sich von online/unknown auf offline geändert
|
||||
log_socket_connection_event(socket_id, 'offline')
|
||||
@ -691,20 +705,66 @@ def check_socket_connection(socket_id):
|
||||
return False
|
||||
|
||||
# Steckdosen-Steuerung mit PyP100
|
||||
def get_socket_device(ip_address):
|
||||
def get_socket_device(ip_address, timeout=8):
|
||||
"""
|
||||
Stellt eine Verbindung zu einer Tapo P100-Steckdose her, mit einem konfigurierbaren Timeout.
|
||||
|
||||
Args:
|
||||
ip_address: IP-Adresse der Steckdose
|
||||
timeout: Timeout in Sekunden, nach dem die Verbindung als fehlgeschlagen gilt
|
||||
|
||||
Returns:
|
||||
Das PyP100-Geräteobjekt bei erfolgreicher Verbindung, sonst None
|
||||
"""
|
||||
try:
|
||||
# Nutze Threading mit Timeout für die Verbindung
|
||||
import threading
|
||||
import queue
|
||||
|
||||
result_queue = queue.Queue()
|
||||
|
||||
def connect_with_timeout():
|
||||
try:
|
||||
device = PyP100.P100(ip_address, TAPO_USERNAME, TAPO_PASSWORD)
|
||||
device.handshake() # Erstellt die erforderlichen Cookies
|
||||
device.login() # Sendet Anmeldedaten und erstellt AES-Schlüssel
|
||||
app.logger.info(f"PyP100 Verbindung zu {ip_address} hergestellt")
|
||||
return device
|
||||
result_queue.put(device)
|
||||
except Exception as e:
|
||||
app.logger.error(f"Fehler bei der Anmeldung an P100-Gerät {ip_address}: {e}")
|
||||
result_queue.put(None)
|
||||
|
||||
# Starte den Verbindungsversuch in einem Thread
|
||||
connect_thread = threading.Thread(target=connect_with_timeout)
|
||||
connect_thread.daemon = True
|
||||
connect_thread.start()
|
||||
|
||||
# Warte mit Timeout auf das Ergebnis
|
||||
try:
|
||||
device = result_queue.get(timeout=timeout)
|
||||
if device:
|
||||
app.logger.info(f"PyP100 Verbindung zu {ip_address} hergestellt")
|
||||
return device
|
||||
except queue.Empty:
|
||||
app.logger.error(f"Timeout bei der Verbindung zu {ip_address} nach {timeout} Sekunden")
|
||||
return None
|
||||
|
||||
def turn_on_socket(ip_address):
|
||||
except Exception as e:
|
||||
app.logger.error(f"Unerwarteter Fehler bei der Anmeldung an P100-Gerät {ip_address}: {e}")
|
||||
return None
|
||||
|
||||
def turn_on_socket(ip_address, timeout=8):
|
||||
"""
|
||||
Schaltet eine Steckdose ein mit konfiguriertem Timeout.
|
||||
|
||||
Args:
|
||||
ip_address: IP-Adresse der Steckdose
|
||||
timeout: Timeout in Sekunden für die Verbindung
|
||||
|
||||
Returns:
|
||||
True bei Erfolg, False bei Fehlern oder Timeout
|
||||
"""
|
||||
try:
|
||||
device = get_socket_device(ip_address)
|
||||
device = get_socket_device(ip_address, timeout=timeout)
|
||||
if device:
|
||||
device.turnOn()
|
||||
app.logger.info(f"P100-Steckdose {ip_address} eingeschaltet")
|
||||
@ -714,9 +774,19 @@ def turn_on_socket(ip_address):
|
||||
app.logger.error(f"Fehler beim Einschalten der P100-Steckdose {ip_address}: {e}")
|
||||
return False
|
||||
|
||||
def turn_off_socket(ip_address):
|
||||
def turn_off_socket(ip_address, timeout=8):
|
||||
"""
|
||||
Schaltet eine Steckdose aus mit konfiguriertem Timeout.
|
||||
|
||||
Args:
|
||||
ip_address: IP-Adresse der Steckdose
|
||||
timeout: Timeout in Sekunden für die Verbindung
|
||||
|
||||
Returns:
|
||||
True bei Erfolg, False bei Fehlern oder Timeout
|
||||
"""
|
||||
try:
|
||||
device = get_socket_device(ip_address)
|
||||
device = get_socket_device(ip_address, timeout=timeout)
|
||||
if device:
|
||||
device.turnOff()
|
||||
app.logger.info(f"P100-Steckdose {ip_address} ausgeschaltet")
|
||||
@ -1405,16 +1475,18 @@ def check_jobs():
|
||||
app.logger.info(f"{len(expired_jobs)} abgelaufene Jobs überprüft, {handled_jobs} Steckdosen aktualisiert.")
|
||||
|
||||
def check_socket_connections():
|
||||
"""Überprüft periodisch die Verbindung zu allen Steckdosen."""
|
||||
"""Überprüft periodisch die Verbindung zu allen Steckdosen mit 8-Sekunden-Timeout."""
|
||||
with app.app_context():
|
||||
sockets = get_all_sockets()
|
||||
app.logger.info(f"Überprüfe Verbindungsstatus von {len(sockets)} Steckdosen")
|
||||
|
||||
online_count = 0
|
||||
offline_count = 0
|
||||
skipped_count = 0
|
||||
|
||||
for socket in sockets:
|
||||
if not socket['ip_address']:
|
||||
skipped_count += 1
|
||||
continue # Überspringe Steckdosen ohne IP-Adresse
|
||||
|
||||
is_online = check_socket_connection(socket['id'])
|
||||
@ -1422,16 +1494,17 @@ def check_socket_connections():
|
||||
online_count += 1
|
||||
else:
|
||||
offline_count += 1
|
||||
app.logger.warning(f"Steckdose {socket['name']} ({socket['ip_address']}) ist nicht erreichbar")
|
||||
|
||||
app.logger.info(f"Verbindungsüberprüfung abgeschlossen: {online_count} online, {offline_count} offline")
|
||||
app.logger.info(f"Verbindungsüberprüfung abgeschlossen: {online_count} online, {offline_count} offline, {skipped_count} übersprungen")
|
||||
|
||||
# Hintergrund-Thread für das Job-Polling und Steckdosen-Monitoring
|
||||
def background_job_checker():
|
||||
"""Hintergrund-Thread, der regelmäßig abgelaufene Jobs und Steckdosenverbindungen überprüft."""
|
||||
app.logger.info("Starte Hintergrund-Thread für Job-Überprüfung und Steckdosen-Monitoring")
|
||||
|
||||
# Standardintervall für Socket-Überprüfungen (5 Minuten)
|
||||
socket_check_interval = int(os.environ.get('SOCKET_CHECK_INTERVAL', '300'))
|
||||
# Standardintervall für Socket-Überprüfungen (2 Minuten)
|
||||
socket_check_interval = int(os.environ.get('SOCKET_CHECK_INTERVAL', '120'))
|
||||
last_socket_check = 0
|
||||
|
||||
while True:
|
||||
@ -1439,11 +1512,13 @@ def background_job_checker():
|
||||
# Überprüfe Jobs bei jedem Durchlauf
|
||||
check_jobs()
|
||||
|
||||
# Überprüfe Steckdosen nur in längeren Intervallen
|
||||
# Überprüfe Steckdosen in regelmäßigen Intervallen
|
||||
current_time = time.time()
|
||||
if current_time - last_socket_check >= socket_check_interval:
|
||||
# Socket-Überprüfung mit 8-Sekunden-Timeout pro Gerät
|
||||
check_socket_connections()
|
||||
last_socket_check = current_time
|
||||
app.logger.info(f"Nächste Socket-Überprüfung in {socket_check_interval} Sekunden")
|
||||
|
||||
except Exception as e:
|
||||
app.logger.error(f"Fehler im Hintergrund-Thread: {e}")
|
||||
|
Loading…
x
Reference in New Issue
Block a user