#!/usr/bin/env python3 """ Script de diagnostic pour identifier et corriger le problème des diagrammes vides """ import sys import os import json import base64 import matplotlib matplotlib.use('Agg') # Backend non-interactif import matplotlib.pyplot as plt import numpy as np # Ajouter le répertoire parent pour importer les modules sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) def test_basic_matplotlib(): """Test si matplotlib fonctionne correctement.""" print("=== TEST MATPLOTLIB DE BASE ===") try: # Créer un graphique simple fig, ax = plt.subplots(figsize=(10, 6)) x = np.linspace(0, 10, 100) y = np.sin(x) ax.plot(x, y, 'b-', linewidth=2) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_title('Test Matplotlib') ax.grid(True) # Sauvegarder plt.savefig('test_matplotlib.png', dpi=100, bbox_inches='tight') plt.close(fig) # Vérifier le fichier if os.path.exists('test_matplotlib.png'): size = os.path.getsize('test_matplotlib.png') print(f"✅ Matplotlib fonctionne - Fichier : {size} octets") return True else: print("❌ Fichier non généré") return False except Exception as e: print(f"❌ Erreur matplotlib : {e}") return False def test_refrigerant_loading(): """Test le chargement du réfrigérant R290.""" print("\n=== TEST CHARGEMENT R290 ===") try: from app.core.refrigerant_loader import get_refrigerant refrigerant = get_refrigerant("R290") if refrigerant: print(f"✅ R290 chargé : {refrigerant.refrig_name}") # Test fonctions de base try: h_l = refrigerant.hsl_px(1.0, 0) / 1000 # kJ/kg h_v = refrigerant.hsv_px(1.0, 1) / 1000 # kJ/kg T_sat = refrigerant.T_px(1.0, 0.5) print(f" h_l(1 bar) : {h_l:.2f} kJ/kg") print(f" h_v(1 bar) : {h_v:.2f} kJ/kg") print(f" T_sat(1 bar) : {T_sat - 273.15:.2f} °C") if h_l is not None and h_v is not None and T_sat is not None: print("✅ Fonctions thermodynamiques OK") return True else: print("❌ Valeurs None retournées") return False except Exception as e: print(f"❌ Erreur fonctions thermodynamiques : {e}") return False else: print("❌ R290 non chargé") return False except Exception as e: print(f"❌ Erreur chargement R290 : {e}") return False def test_saturation_curve(): """Test la génération de la courbe de saturation.""" print("\n=== TEST COURBE DE SATURATION ===") try: from app.core.refrigerant_loader import get_refrigerant refrigerant = get_refrigerant("R290") Hsl, Hsv, Psat, Tsat = [], [], [], [] # Calculer quelques points for p_bar in [0.5, 1.0, 2.0, 5.0, 10.0, 20.0]: try: h_l = refrigerant.hsl_px(p_bar, 0) / 1000 h_v = refrigerant.hsv_px(p_bar, 1) / 1000 T_sat = refrigerant.T_px(p_bar, 0.5) if h_l is not None and h_v is not None and T_sat is not None: Hsl.append(h_l) Hsv.append(h_v) Psat.append(p_bar) Tsat.append(T_sat) except Exception: continue print(f"✅ Points calculés : {len(Hsl)}") if len(Hsl) > 2: # Créer le graphique fig, ax = plt.subplots(figsize=(10, 6)) ax.plot(Hsl, Psat, 'b-', linewidth=2, label='Liquide saturé') ax.plot(Hsv, Psat, 'r-', linewidth=2, label='Vapeur saturée') ax.set_xlabel('Enthalpie [kJ/kg]') ax.set_ylabel('Pression [bar]') ax.set_title('Courbe de Saturation R290') ax.set_yscale('log') ax.grid(True, which='both', alpha=0.3) ax.legend() plt.savefig('test_saturation.png', dpi=100, bbox_inches='tight') plt.close(fig) if os.path.exists('test_saturation.png'): size = os.path.getsize('test_saturation.png') print(f"✅ Courbe générée - Fichier : {size} octets") return True else: print("❌ Fichier non généré") return False else: print("❌ Pas assez de points") return False except Exception as e: print(f"❌ Erreur courbe saturation : {e}") import traceback traceback.print_exc() return False def test_complete_diagram(): """Test la génération complète du diagramme.""" print("\n=== TEST DIAGRAMME COMPLET ===") try: from app.core.refrigerant_loader import get_refrigerant from app.services.diagram_generator import DiagramGenerator # Créer le générateur refrigerant = get_refrigerant("R290") diagram_gen = DiagramGenerator(refrigerant) # Générer le diagramme fig = diagram_gen.plot_diagram( p_min=0.1, p_max=20.0, h_min=-100, h_max=600, include_isotherms=True, title="Test Complet R290" ) # Sauvegarder fig.savefig('test_complete.png', dpi=100, bbox_inches='tight') plt.close(fig) if os.path.exists('test_complete.png'): size = os.path.getsize('test_complete.png') print(f"✅ Diagramme complet généré - Fichier : {size} octets") # Vérifier si le fichier est valide if size > 1000: # Au moins 1 Ko print("✅ Fichier semble valide") return True else: print("❌ Fichier trop petit - probablement vide") return False else: print("❌ Fichier non généré") return False except Exception as e: print(f"❌ Erreur diagramme complet : {e}") import traceback traceback.print_exc() return False def test_api_direct(): """Test l'API directement.""" print("\n=== TEST API DIRECT ===") try: import requests # Charger la requête with open('request_r290.json', 'r') as f: request_data = json.load(f) # Appeler l'API response = requests.post("http://localhost:8001/api/v1/diagrams/ph", json=request_data, timeout=30) if response.status_code == 200: result = response.json() if 'image' in result and result['image']: # Décoder et sauvegarder image_data = base64.b64decode(result['image']) with open('test_api.png', 'wb') as f: f.write(image_data) size = len(image_data) print(f"✅ API fonctionne - Image : {size} octets") if size > 1000: print("✅ Image API valide") return True else: print("❌ Image API trop petite") return False else: print("❌ Pas d'image dans la réponse API") return False else: print(f"❌ Erreur API : {response.status_code}") return False except Exception as e: print(f"❌ Erreur API : {e}") return False def main(): """Fonction principale de diagnostic.""" print("🔍 DIAGNOSTIC COMPLET - API DIAGRAMMES PH") print("=" * 50) # Tests progressifs tests = [ ("Matplotlib de base", test_basic_matplotlib), ("Chargement R290", test_refrigerant_loading), ("Courbe de saturation", test_saturation_curve), ("Diagramme complet", test_complete_diagram), ("API directe", test_api_direct), ] results = [] for test_name, test_func in tests: print(f"\n🧪 {test_name}") print("-" * 30) try: result = test_func() results.append((test_name, result)) except Exception as e: print(f"❌ Erreur inattendue : {e}") results.append((test_name, False)) # Rapport final print("\n" + "=" * 50) print("📊 RAPPORT FINAL") print("=" * 50) success_count = 0 for test_name, success in results: status = "✅ SUCCÈS" if success else "❌ ÉCHEC" print(f"{status} - {test_name}") if success: success_count += 1 total_tests = len(results) success_rate = (success_count / total_tests) * 100 print(f"\n📈 Résumé : {success_count}/{total_tests} tests réussis ({success_rate:.1f}%)") if success_rate == 100: print("\n🎉 TOUS LES TESTS RÉUSSIS !") print("✅ Le système fonctionne parfaitement") elif success_rate >= 60: print("\n🟡 CERTAINS TESTS RÉUSSIS") print("⚠️ Des problèmes subsistent") else: print("\n🔴 NOMBREUX ÉCHECS") print("🚨 Des corrections majeures sont nécessaires") # Recommandations print("\n💡 RECOMMANDATIONS :") if not any(r[1] for r in results[:2]): # Matplotlib ou R290 print("- Vérifier l'installation de matplotlib") print("- Vérifier les fichiers DLL/SO dans libs/so/") if results[2][1] and not results[3][1]: # Saturation OK mais diagramme complet KO print("- Problème dans le service DiagramGenerator") print("- Vérifier les calculs d'isothermes") if results[3][1] and not results[4][1]: # Diagramme local OK mais API KO print("- Problème dans l'endpoint API") print("- Vérifier les logs de l'API") print("\n📁 Fichiers générés dans le répertoire courant") if __name__ == "__main__": main()