""" Module de chargement des refrigerants - Utilise directement IPM_DLL/simple_refrig_api.py """ import sys import os from pathlib import Path from typing import Dict, Optional, List # Prefer the packaged app.ipm module, but keep a fallback to the legacy # IPM_DLL folder for development compatibility. try: from app.ipm.simple_refrig_api import Refifc, MockRefifc # type: ignore except Exception: # Fall back to loading from IPM_DLL directory as before. Import the # module and pick attributes if present; older legacy wrappers may not # define MockRefifc. _current_dir = Path(__file__).parent.parent.parent _ipm_dll_dir = _current_dir / "IPM_DLL" if str(_ipm_dll_dir) not in sys.path: sys.path.insert(0, str(_ipm_dll_dir)) import simple_refrig_api as _sr # type: ignore Refifc = getattr(_sr, 'Refifc') MockRefifc = getattr(_sr, 'MockRefifc', None) class RefrigerantLibrary: """ Wrapper autour de Refifc pour compatibilite avec l'API. Utilise directement la classe Refifc qui fonctionne dans le code original. """ def __init__(self, refrig_name: str, libs_dir: Optional[Path] = None): """ Initialise le chargement du refrigerant. Args: refrig_name: Nom du refrigerant (ex: "R134a", "R290") libs_dir: Repertoire contenant les bibliotheques (optionnel, non utilise car Refifc gere ca) """ self.refrig_name = refrig_name # Utiliser Refifc directement - c'est la classe qui fonctionne dans le code original self._refifc = Refifc(refrig_name) # Exposer toutes les methodes de Refifc avec la meme signature def T_px(self, p: float, x: float) -> float: """Température à partir de pression (Pa) et qualité (retourne K). Note: les méthodes de bas niveau attendent et retournent des unités SI (pression en Pa, température en K, enthalpie en J/kg, entropie en J/kg.K). """ return self._refifc.T_px(p, x) def h_px(self, p: float, x: float) -> float: """Enthalpie à partir de pression (Pa) et qualité (retourne J/kg)""" return self._refifc.h_px(p, x) def h_pT(self, p: float, T: float) -> float: """Enthalpie à partir de pression (Pa) et température (K) (retourne J/kg)""" return self._refifc.h_pT(p, T) def x_ph(self, p: float, h: float) -> float: """Qualité à partir de pression (Pa) et enthalpie (J/kg)""" return self._refifc.x_ph(p, h) def p_Tx(self, T: float, x: float) -> float: """Pression à partir de température (K) et qualité (retourne Pa).""" return self._refifc.p_Tx(T, x) def Ts_px(self, p: float, x: float) -> float: """Température de saturation à partir de pression (Pa) et qualité (retourne K)""" return self._refifc.Ts_px(p, x) def rho_px(self, p: float, x: float) -> float: """Densité à partir de pression (Pa) et qualité""" return self._refifc.rho_px(p, x) def s_px(self, p: float, x: float) -> float: """Entropie à partir de pression (Pa) et qualité (retourne J/kg.K)""" return self._refifc.s_px(p, x) def hsl_px(self, p: float, x: float) -> float: """Enthalpie liquide saturée (retourne J/kg)""" return self._refifc.hsl_px(p, x) def hsv_px(self, p: float, x: float) -> float: """Enthalpie vapeur saturée (retourne J/kg)""" return self._refifc.hsv_px(p, x) def rhosl_px(self, p: float, x: float) -> float: """Densité liquide saturée""" return self._refifc.rhosl_px(p, x) def rhosv_px(self, p: float, x: float) -> float: """Densité vapeur saturée""" return self._refifc.rhosv_px(p, x) def p_begin(self) -> float: """Pression minimale du refrigerant (Pa)""" return self._refifc.p_begin() def p_end(self) -> float: """Pression maximale du refrigerant (Pa)""" return self._refifc.p_end() class RefrigerantManager: """Gestionnaire central pour tous les refrigerants disponibles""" # Liste des refrigerants supportes SUPPORTED_REFRIGERANTS = [ "R12", "R22", "R32", "R134a", "R290", "R404A", "R410A", "R452A", "R454A", "R454B", "R502", "R507A", "R513A", "R515B", "R717", "R744", "R1233zd", "R1234ze" ] def __init__(self, libs_dir: Optional[Path] = None): """ Initialise le gestionnaire Args: libs_dir: Repertoire contenant les bibliotheques """ self.libs_dir = libs_dir self._loaded_refrigerants: Dict[str, RefrigerantLibrary] = {} def get_available_refrigerants(self) -> List[Dict[str, str]]: """ Retourne la liste des refrigerants disponibles Returns: Liste de dictionnaires avec nom et disponibilite """ available = [] for refrig in self.SUPPORTED_REFRIGERANTS: try: # Tenter de charger pour verifier disponibilite if refrig not in self._loaded_refrigerants: self.load_refrigerant(refrig) available.append({ "name": refrig, "available": True, "loaded": refrig in self._loaded_refrigerants }) except Exception as e: available.append({ "name": refrig, "available": False, "error": str(e) }) return available def load_refrigerant(self, refrig_name: str) -> RefrigerantLibrary: """ Charge un refrigerant specifique Args: refrig_name: Nom du refrigerant Returns: Instance RefrigerantLibrary Raises: ValueError: Si le refrigerant n'est pas supporte RuntimeError: Si le chargement echoue """ if refrig_name not in self.SUPPORTED_REFRIGERANTS: raise ValueError( f"Refrigerant non supporte: {refrig_name}. " f"Supportes: {', '.join(self.SUPPORTED_REFRIGERANTS)}" ) if refrig_name in self._loaded_refrigerants: return self._loaded_refrigerants[refrig_name] try: lib = RefrigerantLibrary(refrig_name, self.libs_dir) self._loaded_refrigerants[refrig_name] = lib return lib except Exception as e: raise RuntimeError( f"Erreur chargement {refrig_name}: {e}" ) def get_refrigerant(self, refrig_name: str) -> RefrigerantLibrary: """ Obtient un refrigerant (le charge si necessaire) Args: refrig_name: Nom du refrigerant Returns: Instance RefrigerantLibrary """ if refrig_name not in self._loaded_refrigerants: return self.load_refrigerant(refrig_name) return self._loaded_refrigerants[refrig_name] def unload_all(self): """Decharge tous les refrigerants""" self._loaded_refrigerants.clear() # Instance globale du gestionnaire _manager: Optional[RefrigerantManager] = None def get_manager() -> RefrigerantManager: """Obtient l'instance globale du gestionnaire""" global _manager if _manager is None: _manager = RefrigerantManager() return _manager def get_refrigerant(name: str) -> RefrigerantLibrary: """ Fonction helper pour obtenir un refrigerant Args: name: Nom du refrigerant Returns: Instance RefrigerantLibrary """ return get_manager().get_refrigerant(name)