ci: commit workspace changes from notebook and backend fixes (excludes test_env, Frontend)
This commit is contained in:
1
app/models/__init__.py
Normal file
1
app/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Pydantic models for requests and responses"""
|
||||
223
app/models/cycle.py
Normal file
223
app/models/cycle.py
Normal file
@@ -0,0 +1,223 @@
|
||||
"""
|
||||
Modèles Pydantic pour les calculs de cycles frigorifiques.
|
||||
"""
|
||||
|
||||
from typing import Optional, List, Dict, Any
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
|
||||
|
||||
class CyclePoint(BaseModel):
|
||||
"""Point d'un cycle frigorifique."""
|
||||
|
||||
point_id: str = Field(
|
||||
...,
|
||||
description="Identifiant du point (1, 2, 3, 4, etc.)",
|
||||
examples=["1", "2", "3", "4"]
|
||||
)
|
||||
|
||||
pressure: float = Field(
|
||||
...,
|
||||
description="Pression (bar)",
|
||||
gt=0
|
||||
)
|
||||
|
||||
temperature: Optional[float] = Field(
|
||||
None,
|
||||
description="Température (°C)"
|
||||
)
|
||||
|
||||
enthalpy: Optional[float] = Field(
|
||||
None,
|
||||
description="Enthalpie (kJ/kg)"
|
||||
)
|
||||
|
||||
entropy: Optional[float] = Field(
|
||||
None,
|
||||
description="Entropie (kJ/kg.K)"
|
||||
)
|
||||
|
||||
quality: Optional[float] = Field(
|
||||
None,
|
||||
description="Titre vapeur (0-1)",
|
||||
ge=0,
|
||||
le=1
|
||||
)
|
||||
|
||||
description: Optional[str] = Field(
|
||||
None,
|
||||
description="Description du point"
|
||||
)
|
||||
|
||||
|
||||
class SimpleCycleRequest(BaseModel):
|
||||
"""
|
||||
Requête pour calcul de cycle frigorifique simple (4 points).
|
||||
|
||||
Vous pouvez spécifier soit les pressions, soit les températures de saturation :
|
||||
- evap_pressure OU evap_temperature (température d'évaporation)
|
||||
- cond_pressure OU cond_temperature (température de condensation)
|
||||
"""
|
||||
|
||||
refrigerant: str = Field(
|
||||
...,
|
||||
description="Code du réfrigérant",
|
||||
examples=["R134a", "R410A"]
|
||||
)
|
||||
|
||||
# Évaporation : Pression OU Température
|
||||
evap_pressure: Optional[float] = Field(
|
||||
None,
|
||||
description="Pression d'évaporation (bar). Utiliser soit evap_pressure, soit evap_temperature",
|
||||
gt=0,
|
||||
examples=[2.9]
|
||||
)
|
||||
|
||||
evap_temperature: Optional[float] = Field(
|
||||
None,
|
||||
description="Température d'évaporation (°C). Utiliser soit evap_pressure, soit evap_temperature",
|
||||
examples=[-10.0]
|
||||
)
|
||||
|
||||
# Condensation : Pression OU Température
|
||||
cond_pressure: Optional[float] = Field(
|
||||
None,
|
||||
description="Pression de condensation (bar). Utiliser soit cond_pressure, soit cond_temperature",
|
||||
gt=0,
|
||||
examples=[12.0]
|
||||
)
|
||||
|
||||
cond_temperature: Optional[float] = Field(
|
||||
None,
|
||||
description="Température de condensation (°C). Utiliser soit cond_pressure, soit cond_temperature",
|
||||
examples=[40.0]
|
||||
)
|
||||
|
||||
superheat: float = Field(
|
||||
5.0,
|
||||
description="Surchauffe à l'évaporateur (°C)",
|
||||
ge=0,
|
||||
examples=[5.0]
|
||||
)
|
||||
|
||||
subcool: float = Field(
|
||||
3.0,
|
||||
description="Sous-refroidissement au condenseur (°C)",
|
||||
ge=0,
|
||||
examples=[3.0]
|
||||
)
|
||||
|
||||
compressor_efficiency: Optional[float] = Field(
|
||||
None,
|
||||
description="Rendement isentropique du compresseur (0-1). Si non fourni, calculé automatiquement depuis le rapport de pression",
|
||||
gt=0,
|
||||
le=1,
|
||||
examples=[0.70, 0.85]
|
||||
)
|
||||
|
||||
mass_flow: float = Field(
|
||||
0.1,
|
||||
description="Débit massique (kg/s)",
|
||||
gt=0,
|
||||
examples=[0.1]
|
||||
)
|
||||
|
||||
@field_validator('evap_temperature')
|
||||
@classmethod
|
||||
def validate_evap_input(cls, v, info):
|
||||
"""Valide qu'on a soit evap_pressure, soit evap_temperature (mais pas les deux)."""
|
||||
evap_pressure = info.data.get('evap_pressure')
|
||||
|
||||
if evap_pressure is None and v is None:
|
||||
raise ValueError('Vous devez fournir soit evap_pressure, soit evap_temperature')
|
||||
|
||||
if evap_pressure is not None and v is not None:
|
||||
raise ValueError('Fournissez soit evap_pressure, soit evap_temperature (pas les deux)')
|
||||
|
||||
return v
|
||||
|
||||
@field_validator('cond_temperature')
|
||||
@classmethod
|
||||
def validate_cond_input(cls, v, info):
|
||||
"""Valide qu'on a soit cond_pressure, soit cond_temperature (mais pas les deux)."""
|
||||
cond_pressure = info.data.get('cond_pressure')
|
||||
|
||||
if cond_pressure is None and v is None:
|
||||
raise ValueError('Vous devez fournir soit cond_pressure, soit cond_temperature')
|
||||
|
||||
if cond_pressure is not None and v is not None:
|
||||
raise ValueError('Fournissez soit cond_pressure, soit cond_temperature (pas les deux)')
|
||||
|
||||
return v
|
||||
|
||||
|
||||
class CyclePerformance(BaseModel):
|
||||
"""Performances calculées du cycle."""
|
||||
|
||||
cop: float = Field(..., description="Coefficient de performance")
|
||||
cooling_capacity: float = Field(..., description="Puissance frigorifique (kW)")
|
||||
heating_capacity: float = Field(..., description="Puissance calorifique (kW)")
|
||||
compressor_power: float = Field(..., description="Puissance compresseur (kW)")
|
||||
compressor_efficiency: float = Field(..., description="Rendement isentropique du compresseur")
|
||||
mass_flow: float = Field(..., description="Débit massique (kg/s)")
|
||||
volumetric_flow: Optional[float] = Field(None, description="Débit volumique (m³/h)")
|
||||
compression_ratio: float = Field(..., description="Taux de compression")
|
||||
discharge_temperature: float = Field(..., description="Température refoulement (°C)")
|
||||
|
||||
|
||||
class SimpleCycleResponse(BaseModel):
|
||||
"""Réponse complète pour un cycle frigorifique simple."""
|
||||
|
||||
success: bool = Field(True, description="Succès de l'opération")
|
||||
|
||||
refrigerant: str = Field(..., description="Réfrigérant utilisé")
|
||||
|
||||
points: List[CyclePoint] = Field(
|
||||
...,
|
||||
description="Points du cycle (1: sortie évap, 2: refoulement, 3: sortie cond, 4: aspiration)"
|
||||
)
|
||||
|
||||
performance: CyclePerformance = Field(
|
||||
...,
|
||||
description="Performances du cycle"
|
||||
)
|
||||
|
||||
diagram_data: Optional[Dict[str, Any]] = Field(
|
||||
None,
|
||||
description="Données pour tracer le cycle sur diagramme PH"
|
||||
)
|
||||
|
||||
message: Optional[str] = Field(
|
||||
None,
|
||||
description="Message informatif"
|
||||
)
|
||||
|
||||
|
||||
class EconomizerCycleRequest(BaseModel):
|
||||
"""Requête pour cycle avec économiseur."""
|
||||
|
||||
refrigerant: str = Field(..., description="Code du réfrigérant")
|
||||
evap_pressure: float = Field(..., description="Pression évaporation (bar)", gt=0)
|
||||
intermediate_pressure: float = Field(..., description="Pression intermédiaire (bar)", gt=0)
|
||||
cond_pressure: float = Field(..., description="Pression condensation (bar)", gt=0)
|
||||
superheat: float = Field(5.0, description="Surchauffe (°C)", ge=0)
|
||||
subcool: float = Field(3.0, description="Sous-refroidissement (°C)", ge=0)
|
||||
compressor_efficiency: float = Field(0.70, description="Rendement compresseur", gt=0, le=1)
|
||||
mass_flow: float = Field(0.1, description="Débit massique total (kg/s)", gt=0)
|
||||
|
||||
@field_validator('intermediate_pressure')
|
||||
@classmethod
|
||||
def validate_intermediate_pressure(cls, v, info):
|
||||
"""Valide P_evap < P_inter < P_cond."""
|
||||
if 'evap_pressure' in info.data and v <= info.data['evap_pressure']:
|
||||
raise ValueError('intermediate_pressure doit être > evap_pressure')
|
||||
if 'cond_pressure' in info.data and v >= info.data['cond_pressure']:
|
||||
raise ValueError('intermediate_pressure doit être < cond_pressure')
|
||||
return v
|
||||
|
||||
|
||||
class CycleError(BaseModel):
|
||||
"""Erreur lors du calcul de cycle."""
|
||||
|
||||
success: bool = Field(False, description="Échec de l'opération")
|
||||
error: str = Field(..., description="Message d'erreur")
|
||||
details: Optional[str] = Field(None, description="Détails supplémentaires")
|
||||
188
app/models/diagram.py
Normal file
188
app/models/diagram.py
Normal file
@@ -0,0 +1,188 @@
|
||||
"""
|
||||
Modèles Pydantic pour les diagrammes PH.
|
||||
"""
|
||||
|
||||
from typing import Optional, List, Dict, Any
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
|
||||
|
||||
class DiagramPointRequest(BaseModel):
|
||||
"""Point personnalisé à tracer sur le diagramme."""
|
||||
|
||||
pressure: float = Field(
|
||||
...,
|
||||
description="Pression (bar)",
|
||||
gt=0
|
||||
)
|
||||
enthalpy: float = Field(
|
||||
...,
|
||||
description="Enthalpie (kJ/kg)"
|
||||
)
|
||||
temperature: Optional[float] = Field(
|
||||
None,
|
||||
description="Température (Celsius) - optionnel"
|
||||
)
|
||||
entropy: Optional[float] = Field(
|
||||
None,
|
||||
description="Entropie (kJ/kg.K) - optionnel"
|
||||
)
|
||||
quality: Optional[float] = Field(
|
||||
None,
|
||||
description="Titre vapeur (0-1) - optionnel",
|
||||
ge=0,
|
||||
le=1
|
||||
)
|
||||
label: Optional[str] = Field(
|
||||
None,
|
||||
description="Label du point - optionnel"
|
||||
)
|
||||
|
||||
|
||||
class PressureRange(BaseModel):
|
||||
"""Plage de pression."""
|
||||
min: float = Field(..., gt=0, description="Pression minimale (bar)")
|
||||
max: float = Field(..., gt=0, description="Pression maximale (bar)")
|
||||
|
||||
|
||||
class EnthalpyRange(BaseModel):
|
||||
"""Plage d'enthalpie."""
|
||||
min: float = Field(..., description="Enthalpie minimale (kJ/kg)")
|
||||
max: float = Field(..., description="Enthalpie maximale (kJ/kg)")
|
||||
|
||||
|
||||
class DiagramRequest(BaseModel):
|
||||
"""Requête pour générer un diagramme PH."""
|
||||
|
||||
refrigerant: str = Field(
|
||||
...,
|
||||
description="Code du réfrigérant (ex: R134a, R410A)",
|
||||
examples=["R134a", "R410A", "R744"]
|
||||
)
|
||||
|
||||
pressure_range: PressureRange = Field(
|
||||
...,
|
||||
description="Plage de pression du diagramme"
|
||||
)
|
||||
|
||||
enthalpy_range: Optional[EnthalpyRange] = Field(
|
||||
None,
|
||||
description="Plage d'enthalpie - auto si non fourni"
|
||||
)
|
||||
|
||||
include_isotherms: bool = Field(
|
||||
True,
|
||||
description="Inclure les isothermes"
|
||||
)
|
||||
|
||||
isotherm_values: Optional[List[float]] = Field(
|
||||
None,
|
||||
description="Températures isothermes spécifiques (Celsius)"
|
||||
)
|
||||
|
||||
cycle_points: Optional[List[Dict[str, float]]] = Field(
|
||||
None,
|
||||
description="Points du cycle [(enthalpy, pressure), ...]"
|
||||
)
|
||||
|
||||
title: Optional[str] = Field(
|
||||
None,
|
||||
description="Titre personnalisé du diagramme"
|
||||
)
|
||||
|
||||
format: str = Field(
|
||||
"both",
|
||||
description="Format: 'png', 'json', ou 'both'",
|
||||
pattern="^(png|json|both)$"
|
||||
)
|
||||
|
||||
width: int = Field(1400, gt=0, description="Largeur image (pixels)")
|
||||
height: int = Field(900, gt=0, description="Hauteur image (pixels)")
|
||||
dpi: int = Field(100, gt=0, description="DPI de l'image")
|
||||
|
||||
|
||||
class SaturationPoint(BaseModel):
|
||||
"""Point sur la courbe de saturation."""
|
||||
|
||||
enthalpy: float = Field(..., description="Enthalpie (kJ/kg)")
|
||||
pressure: float = Field(..., description="Pression (bar)")
|
||||
|
||||
|
||||
class IsothermCurve(BaseModel):
|
||||
"""Courbe isotherme."""
|
||||
|
||||
temperature: float = Field(..., description="Température (Celsius)")
|
||||
unit: str = Field("°C", description="Unité de température")
|
||||
points: List[SaturationPoint] = Field(
|
||||
...,
|
||||
description="Points de la courbe"
|
||||
)
|
||||
|
||||
|
||||
class DiagramPointResponse(BaseModel):
|
||||
"""Point personnalisé dans la réponse."""
|
||||
|
||||
enthalpy: float = Field(..., description="Enthalpie (kJ/kg)")
|
||||
pressure: float = Field(..., description="Pression (bar)")
|
||||
temperature: Optional[float] = Field(None, description="Température (Celsius)")
|
||||
entropy: Optional[float] = Field(None, description="Entropie (kJ/kg.K)")
|
||||
quality: Optional[float] = Field(None, description="Titre vapeur (0-1)")
|
||||
|
||||
|
||||
class DiagramDataResponse(BaseModel):
|
||||
"""Données JSON du diagramme."""
|
||||
|
||||
refrigerant: str = Field(..., description="Code du réfrigérant")
|
||||
|
||||
ranges: Dict[str, Optional[float]] = Field(
|
||||
...,
|
||||
description="Plages de valeurs du diagramme"
|
||||
)
|
||||
|
||||
saturation_curve: Dict[str, List[SaturationPoint]] = Field(
|
||||
...,
|
||||
description="Courbe de saturation (liquide et vapeur)"
|
||||
)
|
||||
|
||||
isotherms: Optional[List[IsothermCurve]] = Field(
|
||||
None,
|
||||
description="Courbes isothermes"
|
||||
)
|
||||
|
||||
custom_points: Optional[List[DiagramPointResponse]] = Field(
|
||||
None,
|
||||
description="Points personnalisés"
|
||||
)
|
||||
|
||||
|
||||
class DiagramResponse(BaseModel):
|
||||
"""Réponse complète de génération de diagramme."""
|
||||
|
||||
success: bool = Field(True, description="Succès")
|
||||
|
||||
image: Optional[str] = Field(
|
||||
None,
|
||||
description="Image PNG base64"
|
||||
)
|
||||
|
||||
data: Optional[Dict[str, Any]] = Field(
|
||||
None,
|
||||
description="Données JSON"
|
||||
)
|
||||
|
||||
metadata: Dict[str, Any] = Field(
|
||||
default_factory=dict,
|
||||
description="Métadonnées"
|
||||
)
|
||||
|
||||
message: Optional[str] = Field(
|
||||
None,
|
||||
description="Message"
|
||||
)
|
||||
|
||||
|
||||
class DiagramError(BaseModel):
|
||||
"""Erreur lors de la génération de diagramme."""
|
||||
|
||||
success: bool = Field(False, description="Échec de l'opération")
|
||||
error: str = Field(..., description="Message d'erreur")
|
||||
details: Optional[str] = Field(None, description="Détails supplémentaires")
|
||||
201
app/models/properties.py
Normal file
201
app/models/properties.py
Normal file
@@ -0,0 +1,201 @@
|
||||
"""
|
||||
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)")
|
||||
59
app/models/refrigerant.py
Normal file
59
app/models/refrigerant.py
Normal file
@@ -0,0 +1,59 @@
|
||||
"""
|
||||
Modeles Pydantic pour les refrigerants
|
||||
"""
|
||||
|
||||
from typing import Optional, List
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class RefrigerantInfo(BaseModel):
|
||||
"""Informations sur un refrigerant"""
|
||||
name: str = Field(..., description="Nom du refrigerant (ex: R134a)")
|
||||
available: bool = Field(..., description="Disponibilite de la bibliotheque")
|
||||
loaded: bool = Field(default=False, description="Si charge en memoire")
|
||||
error: Optional[str] = Field(None, description="Message d'erreur si indisponible")
|
||||
|
||||
|
||||
class RefrigerantsListResponse(BaseModel):
|
||||
"""Reponse pour la liste des refrigerants"""
|
||||
refrigerants: List[RefrigerantInfo] = Field(..., description="Liste des refrigerants")
|
||||
total: int = Field(..., description="Nombre total de refrigerants")
|
||||
available_count: int = Field(..., description="Nombre de refrigerants disponibles")
|
||||
|
||||
|
||||
class ThermodynamicProperties(BaseModel):
|
||||
"""Proprietes thermodynamiques d'un point"""
|
||||
temperature: float = Field(..., description="Temperature (K)")
|
||||
pressure: float = Field(..., description="Pression (Pa)")
|
||||
enthalpy: float = Field(..., description="Enthalpie (J/kg)")
|
||||
entropy: float = Field(..., description="Entropie (J/kg.K)")
|
||||
density: float = Field(..., description="Densite (kg/m3)")
|
||||
quality: Optional[float] = Field(None, description="Qualite (0-1)", ge=0, le=1)
|
||||
|
||||
|
||||
class SaturationProperties(BaseModel):
|
||||
"""Proprietes de saturation"""
|
||||
temperature_sat: float = Field(..., description="Temperature de saturation (K)")
|
||||
pressure: float = Field(..., description="Pression (Pa)")
|
||||
enthalpy_liquid: float = Field(..., description="Enthalpie liquide saturee (J/kg)")
|
||||
enthalpy_vapor: float = Field(..., description="Enthalpie vapeur saturee (J/kg)")
|
||||
density_liquid: float = Field(..., description="Densite liquide (kg/m3)")
|
||||
density_vapor: float = Field(..., description="Densite vapeur (kg/m3)")
|
||||
|
||||
|
||||
class PropertyRequest(BaseModel):
|
||||
"""Requete pour calculer des proprietes"""
|
||||
refrigerant: str = Field(..., description="Nom du refrigerant", example="R134a")
|
||||
pressure: float = Field(..., description="Pression (Pa)", gt=0)
|
||||
quality: Optional[float] = Field(None, description="Qualite (0-1)", ge=0, le=1)
|
||||
temperature: Optional[float] = Field(None, description="Temperature (K)", gt=0)
|
||||
enthalpy: Optional[float] = Field(None, description="Enthalpie (J/kg)")
|
||||
|
||||
class Config:
|
||||
json_schema_extra = {
|
||||
"example": {
|
||||
"refrigerant": "R134a",
|
||||
"pressure": 500000,
|
||||
"quality": 0.5
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user