""" Modeles pour les calculs de proprietes thermodynamiques """ from typing import Optional, Literal from pydantic import BaseModel, Field, field_validator class PropertyCalculationRequest(BaseModel): """Requete pour calculer des proprietes thermodynamiques""" refrigerant: str = Field( ..., description="Nom du refrigerant", example="R134a" ) calculation_type: Literal["px", "pT", "ph", "Tx"] = Field( ..., description="Type de calcul: px (pression-qualite), pT (pression-temperature), ph (pression-enthalpie), Tx (temperature-qualite)", example="px" ) # Parametres d'entree selon le type pressure: Optional[float] = Field( None, description="Pression en Pa", gt=0, example=500000 ) temperature: Optional[float] = Field( None, description="Temperature en K", gt=0, example=280.0 ) quality: Optional[float] = Field( None, description="Qualite (titre) entre 0 et 1", ge=0, le=1, example=0.5 ) enthalpy: Optional[float] = Field( None, description="Enthalpie en J/kg", example=250000 ) @field_validator('pressure') @classmethod def validate_pressure(cls, v, info): calc_type = info.data.get('calculation_type') if calc_type in ['px', 'pT', 'ph'] and v is None: raise ValueError(f"Pression requise pour le calcul {calc_type}") return v @field_validator('temperature') @classmethod def validate_temperature(cls, v, info): calc_type = info.data.get('calculation_type') if calc_type in ['pT', 'Tx'] and v is None: raise ValueError(f"Temperature requise pour le calcul {calc_type}") return v @field_validator('quality') @classmethod def validate_quality(cls, v, info): calc_type = info.data.get('calculation_type') if calc_type in ['px', 'Tx'] and v is None: raise ValueError(f"Qualite requise pour le calcul {calc_type}") return v @field_validator('enthalpy') @classmethod def validate_enthalpy(cls, v, info): calc_type = info.data.get('calculation_type') if calc_type == 'ph' and v is None: raise ValueError("Enthalpie requise pour le calcul ph") return v class Config: json_schema_extra = { "examples": [ { "refrigerant": "R134a", "calculation_type": "px", "pressure": 500000, "quality": 0.5 }, { "refrigerant": "R410A", "calculation_type": "pT", "pressure": 800000, "temperature": 280.0 }, { "refrigerant": "R744", "calculation_type": "ph", "pressure": 3000000, "enthalpy": 400000 } ] } class SaturationRequest(BaseModel): """Requete pour obtenir les proprietes de saturation""" refrigerant: str = Field( ..., description="Nom du refrigerant", example="R134a" ) pressure: float = Field( ..., description="Pression en Pa", gt=0, example=500000 ) class Config: json_schema_extra = { "example": { "refrigerant": "R134a", "pressure": 500000 } } class PropertyInputs(BaseModel): """Parametres d'entree du calcul""" pressure: Optional[float] = Field(None, description="Pression (Pa)") pressure_bar: Optional[float] = Field(None, description="Pression (bar)") temperature: Optional[float] = Field(None, description="Temperature (K)") temperature_celsius: Optional[float] = Field(None, description="Temperature (°C)") quality: Optional[float] = Field(None, description="Qualite (0-1)") enthalpy: Optional[float] = Field(None, description="Enthalpie (J/kg)") class ThermodynamicPropertiesDetailed(BaseModel): """Proprietes thermodynamiques detaillees""" temperature: float = Field(..., description="Temperature (K)") temperature_celsius: float = Field(..., description="Temperature (°C)") enthalpy: float = Field(..., description="Enthalpie (J/kg)") enthalpy_kj_kg: float = Field(..., description="Enthalpie (kJ/kg)") entropy: float = Field(..., description="Entropie (J/kg.K)") entropy_kj_kgK: float = Field(..., description="Entropie (kJ/kg.K)") density: float = Field(..., description="Masse volumique (kg/m³)") specific_volume: Optional[float] = Field(None, description="Volume specifique (m³/kg)") quality: Optional[float] = Field(None, description="Qualite (0-1)") class SaturationPropertiesDetailed(BaseModel): """Proprietes de saturation detaillees""" temperature: float = Field(..., description="Temperature de saturation (K)") temperature_celsius: float = Field(..., description="Temperature de saturation (°C)") enthalpy_liquid: float = Field(..., description="Enthalpie liquide (J/kg)") enthalpy_liquid_kj_kg: float = Field(..., description="Enthalpie liquide (kJ/kg)") enthalpy_vapor: float = Field(..., description="Enthalpie vapeur (J/kg)") enthalpy_vapor_kj_kg: float = Field(..., description="Enthalpie vapeur (kJ/kg)") density_liquid: float = Field(..., description="Masse volumique liquide (kg/m³)") density_vapor: float = Field(..., description="Masse volumique vapeur (kg/m³)") latent_heat: float = Field(..., description="Chaleur latente (J/kg)") latent_heat_kj_kg: float = Field(..., description="Chaleur latente (kJ/kg)") class PropertyCalculationResponse(BaseModel): """Reponse complete d'un calcul de proprietes""" refrigerant: str = Field(..., description="Nom du refrigerant") inputs: PropertyInputs = Field(..., description="Parametres d'entree") properties: ThermodynamicPropertiesDetailed = Field(..., description="Proprietes calculees") saturation: SaturationPropertiesDetailed = Field(..., description="Proprietes de saturation") note: Optional[str] = Field(None, description="Note informative") class PhaseProperties(BaseModel): """Proprietes d'une phase (liquide ou vapeur)""" enthalpy: float = Field(..., description="Enthalpie (J/kg)") enthalpy_kj_kg: float = Field(..., description="Enthalpie (kJ/kg)") density: float = Field(..., description="Masse volumique (kg/m³)") specific_volume: Optional[float] = Field(None, description="Volume specifique (m³/kg)") entropy: float = Field(..., description="Entropie (J/kg.K)") entropy_kj_kgK: float = Field(..., description="Entropie (kJ/kg.K)") class SaturationResponse(BaseModel): """Reponse pour les proprietes de saturation""" refrigerant: str = Field(..., description="Nom du refrigerant") pressure: float = Field(..., description="Pression (Pa)") pressure_bar: float = Field(..., description="Pression (bar)") temperature_saturation: float = Field(..., description="Temperature de saturation (K)") temperature_saturation_celsius: float = Field(..., description="Temperature de saturation (°C)") liquid: PhaseProperties = Field(..., description="Proprietes du liquide sature") vapor: PhaseProperties = Field(..., description="Proprietes de la vapeur saturee") latent_heat: float = Field(..., description="Chaleur latente (J/kg)") latent_heat_kj_kg: float = Field(..., description="Chaleur latente (kJ/kg)")