diagram_ph/API_SPECIFICATION.md

11 KiB

API Diagramme PH - Spécifications Techniques

Vue d'ensemble

API REST pour générer des diagrammes Pression-Enthalpie (PH) de réfrigérants et effectuer des calculs thermodynamiques frigorifiques avancés.


Architecture Technique

Stack Technologique

  • Framework: FastAPI (Python 3.12+)
  • Bibliothèques thermodynamiques: DLL/SO personnalisées (IPM_DLL)
  • Visualisation: Matplotlib, Plotly
  • Déploiement: Docker + AWS Elastic Beanstalk
  • Format de réponse: JSON + images base64

Réfrigérants supportés

R12, R22, R32, R134a, R290, R404A, R410A, R452A, R454A, R454B, R502, R507A, R513A, R515B, R744 (CO2), R1233zd, R1234ze


Endpoints API

1. GET /api/v1/health

Description: Vérification de l'état de l'API

Réponse:

{
  "status": "healthy",
  "version": "1.0.0",
  "available_refrigerants": ["R134a", "R410A", ...]
}

2. GET /api/v1/refrigerants

Description: Liste des réfrigérants disponibles

Réponse:

{
  "refrigerants": [
    {
      "name": "R134a",
      "description": "HFC Refrigerant",
      "pressure_range": {"min": 51325, "max": 4059280, "unit": "Pa"},
      "temperature_range": {"min": -103.3, "max": 101.1, "unit": "°C"}
    },
    ...
  ]
}

3. POST /api/v1/diagram/generate

Description: Génération d'un diagramme PH

Request Body:

{
  "refrigerant": "R134a",
  "output_format": "plotly_json",  // "matplotlib_png", "plotly_json", "plotly_html"
  "points": [
    {
      "type": "PT",  // "PT", "PX", "PH", "TSX"
      "pressure": 500000,  // Pa
      "temperature": 5,    // °C
      "label": "Point 1",
      "order": 1
    },
    {
      "type": "PX",
      "pressure": 1500000,  // Pa
      "quality": 1.0,
      "label": "Point 2",
      "order": 2
    }
  ],
  "diagram_options": {
    "show_isotherms": true,
    "isotherm_step": 10,  // °C
    "show_saturation_lines": true,
    "title": "Custom Title (optional)",
    "width": 1000,
    "height": 800
  }
}

Réponse (format plotly_json):

{
  "success": true,
  "refrigerant": "R134a",
  "diagram_type": "PH",
  "output_format": "plotly_json",
  "data": {
    "plotly_figure": {
      "data": [...],  // Plotly traces
      "layout": {...}  // Plotly layout
    },
    "points_calculated": [
      {
        "label": "Point 1",
        "order": 1,
        "pressure": 500000,
        "temperature": 5,
        "enthalpy": 250000,
        "quality": 0.0,
        "entropy": 1200,
        "density": 1250
      }
    ]
  },
  "metadata": {
    "generated_at": "2025-10-18T12:30:00Z",
    "computation_time_ms": 245
  }
}

Réponse (format matplotlib_png):

{
  "success": true,
  "refrigerant": "R134a",
  "diagram_type": "PH",
  "output_format": "matplotlib_png",
  "data": {
    "image_base64": "iVBORw0KGgoAAAANSUhEUgAA...",
    "mime_type": "image/png",
    "points_calculated": [...]
  },
  "metadata": {...}
}

4. POST /api/v1/calculations/cycle

Description: Calculs de cycle frigorifique complet (COP, puissance, rendement)

Request Body:

{
  "refrigerant": "R134a",
  "cycle_type": "standard",  // "standard", "economizer", "two_stage"
  "points": {
    "evaporator_outlet": {
      "type": "PT",
      "pressure": 200000,
      "temperature": -10,
      "superheat": 5  // °C (optionnel)
    },
    "compressor_outlet": {
      "type": "PT",
      "pressure": 1500000,
      "temperature": 80
    },
    "condenser_outlet": {
      "type": "PT",
      "pressure": 1500000,
      "temperature": 40,
      "subcooling": 5  // °C (optionnel)
    },
    "expansion_valve_outlet": {
      "type": "PX",
      "pressure": 200000,
      "quality": 0.25
    }
  },
  "operating_conditions": {
    "mass_flow_rate": 0.05,  // kg/s
    "volumetric_efficiency": 0.85,
    "isentropic_efficiency": 0.75,
    "mechanical_efficiency": 0.95
  },
  "economizer": {  // Optionnel pour cycle avec économiseur
    "enabled": false,
    "intermediate_pressure": 600000,
    "subcooling_gain": 10
  }
}

Réponse:

{
  "success": true,
  "refrigerant": "R134a",
  "cycle_type": "standard",
  "results": {
    "cop": {
      "cop_cooling": 3.85,
      "cop_heating": 4.85,
      "carnot_cop": 5.2,
      "carnot_efficiency": 0.74
    },
    "capacities": {
      "cooling_capacity": 12500,  // W
      "heating_capacity": 15750,  // W
      "compressor_power": 3250    // W
    },
    "energies": {
      "evaporator_heat": 250000,    // J/kg
      "condenser_heat": 315000,     // J/kg
      "compressor_work": 65000      // J/kg
    },
    "efficiencies": {
      "volumetric_efficiency": 0.85,
      "isentropic_efficiency": 0.75,
      "mechanical_efficiency": 0.95,
      "overall_efficiency": 0.606
    },
    "mass_flow": {
      "refrigerant_mass_flow": 0.05,  // kg/s
      "volume_flow_rate": 0.04        // m³/s
    },
    "cycle_points": [
      {
        "point_name": "evaporator_outlet",
        "order": 1,
        "pressure": 200000,
        "temperature": -5,
        "enthalpy": 390000,
        "entropy": 1750,
        "quality": 1.0,
        "density": 8.5
      },
      {
        "point_name": "compressor_outlet",
        "order": 2,
        "pressure": 1500000,
        "temperature": 80,
        "enthalpy": 455000,
        "entropy": 1820,
        "quality": null,
        "density": 45.2
      }
    ]
  },
  "diagram_data": {
    "plotly_json": {...}  // Diagramme PH du cycle
  },
  "metadata": {
    "generated_at": "2025-10-18T12:30:00Z",
    "computation_time_ms": 185
  }
}

5. POST /api/v1/calculations/power

Description: Calcul de puissance entre deux points avec débit massique

Request Body:

{
  "refrigerant": "R134a",
  "point_1": {
    "type": "PT",
    "pressure": 500000,
    "temperature": 5
  },
  "point_2": {
    "type": "PT",
    "pressure": 1500000,
    "temperature": 80
  },
  "mass_flow_rate": 0.05,  // kg/s
  "process_type": "compression"  // "compression", "expansion", "heat_exchange"
}

Réponse:

{
  "success": true,
  "refrigerant": "R134a",
  "results": {
    "power": 3250,  // W
    "enthalpy_difference": 65000,  // J/kg
    "entropy_difference": 70,      // J/(kg·K)
    "point_1": {
      "pressure": 500000,
      "temperature": 5,
      "enthalpy": 390000,
      "entropy": 1750
    },
    "point_2": {
      "pressure": 1500000,
      "temperature": 80,
      "enthalpy": 455000,
      "entropy": 1820
    },
    "mass_flow_rate": 0.05
  }
}

6. POST /api/v1/properties/calculate

Description: Calcul des propriétés thermodynamiques à un point

Request Body:

{
  "refrigerant": "R134a",
  "point": {
    "type": "PT",  // "PT", "PX", "PH", "TX"
    "pressure": 500000,
    "temperature": 5
  }
}

Réponse:

{
  "success": true,
  "refrigerant": "R134a",
  "properties": {
    "pressure": 500000,          // Pa
    "temperature": 5,            // °C
    "enthalpy": 390000,          // J/kg
    "entropy": 1750,             // J/(kg·K)
    "density": 1250,             // kg/m³
    "quality": 1.0,              // 0-1 (null si surchauffe/sous-refroidissement)
    "specific_volume": 0.0008,   // m³/kg
    "cp": 1050,                  // J/(kg·K)
    "cv": 850,                   // J/(kg·K)
    "viscosity": 0.00012,        // Pa·s
    "thermal_conductivity": 0.015, // W/(m·K)
    "sound_velocity": 250,       // m/s
    "saturation_temperature": -10, // °C
    "phase": "superheated_vapor"  // "subcooled_liquid", "two_phase", "superheated_vapor"
  }
}

7. POST /api/v1/calculations/economizer

Description: Calculs spécifiques pour cycles avec économiseur

Request Body:

{
  "refrigerant": "R134a",
  "main_cycle": {
    "evaporator_pressure": 200000,
    "condenser_pressure": 1500000,
    "evaporator_superheat": 5,
    "condenser_subcooling": 5
  },
  "economizer": {
    "intermediate_pressure": 600000,
    "flash_gas_quality": 0.3,
    "subcooling_effectiveness": 0.8
  },
  "mass_flow_rate": 0.05,
  "efficiencies": {
    "isentropic_low_stage": 0.75,
    "isentropic_high_stage": 0.75,
    "volumetric": 0.85
  }
}

Réponse:

{
  "success": true,
  "refrigerant": "R134a",
  "results": {
    "performance": {
      "cop": 4.2,
      "cop_improvement": 9.1,  // % vs standard cycle
      "cooling_capacity": 13500,
      "total_compressor_power": 3214
    },
    "mass_flows": {
      "evaporator_flow": 0.05,
      "economizer_flash_gas": 0.008,
      "high_stage_flow": 0.058
    },
    "economizer_benefit": {
      "subcooling_increase": 8,  // °C
      "enthalpy_reduction": 12000,  // J/kg
      "capacity_increase": 8.0  // %
    },
    "cycle_points": [...]
  }
}

8. POST /api/v1/batch/calculate

Description: Calculs en batch pour plusieurs points ou configurations

Request Body:

{
  "refrigerant": "R134a",
  "calculations": [
    {
      "id": "calc_1",
      "type": "properties",
      "point": {"type": "PT", "pressure": 500000, "temperature": 5}
    },
    {
      "id": "calc_2",
      "type": "power",
      "point_1": {"type": "PT", "pressure": 500000, "temperature": 5},
      "point_2": {"type": "PT", "pressure": 1500000, "temperature": 80},
      "mass_flow_rate": 0.05
    }
  ]
}

Codes d'erreur

Code Description
400 Requête invalide (paramètres manquants ou invalides)
404 Réfrigérant non trouvé
422 Point thermodynamique hors limites
500 Erreur serveur (DLL, calcul)
503 Service temporairement indisponible

Format d'erreur:

{
  "success": false,
  "error": {
    "code": "INVALID_REFRIGERANT",
    "message": "Refrigerant R999 not found",
    "details": {
      "available_refrigerants": ["R134a", "R410A", ...]
    }
  }
}

Limites et Contraintes

Rate Limiting

  • 100 requêtes/minute par IP
  • 1000 requêtes/heure par IP

Taille des requêtes

  • Max 100 points par diagramme
  • Max 50 calculs par batch
  • Timeout: 30 secondes par requête

Précision des calculs

  • Pression: ±0.1%
  • Température: ±0.1 K
  • Enthalpie: ±0.5%

Exemples d'utilisation

Python

import requests

# Générer un diagramme PH
response = requests.post(
    "https://api.diagramph.com/api/v1/diagram/generate",
    json={
        "refrigerant": "R134a",
        "output_format": "plotly_json",
        "points": [
            {"type": "PT", "pressure": 500000, "temperature": 5, "order": 1},
            {"type": "PT", "pressure": 1500000, "temperature": 80, "order": 2}
        ]
    }
)

data = response.json()

JavaScript/React

const response = await fetch('https://api.diagramph.com/api/v1/diagram/generate', {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    refrigerant: 'R134a',
    output_format: 'plotly_json',
    points: [...]
  })
});

const data = await response.json();
// Utiliser Plotly.react() pour afficher le graphique

cURL

curl -X POST https://api.diagramph.com/api/v1/diagram/generate \
  -H "Content-Type: application/json" \
  -d '{
    "refrigerant": "R134a",
    "output_format": "matplotlib_png",
    "points": [
      {"type": "PT", "pressure": 500000, "temperature": 5}
    ]
  }'

Changelog

Version 1.0.0 (2025-10)

  • Endpoints de base pour diagrammes PH
  • Calculs de cycles frigorifiques
  • Support économiseur
  • 17 réfrigérants supportés