- Frontend v4 accessible sur réseau local (192.168.1.40) - Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard) - Ollama GPU fonctionnel - Self-healing interactif - Dashboard confiance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
254 lines
8.4 KiB
Python
254 lines
8.4 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
Test Direct du Service de Capture d'Écran - RPA Vision V3
|
|
Auteur : Dom, Alice, Kiro - 8 janvier 2026
|
|
|
|
Test direct du service sans les imports problématiques.
|
|
"""
|
|
|
|
import cv2
|
|
import numpy as np
|
|
import mss
|
|
import base64
|
|
import io
|
|
from PIL import Image
|
|
import threading
|
|
import time
|
|
import logging
|
|
|
|
class SimpleRealScreenCaptureService:
|
|
"""
|
|
Version simplifiée du service de capture d'écran réelle
|
|
"""
|
|
|
|
def __init__(self):
|
|
self.is_capturing = False
|
|
self.capture_thread = None
|
|
self.current_screenshot = None
|
|
self.detected_elements = []
|
|
|
|
self.capture_interval = 1.0
|
|
self.monitors = []
|
|
self.selected_monitor = 0
|
|
|
|
# Initialiser MSS pour la capture d'écran
|
|
try:
|
|
self.sct = mss.mss()
|
|
self._detect_monitors()
|
|
except Exception as e:
|
|
print(f"Warning: MSS non disponible: {e}")
|
|
self.sct = None
|
|
|
|
def _detect_monitors(self):
|
|
"""Détecte les moniteurs disponibles"""
|
|
try:
|
|
self.monitors = self.sct.monitors
|
|
print(f"Détecté {len(self.monitors)} moniteurs")
|
|
for i, monitor in enumerate(self.monitors):
|
|
print(f"Moniteur {i}: {monitor}")
|
|
except Exception as e:
|
|
print(f"Erreur lors de la détection des moniteurs: {e}")
|
|
self.monitors = [{"top": 0, "left": 0, "width": 1920, "height": 1080}]
|
|
|
|
def get_monitors(self):
|
|
"""Retourne la liste des moniteurs disponibles"""
|
|
return [
|
|
{
|
|
"id": i,
|
|
"width": monitor.get("width", 0),
|
|
"height": monitor.get("height", 0),
|
|
"top": monitor.get("top", 0),
|
|
"left": monitor.get("left", 0)
|
|
}
|
|
for i, monitor in enumerate(self.monitors)
|
|
]
|
|
|
|
def select_monitor(self, monitor_id: int) -> bool:
|
|
"""Sélectionne le moniteur à capturer"""
|
|
if 0 <= monitor_id < len(self.monitors):
|
|
self.selected_monitor = monitor_id
|
|
print(f"Moniteur sélectionné: {monitor_id}")
|
|
return True
|
|
return False
|
|
|
|
def start_capture(self, interval: float = 1.0) -> bool:
|
|
"""Démarre la capture d'écran en temps réel"""
|
|
if self.is_capturing:
|
|
print("Capture déjà en cours")
|
|
return False
|
|
|
|
self.capture_interval = interval
|
|
self.is_capturing = True
|
|
|
|
# Démarrer le thread de capture
|
|
self.capture_thread = threading.Thread(target=self._capture_loop, daemon=True)
|
|
self.capture_thread.start()
|
|
|
|
print(f"Capture démarrée (intervalle: {interval}s)")
|
|
return True
|
|
|
|
def stop_capture(self) -> bool:
|
|
"""Arrête la capture d'écran"""
|
|
if not self.is_capturing:
|
|
return False
|
|
|
|
self.is_capturing = False
|
|
|
|
if self.capture_thread and self.capture_thread.is_alive():
|
|
self.capture_thread.join(timeout=2.0)
|
|
|
|
print("Capture arrêtée")
|
|
return True
|
|
|
|
def _capture_loop(self):
|
|
"""Boucle principale de capture"""
|
|
while self.is_capturing:
|
|
try:
|
|
# Capturer l'écran
|
|
screenshot = self._capture_screen()
|
|
if screenshot is not None:
|
|
self.current_screenshot = screenshot
|
|
print(f"Screenshot capturé: {screenshot.shape}")
|
|
|
|
# Attendre avant la prochaine capture
|
|
time.sleep(self.capture_interval)
|
|
|
|
except Exception as e:
|
|
print(f"Erreur dans la boucle de capture: {e}")
|
|
time.sleep(1.0)
|
|
|
|
def _capture_screen(self):
|
|
"""Capture l'écran sélectionné"""
|
|
try:
|
|
if self.selected_monitor >= len(self.monitors):
|
|
self.selected_monitor = 0
|
|
|
|
monitor = self.monitors[self.selected_monitor]
|
|
|
|
# Capturer avec MSS
|
|
screenshot = self.sct.grab(monitor)
|
|
|
|
# Convertir en array numpy
|
|
img_array = np.array(screenshot)
|
|
|
|
# Convertir BGRA vers BGR (OpenCV)
|
|
if img_array.shape[2] == 4:
|
|
img_array = cv2.cvtColor(img_array, cv2.COLOR_BGRA2BGR)
|
|
|
|
return img_array
|
|
|
|
except Exception as e:
|
|
print(f"Erreur lors de la capture d'écran: {e}")
|
|
return None
|
|
|
|
def get_current_screenshot_base64(self):
|
|
"""Retourne la capture d'écran actuelle en base64"""
|
|
if self.current_screenshot is None:
|
|
return None
|
|
|
|
try:
|
|
# Convertir en PIL Image
|
|
if len(self.current_screenshot.shape) == 3:
|
|
# BGR vers RGB
|
|
rgb_image = cv2.cvtColor(self.current_screenshot, cv2.COLOR_BGR2RGB)
|
|
pil_image = Image.fromarray(rgb_image)
|
|
else:
|
|
pil_image = Image.fromarray(self.current_screenshot)
|
|
|
|
# Redimensionner pour l'affichage web
|
|
max_width = 1200
|
|
if pil_image.width > max_width:
|
|
ratio = max_width / pil_image.width
|
|
new_height = int(pil_image.height * ratio)
|
|
pil_image = pil_image.resize((max_width, new_height), Image.Resampling.LANCZOS)
|
|
|
|
# Convertir en base64
|
|
buffer = io.BytesIO()
|
|
pil_image.save(buffer, format='JPEG', quality=85)
|
|
img_base64 = base64.b64encode(buffer.getvalue()).decode('utf-8')
|
|
|
|
return f"data:image/jpeg;base64,{img_base64}"
|
|
|
|
except Exception as e:
|
|
print(f"Erreur lors de la conversion base64: {e}")
|
|
return None
|
|
|
|
def get_status(self):
|
|
"""Retourne le statut du service"""
|
|
return {
|
|
"is_capturing": self.is_capturing,
|
|
"selected_monitor": self.selected_monitor,
|
|
"monitors_count": len(self.monitors),
|
|
"capture_interval": self.capture_interval,
|
|
"elements_detected": len(self.detected_elements),
|
|
"has_screenshot": self.current_screenshot is not None
|
|
}
|
|
|
|
def cleanup(self):
|
|
"""Nettoie les ressources"""
|
|
self.stop_capture()
|
|
if hasattr(self, 'sct'):
|
|
self.sct.close()
|
|
|
|
def test_service_complet():
|
|
"""Test complet du service"""
|
|
print("=== Test Complet du Service de Capture ===")
|
|
|
|
service = SimpleRealScreenCaptureService()
|
|
|
|
try:
|
|
# 1. Test des moniteurs
|
|
monitors = service.get_monitors()
|
|
print(f"✅ Moniteurs détectés: {len(monitors)}")
|
|
for monitor in monitors:
|
|
print(f" - Moniteur {monitor['id']}: {monitor['width']}x{monitor['height']}")
|
|
|
|
# 2. Test de sélection de moniteur
|
|
if len(monitors) > 0:
|
|
success = service.select_monitor(0)
|
|
print(f"✅ Sélection moniteur 0: {success}")
|
|
|
|
# 3. Test de démarrage de capture
|
|
success = service.start_capture(interval=0.5)
|
|
print(f"✅ Démarrage capture: {success}")
|
|
|
|
# 4. Attendre quelques captures
|
|
print("Attente de 3 secondes pour les captures...")
|
|
time.sleep(3.0)
|
|
|
|
# 5. Vérifier le statut
|
|
status = service.get_status()
|
|
print(f"✅ Statut: {status}")
|
|
|
|
# 6. Obtenir une capture
|
|
screenshot = service.get_current_screenshot_base64()
|
|
if screenshot:
|
|
print(f"✅ Screenshot base64: {len(screenshot)} caractères")
|
|
print(f" Début: {screenshot[:50]}...")
|
|
else:
|
|
print("❌ Aucun screenshot disponible")
|
|
|
|
# 7. Arrêter la capture
|
|
success = service.stop_capture()
|
|
print(f"✅ Arrêt capture: {success}")
|
|
|
|
return screenshot is not None
|
|
|
|
except Exception as e:
|
|
print(f"❌ Erreur lors du test: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
finally:
|
|
service.cleanup()
|
|
|
|
if __name__ == "__main__":
|
|
print("🔍 Test Direct du Service de Capture d'Écran")
|
|
print("=" * 50)
|
|
|
|
if test_service_complet():
|
|
print("\n🎉 Service de capture fonctionnel !")
|
|
else:
|
|
print("\n❌ Problème avec le service de capture") |