From ff93a2a2da28089e286e0b49c30602738a5ff135 Mon Sep 17 00:00:00 2001 From: Till Tomczak Date: Thu, 29 May 2025 22:59:04 +0200 Subject: [PATCH] "Refactor database shm and WAL paths for improved maintainability (feat)" --- backend/app/database/myp.db-shm | Bin 32768 -> 32768 bytes backend/app/database/myp.db-wal | Bin 24752 -> 37112 bytes backend/app/utils/printer_monitor.py | 76 +++++++++++++++++++-------- 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/backend/app/database/myp.db-shm b/backend/app/database/myp.db-shm index 14d0afe617ea4834ff6ea297a5b8c197fbdecf80..d11765ba1f4b3d3057fd79d6ec483f668d4d31ab 100644 GIT binary patch delta 177 zcmZo@U}|V!s+V}A%K!q*K+MR%AixQvrGVI^j{#XPZ>axeE3vzH;!&_9b8N>x zQq=>E0t1k_|B(Pxn2CXHVxv4K6OhXa!W$O`yH5V&%EidOap8LoW)23ZtG1I@ryu6|Qm#xI^qLZ=MkEtvEwUVkH qXcQQL%>9o9pu$WHtP>mMH*WE8op?ZG@*h{Ojhn6*ZN62Z#tr}(X*V7K diff --git a/backend/app/database/myp.db-wal b/backend/app/database/myp.db-wal index d3bce18e6db84c3adc0db6942aaad8413226963d..f51b2ba67fd89dd2d68d804dbb7315016f62a1f5 100644 GIT binary patch literal 37112 zcmeI*Pi)&%90%~UOWTdD38I<;8{2#+lrieQ_w47yp0<&6ZPR9s{BzPd#3k=@pIpe4l#!-}>M4zwN)~H~pvl0pD%Wga-s5009U<00Izz00bZa0SG|g zzat>;^BzCbmur}HD_t`$wg1-h+10eOC0(~NR-?`&+P~KuIMvsvo3(oVQZa9t=}g0_ z28vb9zH8y#t?iCyUM9#H}tP3`yH zSiXy)N#aKw$WHORmkUfcd%pkdEpob@3v~D&^N3$OAOHafKmY;|fB*y_009U<00O&D zpq1@-#B(yx>KX{_3x~t&0O3rwlrKM9GHZ)w)~pXMnB}ItSShVH_p^n5%KC@3`JB8E zU&{qa#9C>V3UYxzH%S-gQn9Ioo~fql*;4XKBUO&g$}7`MO+~fK=fmyo=Id51V^wPF zTVsUrLBa=_F42&oazkOV8q|Yo(B7jPOf@)_MKk59t%os#Fhgas7E(h*xAkn=n%FN# zF7Qg=`pg$Eo;ikGVE0XV>@fr&009U<00Izz00bZa0SMRxwwnvE;`~xb&cum4HkE8F zRmgCN&dIqPi^a}IQ}IPP9-A#@7vkfrTsdD!*7$rPk=l`5KrvKRrj!!S+~)!>OCQQt zK6&DE;NZ8kNhj_UgSWq2~k$L5CkR5Uk~k7!C`a;Y&owiCI4q8XIPJjhu{ai0t9|M|P?7k_!}B60!S zT)-j(AOHafKmY;|fB*y_009W>K7sA#0&6SD*|X!~lz@t?7ba^ z=KRP+bB0XEhT~ynxl)N{`2^3c?L;o15`*e8=equPzDMxF8=jkuXWpMiF0lKiJoXp@ z5P$##AOHafKmY;|fB*z+0^7|6mX#!3ER)1)ZDygFte)fL%!D#IGk11;eX6xEnFOx=OcA(CvpKEG#C}vDx^BO|M>!4Vz2MrkKkA1tFfbNR|k6!eCg@l zZ+Q+3_@DQEwBPEr4&1QmU=ackfB*y_009U<00IzrK!FzV`aEY2o*Xza5C|OJ8xCK{ zR4Y()it0?JT1X}`CCYKp##3gkAQ6>FgHpt-74v1Wa3KhO7v*-B2_xmTJ* zU6x3kB~p8d#AS(8qmFM%>jqH_s>mwS6eZ*fczQ&MEvb9!N;Q|2YR*bEd!?GoN;zeY zYrQ!uZAo2Qm&jd~s5(pJ_7YW>C5mlqy0pC=Q_S#pwmjad%Mul5iT}iuq?;A@Y^|uc zERi`&RP2h(tzt;M&y;LQom-d4T$V_kB{F-7)NP4D$DIl`DT)K_$OR7m@RGWcxc%nl zT)@|ZT;Ku!?PGNaKmY;|fB*y_009U%1dt1m9moZGt^Z3dAST1BTYl*N_i}+25mAMU gs7iGkRqa4@aW|?8%Bo1vRJA1`7jPB$-8UEb12i~a>i_@% delta 9 QcmeydkZHp~#tj=102z=3&Hw-a diff --git a/backend/app/utils/printer_monitor.py b/backend/app/utils/printer_monitor.py index ea723f30..5c569749 100644 --- a/backend/app/utils/printer_monitor.py +++ b/backend/app/utils/printer_monitor.py @@ -497,6 +497,7 @@ class PrinterMonitor: def auto_discover_tapo_outlets(self) -> Dict[str, bool]: """ Automatische Erkennung und Konfiguration von TP-Link Tapo P110-Steckdosen im Netzwerk. + Robuste Version mit Timeout-Behandlung und Fehler-Resilience. Returns: Dict[str, bool]: Ergebnis der Steckdosenerkennung mit IP als Schlüssel @@ -507,39 +508,68 @@ class PrinterMonitor: monitor_logger.info("🔍 Starte automatische Tapo-Steckdosenerkennung...") results = {} + start_time = time.time() # 1. Zuerst die Standard-IPs aus der Konfiguration testen monitor_logger.info(f"🔄 Teste {len(DEFAULT_TAPO_IPS)} Standard-IPs aus der Konfiguration") - for ip in DEFAULT_TAPO_IPS: + for i, ip in enumerate(DEFAULT_TAPO_IPS): try: - # TCP-Verbindungstest für Grundkonnektivität - ping_success = self._ping_address(ip, timeout=3) + # Fortschrittsmeldung + monitor_logger.info(f"🔍 Teste IP {i+1}/{len(DEFAULT_TAPO_IPS)}: {ip}") + + # Reduzierte Timeouts für schnellere Erkennung + ping_success = self._ping_address(ip, timeout=2) if ping_success: monitor_logger.info(f"✅ Steckdose mit IP {ip} ist erreichbar") - # Tapo-Verbindung testen + # Tapo-Verbindung testen mit Timeout-Schutz if TAPO_AVAILABLE: try: - from PyP100 import PyP100 - p100 = PyP100.P100(ip, TAPO_USERNAME, TAPO_PASSWORD) - p100.handshake() - p100.login() - device_info = p100.getDeviceInfo() + # Timeout für Tapo-Verbindung + import signal - # Steckdose gefunden und verbunden - nickname = device_info.get('nickname', f"Tapo P110 ({ip})") - state = "on" if device_info.get('device_on', False) else "off" + def timeout_handler(signum, frame): + raise TimeoutError("Tapo-Verbindung Timeout") - monitor_logger.info(f"✅ Tapo-Steckdose '{nickname}' ({ip}) gefunden - Status: {state}") - results[ip] = True + # Nur unter Unix/Linux verfügbar + if hasattr(signal, 'SIGALRM'): + signal.signal(signal.SIGALRM, timeout_handler) + signal.alarm(5) # 5 Sekunden Timeout - # Steckdose in Datenbank speichern/aktualisieren - self._ensure_tapo_in_database(ip, nickname) - - except Exception as e: - monitor_logger.debug(f"❌ IP {ip} ist erreichbar, aber keine Tapo-Steckdose: {str(e)}") + try: + from PyP100 import PyP100 + p100 = PyP100.P100(ip, TAPO_USERNAME, TAPO_PASSWORD) + p100.handshake() + p100.login() + device_info = p100.getDeviceInfo() + + # Timeout zurücksetzen + if hasattr(signal, 'SIGALRM'): + signal.alarm(0) + + # Steckdose gefunden und verbunden + nickname = device_info.get('nickname', f"Tapo P110 ({ip})") + state = "on" if device_info.get('device_on', False) else "off" + + monitor_logger.info(f"✅ Tapo-Steckdose '{nickname}' ({ip}) gefunden - Status: {state}") + results[ip] = True + + # Steckdose in Datenbank speichern/aktualisieren (nicht-blockierend) + try: + self._ensure_tapo_in_database(ip, nickname) + except Exception as db_error: + monitor_logger.warning(f"⚠️ Fehler beim Speichern in DB für {ip}: {str(db_error)}") + + except (TimeoutError, Exception) as tapo_error: + if hasattr(signal, 'SIGALRM'): + signal.alarm(0) # Timeout zurücksetzen + monitor_logger.debug(f"❌ IP {ip} ist erreichbar, aber keine Tapo-Steckdose oder Timeout: {str(tapo_error)}") + results[ip] = False + + except Exception as outer_error: + monitor_logger.debug(f"❌ Fehler bei Tapo-Test für {ip}: {str(outer_error)}") results[ip] = False else: monitor_logger.warning("⚠️ PyP100-Modul nicht verfügbar - kann Tapo-Verbindung nicht testen") @@ -549,12 +579,16 @@ class PrinterMonitor: results[ip] = False except Exception as e: - monitor_logger.error(f"❌ Fehler bei Steckdosen-Erkennung für IP {ip}: {str(e)}") + monitor_logger.warning(f"❌ Fehler bei Steckdosen-Erkennung für IP {ip}: {str(e)}") results[ip] = False + # Weiter mit nächster IP - nicht abbrechen + continue # Erfolgsstatistik berechnen success_count = sum(1 for success in results.values() if success) - monitor_logger.info(f"✅ Steckdosen-Erkennung abgeschlossen: {success_count}/{len(results)} Steckdosen gefunden") + elapsed_time = time.time() - start_time + + monitor_logger.info(f"✅ Steckdosen-Erkennung abgeschlossen: {success_count}/{len(results)} Steckdosen gefunden in {elapsed_time:.1f}s") # Markieren, dass automatische Erkennung durchgeführt wurde self.auto_discovered_tapo = True