"feat: Integrate printer monitor for enhanced logging in backend"
This commit is contained in:
parent
81c2b2ab88
commit
482e04723d
@ -4345,3 +4345,535 @@ if __name__ == "__main__":
|
||||
except:
|
||||
pass
|
||||
sys.exit(1)
|
||||
|
||||
# ===== FILE-UPLOAD-ROUTEN =====
|
||||
|
||||
@app.route('/api/upload/job', methods=['POST'])
|
||||
@login_required
|
||||
def upload_job_file():
|
||||
"""
|
||||
Lädt eine Datei für einen Druckjob hoch
|
||||
|
||||
Form Data:
|
||||
file: Die hochzuladende Datei
|
||||
job_name: Name des Jobs (optional)
|
||||
"""
|
||||
try:
|
||||
if 'file' not in request.files:
|
||||
return jsonify({'error': 'Keine Datei ausgewählt'}), 400
|
||||
|
||||
file = request.files['file']
|
||||
job_name = request.form.get('job_name', '')
|
||||
|
||||
if file.filename == '':
|
||||
return jsonify({'error': 'Keine Datei ausgewählt'}), 400
|
||||
|
||||
# Metadaten für die Datei
|
||||
metadata = {
|
||||
'uploader_id': current_user.id,
|
||||
'uploader_name': current_user.username,
|
||||
'job_name': job_name
|
||||
}
|
||||
|
||||
# Datei speichern
|
||||
result = save_job_file(file, current_user.id, metadata)
|
||||
|
||||
if result:
|
||||
relative_path, absolute_path, file_metadata = result
|
||||
|
||||
app_logger.info(f"Job-Datei hochgeladen: {file_metadata['original_filename']} von User {current_user.id}")
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': 'Datei erfolgreich hochgeladen',
|
||||
'file_path': relative_path,
|
||||
'filename': file_metadata['original_filename'],
|
||||
'unique_filename': file_metadata['unique_filename'],
|
||||
'file_size': file_metadata['file_size'],
|
||||
'metadata': file_metadata
|
||||
})
|
||||
else:
|
||||
return jsonify({'error': 'Fehler beim Speichern der Datei'}), 500
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Hochladen der Job-Datei: {str(e)}")
|
||||
return jsonify({'error': f'Fehler beim Hochladen: {str(e)}'}), 500
|
||||
|
||||
@app.route('/api/upload/guest', methods=['POST'])
|
||||
def upload_guest_file():
|
||||
"""
|
||||
Lädt eine Datei für einen Gastauftrag hoch
|
||||
|
||||
Form Data:
|
||||
file: Die hochzuladende Datei
|
||||
guest_name: Name des Gasts (optional)
|
||||
guest_email: E-Mail des Gasts (optional)
|
||||
"""
|
||||
try:
|
||||
if 'file' not in request.files:
|
||||
return jsonify({'error': 'Keine Datei ausgewählt'}), 400
|
||||
|
||||
file = request.files['file']
|
||||
guest_name = request.form.get('guest_name', '')
|
||||
guest_email = request.form.get('guest_email', '')
|
||||
|
||||
if file.filename == '':
|
||||
return jsonify({'error': 'Keine Datei ausgewählt'}), 400
|
||||
|
||||
# Metadaten für die Datei
|
||||
metadata = {
|
||||
'guest_name': guest_name,
|
||||
'guest_email': guest_email
|
||||
}
|
||||
|
||||
# Datei speichern
|
||||
result = save_guest_file(file, metadata)
|
||||
|
||||
if result:
|
||||
relative_path, absolute_path, file_metadata = result
|
||||
|
||||
app_logger.info(f"Gast-Datei hochgeladen: {file_metadata['original_filename']} für {guest_name or 'Unbekannt'}")
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': 'Datei erfolgreich hochgeladen',
|
||||
'file_path': relative_path,
|
||||
'filename': file_metadata['original_filename'],
|
||||
'unique_filename': file_metadata['unique_filename'],
|
||||
'file_size': file_metadata['file_size'],
|
||||
'metadata': file_metadata
|
||||
})
|
||||
else:
|
||||
return jsonify({'error': 'Fehler beim Speichern der Datei'}), 500
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Hochladen der Gast-Datei: {str(e)}")
|
||||
return jsonify({'error': f'Fehler beim Hochladen: {str(e)}'}), 500
|
||||
|
||||
@app.route('/api/upload/avatar', methods=['POST'])
|
||||
@login_required
|
||||
def upload_avatar():
|
||||
"""
|
||||
Lädt ein Avatar-Bild für den aktuellen Benutzer hoch
|
||||
|
||||
Form Data:
|
||||
file: Das Avatar-Bild
|
||||
"""
|
||||
try:
|
||||
if 'file' not in request.files:
|
||||
return jsonify({'error': 'Keine Datei ausgewählt'}), 400
|
||||
|
||||
file = request.files['file']
|
||||
|
||||
if file.filename == '':
|
||||
return jsonify({'error': 'Keine Datei ausgewählt'}), 400
|
||||
|
||||
# Nur Bilder erlauben
|
||||
allowed_extensions = {'png', 'jpg', 'jpeg', 'gif', 'webp'}
|
||||
if not file.filename or '.' not in file.filename:
|
||||
return jsonify({'error': 'Ungültiger Dateityp'}), 400
|
||||
|
||||
file_ext = file.filename.rsplit('.', 1)[1].lower()
|
||||
if file_ext not in allowed_extensions:
|
||||
return jsonify({'error': 'Nur Bilddateien sind erlaubt (PNG, JPG, JPEG, GIF, WebP)'}), 400
|
||||
|
||||
# Alte Avatar-Datei löschen falls vorhanden
|
||||
db_session = get_db_session()
|
||||
user = db_session.query(User).get(current_user.id)
|
||||
if user and user.avatar_path:
|
||||
delete_file_safe(user.avatar_path)
|
||||
|
||||
# Neue Avatar-Datei speichern
|
||||
result = save_avatar_file(file, current_user.id)
|
||||
|
||||
if result:
|
||||
relative_path, absolute_path, file_metadata = result
|
||||
|
||||
# Avatar-Pfad in der Datenbank aktualisieren
|
||||
user.avatar_path = relative_path
|
||||
db_session.commit()
|
||||
db_session.close()
|
||||
|
||||
app_logger.info(f"Avatar hochgeladen für User {current_user.id}")
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': 'Avatar erfolgreich hochgeladen',
|
||||
'file_path': relative_path,
|
||||
'filename': file_metadata['original_filename'],
|
||||
'unique_filename': file_metadata['unique_filename'],
|
||||
'file_size': file_metadata['file_size']
|
||||
})
|
||||
else:
|
||||
db_session.close()
|
||||
return jsonify({'error': 'Fehler beim Speichern des Avatars'}), 500
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Hochladen des Avatars: {str(e)}")
|
||||
return jsonify({'error': f'Fehler beim Hochladen: {str(e)}'}), 500
|
||||
|
||||
@app.route('/api/upload/asset', methods=['POST'])
|
||||
@login_required
|
||||
@admin_required
|
||||
def upload_asset():
|
||||
"""
|
||||
Lädt ein statisches Asset hoch (nur für Administratoren)
|
||||
|
||||
Form Data:
|
||||
file: Die Asset-Datei
|
||||
asset_name: Name des Assets (optional)
|
||||
"""
|
||||
try:
|
||||
if 'file' not in request.files:
|
||||
return jsonify({'error': 'Keine Datei ausgewählt'}), 400
|
||||
|
||||
file = request.files['file']
|
||||
asset_name = request.form.get('asset_name', '')
|
||||
|
||||
if file.filename == '':
|
||||
return jsonify({'error': 'Keine Datei ausgewählt'}), 400
|
||||
|
||||
# Metadaten für die Datei
|
||||
metadata = {
|
||||
'uploader_id': current_user.id,
|
||||
'uploader_name': current_user.username,
|
||||
'asset_name': asset_name
|
||||
}
|
||||
|
||||
# Datei speichern
|
||||
result = file_manager.save_file(file, 'assets', current_user.id, 'asset', metadata)
|
||||
|
||||
if result:
|
||||
relative_path, absolute_path, file_metadata = result
|
||||
|
||||
app_logger.info(f"Asset hochgeladen: {file_metadata['original_filename']} von Admin {current_user.id}")
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': 'Asset erfolgreich hochgeladen',
|
||||
'file_path': relative_path,
|
||||
'filename': file_metadata['original_filename'],
|
||||
'unique_filename': file_metadata['unique_filename'],
|
||||
'file_size': file_metadata['file_size'],
|
||||
'metadata': file_metadata
|
||||
})
|
||||
else:
|
||||
return jsonify({'error': 'Fehler beim Speichern des Assets'}), 500
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Hochladen des Assets: {str(e)}")
|
||||
return jsonify({'error': f'Fehler beim Hochladen: {str(e)}'}), 500
|
||||
|
||||
@app.route('/api/upload/log', methods=['POST'])
|
||||
@login_required
|
||||
@admin_required
|
||||
def upload_log():
|
||||
"""
|
||||
Lädt eine Log-Datei hoch (nur für Administratoren)
|
||||
|
||||
Form Data:
|
||||
file: Die Log-Datei
|
||||
log_type: Typ des Logs (optional)
|
||||
"""
|
||||
try:
|
||||
if 'file' not in request.files:
|
||||
return jsonify({'error': 'Keine Datei ausgewählt'}), 400
|
||||
|
||||
file = request.files['file']
|
||||
log_type = request.form.get('log_type', 'allgemein')
|
||||
|
||||
if file.filename == '':
|
||||
return jsonify({'error': 'Keine Datei ausgewählt'}), 400
|
||||
|
||||
# Metadaten für die Datei
|
||||
metadata = {
|
||||
'uploader_id': current_user.id,
|
||||
'uploader_name': current_user.username,
|
||||
'log_type': log_type
|
||||
}
|
||||
|
||||
# Datei speichern
|
||||
result = file_manager.save_file(file, 'logs', current_user.id, 'log', metadata)
|
||||
|
||||
if result:
|
||||
relative_path, absolute_path, file_metadata = result
|
||||
|
||||
app_logger.info(f"Log-Datei hochgeladen: {file_metadata['original_filename']} von Admin {current_user.id}")
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': 'Log-Datei erfolgreich hochgeladen',
|
||||
'file_path': relative_path,
|
||||
'filename': file_metadata['original_filename'],
|
||||
'unique_filename': file_metadata['unique_filename'],
|
||||
'file_size': file_metadata['file_size'],
|
||||
'metadata': file_metadata
|
||||
})
|
||||
else:
|
||||
return jsonify({'error': 'Fehler beim Speichern der Log-Datei'}), 500
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Hochladen der Log-Datei: {str(e)}")
|
||||
return jsonify({'error': f'Fehler beim Hochladen: {str(e)}'}), 500
|
||||
|
||||
@app.route('/api/upload/backup', methods=['POST'])
|
||||
@login_required
|
||||
@admin_required
|
||||
def upload_backup():
|
||||
"""
|
||||
Lädt eine Backup-Datei hoch (nur für Administratoren)
|
||||
|
||||
Form Data:
|
||||
file: Die Backup-Datei
|
||||
backup_type: Typ des Backups (optional)
|
||||
"""
|
||||
try:
|
||||
if 'file' not in request.files:
|
||||
return jsonify({'error': 'Keine Datei ausgewählt'}), 400
|
||||
|
||||
file = request.files['file']
|
||||
backup_type = request.form.get('backup_type', 'allgemein')
|
||||
|
||||
if file.filename == '':
|
||||
return jsonify({'error': 'Keine Datei ausgewählt'}), 400
|
||||
|
||||
# Metadaten für die Datei
|
||||
metadata = {
|
||||
'uploader_id': current_user.id,
|
||||
'uploader_name': current_user.username,
|
||||
'backup_type': backup_type
|
||||
}
|
||||
|
||||
# Datei speichern
|
||||
result = file_manager.save_file(file, 'backups', current_user.id, 'backup', metadata)
|
||||
|
||||
if result:
|
||||
relative_path, absolute_path, file_metadata = result
|
||||
|
||||
app_logger.info(f"Backup-Datei hochgeladen: {file_metadata['original_filename']} von Admin {current_user.id}")
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': 'Backup-Datei erfolgreich hochgeladen',
|
||||
'file_path': relative_path,
|
||||
'filename': file_metadata['original_filename'],
|
||||
'unique_filename': file_metadata['unique_filename'],
|
||||
'file_size': file_metadata['file_size'],
|
||||
'metadata': file_metadata
|
||||
})
|
||||
else:
|
||||
return jsonify({'error': 'Fehler beim Speichern der Backup-Datei'}), 500
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Hochladen der Backup-Datei: {str(e)}")
|
||||
return jsonify({'error': f'Fehler beim Hochladen: {str(e)}'}), 500
|
||||
|
||||
@app.route('/api/upload/temp', methods=['POST'])
|
||||
@login_required
|
||||
def upload_temp_file():
|
||||
"""
|
||||
Lädt eine temporäre Datei hoch
|
||||
|
||||
Form Data:
|
||||
file: Die temporäre Datei
|
||||
purpose: Verwendungszweck (optional)
|
||||
"""
|
||||
try:
|
||||
if 'file' not in request.files:
|
||||
return jsonify({'error': 'Keine Datei ausgewählt'}), 400
|
||||
|
||||
file = request.files['file']
|
||||
purpose = request.form.get('purpose', '')
|
||||
|
||||
if file.filename == '':
|
||||
return jsonify({'error': 'Keine Datei ausgewählt'}), 400
|
||||
|
||||
# Metadaten für die Datei
|
||||
metadata = {
|
||||
'uploader_id': current_user.id,
|
||||
'uploader_name': current_user.username,
|
||||
'purpose': purpose
|
||||
}
|
||||
|
||||
# Datei speichern
|
||||
result = file_manager.save_file(file, 'temp', current_user.id, 'temp', metadata)
|
||||
|
||||
if result:
|
||||
relative_path, absolute_path, file_metadata = result
|
||||
|
||||
app_logger.info(f"Temporäre Datei hochgeladen: {file_metadata['original_filename']} von User {current_user.id}")
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': 'Temporäre Datei erfolgreich hochgeladen',
|
||||
'file_path': relative_path,
|
||||
'filename': file_metadata['original_filename'],
|
||||
'unique_filename': file_metadata['unique_filename'],
|
||||
'file_size': file_metadata['file_size'],
|
||||
'metadata': file_metadata
|
||||
})
|
||||
else:
|
||||
return jsonify({'error': 'Fehler beim Speichern der temporären Datei'}), 500
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Hochladen der temporären Datei: {str(e)}")
|
||||
return jsonify({'error': f'Fehler beim Hochladen: {str(e)}'}), 500
|
||||
|
||||
@app.route('/api/files/<path:file_path>', methods=['GET'])
|
||||
@login_required
|
||||
def serve_uploaded_file(file_path):
|
||||
"""
|
||||
Stellt hochgeladene Dateien bereit (mit Zugriffskontrolle)
|
||||
"""
|
||||
try:
|
||||
# Datei-Info abrufen
|
||||
file_info = file_manager.get_file_info(file_path)
|
||||
|
||||
if not file_info:
|
||||
return jsonify({'error': 'Datei nicht gefunden'}), 404
|
||||
|
||||
# Zugriffskontrolle basierend auf Dateikategorie
|
||||
if file_path.startswith('jobs/'):
|
||||
# Job-Dateien: Nur Besitzer und Admins
|
||||
if not current_user.is_admin:
|
||||
# Prüfen ob Benutzer der Besitzer ist
|
||||
if f"user_{current_user.id}" not in file_path:
|
||||
return jsonify({'error': 'Zugriff verweigert'}), 403
|
||||
|
||||
elif file_path.startswith('guests/'):
|
||||
# Gast-Dateien: Nur Admins
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'error': 'Zugriff verweigert'}), 403
|
||||
|
||||
elif file_path.startswith('avatars/'):
|
||||
# Avatar-Dateien: Öffentlich zugänglich für angemeldete Benutzer
|
||||
pass
|
||||
|
||||
elif file_path.startswith('temp/'):
|
||||
# Temporäre Dateien: Nur Besitzer und Admins
|
||||
if not current_user.is_admin:
|
||||
# Prüfen ob Benutzer der Besitzer ist
|
||||
if f"user_{current_user.id}" not in file_path:
|
||||
return jsonify({'error': 'Zugriff verweigert'}), 403
|
||||
|
||||
else:
|
||||
# Andere Dateien (assets, logs, backups): Nur Admins
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'error': 'Zugriff verweigert'}), 403
|
||||
|
||||
# Datei bereitstellen
|
||||
return send_file(file_info['absolute_path'], as_attachment=False)
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Bereitstellen der Datei {file_path}: {str(e)}")
|
||||
return jsonify({'error': 'Fehler beim Laden der Datei'}), 500
|
||||
|
||||
@app.route('/api/files/<path:file_path>', methods=['DELETE'])
|
||||
@login_required
|
||||
def delete_uploaded_file(file_path):
|
||||
"""
|
||||
Löscht eine hochgeladene Datei (mit Zugriffskontrolle)
|
||||
"""
|
||||
try:
|
||||
# Datei-Info abrufen
|
||||
file_info = file_manager.get_file_info(file_path)
|
||||
|
||||
if not file_info:
|
||||
return jsonify({'error': 'Datei nicht gefunden'}), 404
|
||||
|
||||
# Zugriffskontrolle basierend auf Dateikategorie
|
||||
if file_path.startswith('jobs/'):
|
||||
# Job-Dateien: Nur Besitzer und Admins
|
||||
if not current_user.is_admin:
|
||||
# Prüfen ob Benutzer der Besitzer ist
|
||||
if f"user_{current_user.id}" not in file_path:
|
||||
return jsonify({'error': 'Zugriff verweigert'}), 403
|
||||
|
||||
elif file_path.startswith('guests/'):
|
||||
# Gast-Dateien: Nur Admins
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'error': 'Zugriff verweigert'}), 403
|
||||
|
||||
elif file_path.startswith('avatars/'):
|
||||
# Avatar-Dateien: Nur Besitzer und Admins
|
||||
if not current_user.is_admin:
|
||||
# Prüfen ob Benutzer der Besitzer ist
|
||||
if f"user_{current_user.id}" not in file_path:
|
||||
return jsonify({'error': 'Zugriff verweigert'}), 403
|
||||
|
||||
elif file_path.startswith('temp/'):
|
||||
# Temporäre Dateien: Nur Besitzer und Admins
|
||||
if not current_user.is_admin:
|
||||
# Prüfen ob Benutzer der Besitzer ist
|
||||
if f"user_{current_user.id}" not in file_path:
|
||||
return jsonify({'error': 'Zugriff verweigert'}), 403
|
||||
|
||||
else:
|
||||
# Andere Dateien (assets, logs, backups): Nur Admins
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'error': 'Zugriff verweigert'}), 403
|
||||
|
||||
# Datei löschen
|
||||
if delete_file_safe(file_path):
|
||||
app_logger.info(f"Datei gelöscht: {file_path} von User {current_user.id}")
|
||||
return jsonify({'success': True, 'message': 'Datei erfolgreich gelöscht'})
|
||||
else:
|
||||
return jsonify({'error': 'Fehler beim Löschen der Datei'}), 500
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Löschen der Datei {file_path}: {str(e)}")
|
||||
return jsonify({'error': f'Fehler beim Löschen der Datei: {str(e)}'}), 500
|
||||
|
||||
@app.route('/api/admin/files/stats', methods=['GET'])
|
||||
@login_required
|
||||
@admin_required
|
||||
def get_file_stats():
|
||||
"""
|
||||
Gibt Statistiken zu allen Dateien zurück (nur für Administratoren)
|
||||
"""
|
||||
try:
|
||||
stats = file_manager.get_category_stats()
|
||||
|
||||
# Gesamtstatistiken berechnen
|
||||
total_files = sum(category.get('file_count', 0) for category in stats.values())
|
||||
total_size = sum(category.get('total_size', 0) for category in stats.values())
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'categories': stats,
|
||||
'totals': {
|
||||
'file_count': total_files,
|
||||
'total_size': total_size,
|
||||
'total_size_mb': round(total_size / (1024 * 1024), 2)
|
||||
}
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Abrufen der Datei-Statistiken: {str(e)}")
|
||||
return jsonify({'error': f'Fehler beim Abrufen der Statistiken: {str(e)}'}), 500
|
||||
|
||||
@app.route('/api/admin/files/cleanup', methods=['POST'])
|
||||
@login_required
|
||||
@admin_required
|
||||
def cleanup_temp_files():
|
||||
"""
|
||||
Räumt temporäre Dateien auf (nur für Administratoren)
|
||||
"""
|
||||
try:
|
||||
data = request.get_json() or {}
|
||||
max_age_hours = data.get('max_age_hours', 24)
|
||||
|
||||
# Temporäre Dateien aufräumen
|
||||
deleted_count = file_manager.cleanup_temp_files(max_age_hours)
|
||||
|
||||
app_logger.info(f"Temporäre Dateien aufgeräumt: {deleted_count} Dateien gelöscht")
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': f'{deleted_count} temporäre Dateien erfolgreich gelöscht',
|
||||
'deleted_count': deleted_count
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Aufräumen temporärer Dateien: {str(e)}")
|
||||
return jsonify({'error': f'Fehler beim Aufräumen: {str(e)}'}), 500
|
@ -138,8 +138,15 @@ class PrinterMonitor:
|
||||
monitor_logger.error("⚠️ PyP100-Modul nicht verfügbar - kann Tapo-Steckdose nicht schalten")
|
||||
return False
|
||||
|
||||
# Fallback zu globalen Anmeldedaten wenn keine lokalen vorhanden
|
||||
if not username or not password:
|
||||
username = TAPO_USERNAME
|
||||
password = TAPO_PASSWORD
|
||||
monitor_logger.debug(f"🔧 Verwende globale Tapo-Anmeldedaten für {ip_address}")
|
||||
|
||||
try:
|
||||
# TP-Link Tapo P100 Verbindung herstellen (P100 statt P110 verwenden)
|
||||
from PyP100 import PyP100
|
||||
p100 = PyP100.P100(ip_address, username, password)
|
||||
p100.handshake() # Authentifizierung
|
||||
p100.login() # Login
|
||||
@ -342,7 +349,7 @@ class PrinterMonitor:
|
||||
def _ping_address(self, ip_address: str, timeout: int = 3) -> bool:
|
||||
"""
|
||||
Führt einen Konnektivitätstest zu einer IP-Adresse durch.
|
||||
Verwendet TCP-Verbindung statt Ping, um Encoding-Probleme zu vermeiden.
|
||||
Verwendet ausschließlich TCP-Verbindung statt Ping, um Encoding-Probleme zu vermeiden.
|
||||
|
||||
Args:
|
||||
ip_address: Zu testende IP-Adresse
|
||||
@ -355,10 +362,18 @@ class PrinterMonitor:
|
||||
# IP-Adresse validieren
|
||||
ipaddress.ip_address(ip_address.strip())
|
||||
|
||||
# TCP-Verbindung zu Port 80 (HTTP) oder 443 (HTTPS) versuchen
|
||||
import socket
|
||||
|
||||
# Erst Port 80 versuchen (HTTP)
|
||||
# Erst Port 9999 versuchen (Tapo-Standard)
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(timeout)
|
||||
result = sock.connect_ex((ip_address.strip(), 9999))
|
||||
sock.close()
|
||||
|
||||
if result == 0:
|
||||
return True
|
||||
|
||||
# Falls Port 9999 nicht erfolgreich, Port 80 versuchen (HTTP)
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(timeout)
|
||||
result = sock.connect_ex((ip_address.strip(), 80))
|
||||
@ -481,15 +496,16 @@ class PrinterMonitor:
|
||||
|
||||
for ip in DEFAULT_TAPO_IPS:
|
||||
try:
|
||||
# Ping-Test für Grundkonnektivität
|
||||
ping_success = self._ping_address(ip, timeout=2)
|
||||
# TCP-Verbindungstest für Grundkonnektivität
|
||||
ping_success = self._ping_address(ip, timeout=3)
|
||||
|
||||
if ping_success:
|
||||
monitor_logger.info(f"✅ Steckdose mit IP {ip} ist pingbar")
|
||||
monitor_logger.info(f"✅ Steckdose mit IP {ip} ist erreichbar")
|
||||
|
||||
# Tapo-Verbindung testen
|
||||
if TAPO_AVAILABLE:
|
||||
try:
|
||||
from PyP100 import PyP100
|
||||
p100 = PyP100.P100(ip, TAPO_USERNAME, TAPO_PASSWORD)
|
||||
p100.handshake()
|
||||
p100.login()
|
||||
@ -506,7 +522,7 @@ class PrinterMonitor:
|
||||
self._ensure_tapo_in_database(ip, nickname)
|
||||
|
||||
except Exception as e:
|
||||
monitor_logger.debug(f"❌ IP {ip} ist pingbar, aber keine Tapo-Steckdose: {str(e)}")
|
||||
monitor_logger.debug(f"❌ IP {ip} ist erreichbar, aber keine Tapo-Steckdose: {str(e)}")
|
||||
results[ip] = False
|
||||
else:
|
||||
monitor_logger.warning("⚠️ PyP100-Modul nicht verfügbar - kann Tapo-Verbindung nicht testen")
|
||||
|
Loading…
x
Reference in New Issue
Block a user