# Story 10.6: Mise à jour des Bindings Python **Epic:** 10 - Enhanced Boundary Conditions **Priorité:** P1-HIGH **Estimation:** 2h **Statut:** backlog **Dépendances:** Stories 10-2, 10-3, 10-4 --- ## Story > En tant qu'utilisateur Python de la librairie Entropyk, > Je veux accéder aux nouveaux types de conditions aux limites via l'API Python, > Afin de pouvoir utiliser les fonctionnalités avancées (concentration glycol, titre, psychrométrie). --- ## Contexte Les bindings Python (via PyO3) doivent être mis à jour pour exposer: 1. Les nouveaux types physiques (`Concentration`, `VolumeFlow`, `RelativeHumidity`, `VaporQuality`) 2. Les nouveaux composants (`RefrigerantSource`, `BrineSource`, `AirSource`, etc.) --- ## Spécifications Techniques ### 1. Exposer les Nouveaux Types Physiques ```python # bindings/python/entropyk/core.py class Concentration: """Concentration massique en % (0-100)""" @staticmethod def from_percent(value: float) -> 'Concentration': """Crée une concentration depuis un pourcentage.""" pass def to_percent(self) -> float: """Retourne la concentration en pourcentage.""" pass def to_mass_fraction(self) -> float: """Retourne la fraction massique (0-1).""" pass class VolumeFlow: """Débit volumique en m³/s""" @staticmethod def from_m3_per_s(value: float) -> 'VolumeFlow': pass @staticmethod def from_l_per_min(value: float) -> 'VolumeFlow': pass def to_m3_per_s(self) -> float: pass def to_l_per_min(self) -> float: pass class RelativeHumidity: """Humidité relative en % (0-100)""" @staticmethod def from_percent(value: float) -> 'RelativeHumidity': pass def to_percent(self) -> float: pass def to_fraction(self) -> float: pass class VaporQuality: """Titre (vapor quality) pour fluides frigorigènes (0-1)""" @staticmethod def from_fraction(value: float) -> 'VaporQuality': pass def to_fraction(self) -> float: pass def to_percent(self) -> float: pass ``` ### 2. Exposer les Nouveaux Composants ```python # bindings/python/entropyk/components.py class RefrigerantSource: """Source pour fluides frigorigènes compressibles.""" @staticmethod def new( fluid_id: str, pressure: Pressure, enthalpy: Enthalpy, outlet: ConnectedPort, ) -> 'RefrigerantSource': """Crée une source avec pression et enthalpie fixées.""" pass @staticmethod def with_vapor_quality( fluid_id: str, pressure: Pressure, vapor_quality: VaporQuality, outlet: ConnectedPort, ) -> 'RefrigerantSource': """Crée une source avec pression et titre fixés.""" pass def set_mass_flow(self, mass_flow: MassFlow) -> None: """Définit le débit massique imposé.""" pass class BrineSource: """Source pour fluides caloporteurs liquides.""" @staticmethod def water( temperature: Temperature, pressure: Pressure, outlet: ConnectedPort, ) -> 'BrineSource': """Crée une source d'eau pure.""" pass @staticmethod def glycol_mixture( fluid_id: str, concentration: Concentration, temperature: Temperature, pressure: Pressure, outlet: ConnectedPort, ) -> 'BrineSource': """Crée une source de mélange eau-glycol.""" pass class AirSource: """Source pour air humide.""" @staticmethod def from_dry_bulb_rh( temperature_dry: Temperature, relative_humidity: RelativeHumidity, pressure: Pressure, outlet: ConnectedPort, ) -> 'AirSource': """Crée une source avec température sèche et humidité relative.""" pass @staticmethod def from_dry_and_wet_bulb( temperature_dry: Temperature, temperature_wet_bulb: Temperature, pressure: Pressure, outlet: ConnectedPort, ) -> 'AirSource': """Crée une source avec températures sèche et bulbe humide.""" pass def specific_enthalpy(self) -> Enthalpy: """Retourne l'enthalpie spécifique de l'air humide.""" pass def humidity_ratio(self) -> float: """Retourne le rapport d'humidité.""" pass ``` --- ## Fichiers à Modifier | Fichier | Action | |---------|--------| | `bindings/python/src/core.rs` | Ajouter bindings pour nouveaux types | | `bindings/python/src/components.rs` | Ajouter bindings pour nouveaux composants | | `bindings/python/src/lib.rs` | Exporter les nouveaux types | | `bindings/python/tests/test_boundary.py` | Tests pour nouveaux types | --- ## Critères d'Acceptation - [ ] `Concentration` accessible depuis Python - [ ] `VolumeFlow` accessible depuis Python - [ ] `RelativeHumidity` accessible depuis Python - [ ] `VaporQuality` accessible depuis Python - [ ] `RefrigerantSource` et `RefrigerantSink` accessibles - [ ] `BrineSource` et `BrineSink` accessibles - [ ] `AirSource` et `AirSink` accessibles - [ ] Tests Python passent - [ ] Documentation Python générée --- ## Tests Requis ```python # bindings/python/tests/test_boundary.py def test_concentration(): c = Concentration.from_percent(30.0) assert c.to_percent() == 30.0 assert c.to_mass_fraction() == 0.3 def test_vapor_quality(): vq = VaporQuality.from_fraction(0.5) assert vq.to_fraction() == 0.5 assert vq.to_percent() == 50.0 def test_refrigerant_source(): source = RefrigerantSource.new( "R410A", Pressure.from_pascals(1e6), Enthalpy.from_joules_per_kg(280000), port ) assert source is not None def test_brine_source_glycol(): source = BrineSource.glycol_mixture( "MEG", Concentration.from_percent(30.0), Temperature.from_celsius(10.0), Pressure.from_pascals(3e5), port ) assert source is not None def test_air_source_psychrometrics(): source = AirSource.from_dry_bulb_rh( Temperature.from_celsius(25.0), RelativeHumidity.from_percent(50.0), Pressure.from_pascals(101325), port ) h = source.specific_enthalpy() w = source.humidity_ratio() assert h is not None assert w > 0 ``` --- ## Références - [Architecture Document](../../plans/boundary-condition-refactoring-architecture.md) - [Story 10-1: Nouveaux types physiques](./10-1-new-physical-types.md) - [PyO3 Documentation](https://pyo3.rs/)