Interfaces Graphiques et Outils Visuels
EnergySystemModels propose plusieurs outils graphiques pour faciliter la modélisation et la visualisation des systèmes énergétiques.
NodeEditor - Éditeur Graphique de Flux
Introduction
NodeEditor est un éditeur graphique basé sur PyQt5 qui permet de créer et simuler des réseaux de flux énergétiques de manière visuelle et interactive.
Fonctionnalités principales :
✅ Création de nœuds (sources, échangeurs, compresseurs, etc.)
✅ Connexion visuelle des composants
✅ Paramétrage interactif
✅ Simulation en temps réel
✅ Export des résultats
Installation
NodeEditor nécessite PyQt5 :
pip install energysystemmodels[gui]
# ou
pip install PyQt5
Lancement
from NodeEditor.NodeEditor import NodeEditor
import sys
from PyQt5.QtWidgets import QApplication
# Créer l'application
app = QApplication(sys.argv)
# Lancer l'éditeur
editor = NodeEditor()
editor.show()
# Boucle d'événements
sys.exit(app.exec_())
Ou directement depuis la ligne de commande :
python -m NodeEditor.NodeEditor
Interface utilisateur
L’interface se compose de :
Palette de composants (gauche) : Liste des composants disponibles
Zone de travail (centre) : Canvas pour dessiner le réseau
Panneau de propriétés (droite) : Paramètres du composant sélectionné
Barre d’outils (haut) : Commandes (nouveau, ouvrir, sauvegarder, simuler)
Composants disponibles
Sources et Puits :
Source: Source de fluide avec propriétés définiesSink: Puits de fluide (sortie du système)
Composants thermodynamiques :
Compressor: CompresseurTurbine: Turbine de détenteHEX: Échangeur de chaleurEvaporator: ÉvaporateurCondenser: CondenseurExpansion_Valve: Détendeur
Composants hydrauliques :
Pump: PompePipe: Tuyauterie avec pertes de chargeValve: Vanne de régulation
Composants CTA :
FreshAir: Prise d’air neufHeatingCoil: Batterie de chauffageCoolingCoil: Batterie de refroidissementFan: Ventilateur
Exemple : Créer un cycle frigorifique
from NodeEditor.NodeEditor import NodeEditor, Node, Connection
from PyQt5.QtWidgets import QApplication
import sys
app = QApplication(sys.argv)
editor = NodeEditor()
# Créer les nœuds
evaporator = editor.add_node('Evaporator', x=100, y=200)
compressor = editor.add_node('Compressor', x=300, y=200)
condenser = editor.add_node('Condenser', x=500, y=200)
valve = editor.add_node('Expansion_Valve', x=300, y=400)
# Connecter les nœuds
editor.connect(evaporator, compressor)
editor.connect(compressor, condenser)
editor.connect(condenser, valve)
editor.connect(valve, evaporator)
# Paramétrer
evaporator.set_parameter('P_evap', 2.5) # bar
evaporator.set_parameter('fluid', 'R134a')
compressor.set_parameter('P_cond', 8.0) # bar
compressor.set_parameter('eta', 0.75)
# Simuler
editor.simulate()
# Afficher les résultats
print(f"COP : {editor.get_result('COP'):.2f}")
print(f"Puissance froid : {editor.get_result('Q_evap'):.2f} kW")
editor.show()
sys.exit(app.exec_())
Sauvegarde et chargement
Les projets peuvent être sauvegardés au format JSON :
# Sauvegarder
editor.save_project('mon_cycle.json')
# Charger
editor.load_project('mon_cycle.json')
TkinterGUI - Interface Tkinter pour Chillers
Introduction
TkinterGUI fournit une interface graphique simple basée sur Tkinter pour simuler des groupes frigorifiques (chillers).
Lancement
from TkinterGUI.ChillerGUI import ChillerGUI
# Créer et lancer l'interface
gui = ChillerGUI()
gui.run()
Ou depuis la ligne de commande :
python -m TkinterGUI.ChillerGUI
Fonctionnalités
Sélection du fluide frigorigène : R134a, R32, R410A, etc.
Paramètres d’évaporation : Température ou pression
Paramètres de condensation : Température ou pression
Rendements : Isentropique, volumétrique
Calcul en temps réel : Mise à jour automatique des résultats
Diagramme P-h : Visualisation du cycle sur diagramme de Mollier
Exemple d’utilisation
Lancer l’interface :
python -m TkinterGUI.ChillerGUISélectionner le fluide :
R134aTempérature évaporation :
5°CTempérature condensation :
40°CDébit massique :
0.5 kg/sRendement isentropique :
0.75Cliquer sur Calculer
Résultats affichés :
Puissance frigorifique :
XX.X kWPuissance compresseur :
XX.X kWCOP :
X.XXTempérature refoulement :
XX°CTaux de compression :
X.XX
PyqtSimulator - Simulateur Temps Réel
Introduction
PyqtSimulator est un simulateur interactif permettant de visualiser le comportement dynamique des systèmes énergétiques.
Fonctionnalités
Simulation temporelle : Évolution des paramètres dans le temps
Graphiques en temps réel : Courbes de température, pression, puissance
Contrôle de régulation : PID, ON/OFF, etc.
Scenarios dynamiques : Changement de consignes, perturbations
Export de données : CSV, Excel
Lancement
from PyqtSimulator.Simulator import Simulator
from PyQt5.QtWidgets import QApplication
import sys
app = QApplication(sys.argv)
simulator = Simulator()
simulator.show()
sys.exit(app.exec_())
Exemple : Régulation de température
from PyqtSimulator.Simulator import Simulator, PID_Controller
from PyQt5.QtWidgets import QApplication
import sys
app = QApplication(sys.argv)
simulator = Simulator()
# Définir le système
simulator.set_system('heating_coil')
simulator.set_parameter('T_setpoint', 20) # °C
simulator.set_parameter('T_outdoor', -5) # °C
# Configurer le régulateur PID
pid = PID_Controller(Kp=10, Ki=0.5, Kd=2)
simulator.set_controller(pid)
# Lancer la simulation
simulator.run(duration=3600, timestep=10) # 1h, pas de 10s
# Visualiser
simulator.plot(['T_indoor', 'T_setpoint', 'Q_heating'])
simulator.show()
sys.exit(app.exec_())
Visualisations Graphiques
EnergySystemModels intègre de nombreuses fonctions de visualisation basées sur matplotlib.
Courbes composites (Pinch Analysis)
from PinchAnalysis import PinchAnalysis
import pandas as pd
df = pd.DataFrame({
'Ti': [200, 125, 50, 45],
'To': [50, 45, 250, 195],
'mCp': [3.0, 2.5, 2.0, 4.0],
'dTmin2': [5, 5, 5, 5],
'integration': [True, True, True, True]
})
pinch = PinchAnalysis.Object(df)
# Courbes composites
pinch.plot_composites_curves()
# Grande courbe composite
pinch.plot_GCC()
# Flux et intervalles
pinch.plot_streams_and_temperature_intervals()
# Réseau d'échangeurs
pinch.graphical_hen_design()
Diagramme P-h (Cycles thermodynamiques)
from ThermodynamicCycles.Chiller import Chiller
import matplotlib.pyplot as plt
chiller = Chiller()
chiller.fluid = "R134a"
chiller.T_evap = 5
chiller.T_cond = 40
chiller.calculate()
# Tracer le cycle sur diagramme P-h
chiller.plot_ph_diagram()
plt.show()
Profils de température
from HeatTransfer.CompositeWall import CompositeWall
import matplotlib.pyplot as plt
wall = CompositeWall.Object()
wall.add_layer(0.02, 0.25)
wall.add_layer(0.15, 0.04)
wall.add_layer(0.20, 1.40)
wall.T_interior = 20
wall.T_exterior = -5
wall.calculate()
# Tracer le profil de température
profile = wall.get_temperature_profile()
plt.plot(profile['position'], profile['temperature'])
plt.xlabel('Position dans le mur [m]')
plt.ylabel('Température [°C]')
plt.title('Profil de température')
plt.grid(True)
plt.show()
Cartes de performance
import numpy as np
import matplotlib.pyplot as plt
from ThermodynamicCycles.Compressor import Compressor
# Créer une carte de performance
T_evap_range = np.arange(-10, 15, 1)
T_cond_range = np.arange(30, 50, 1)
COP_map = np.zeros((len(T_evap_range), len(T_cond_range)))
for i, T_evap in enumerate(T_evap_range):
for j, T_cond in enumerate(T_cond_range):
# Calculer le COP pour chaque point
compressor = Compressor.Object()
# ... configuration et calcul ...
COP_map[i, j] = compressor.COP
# Tracer la carte
plt.contourf(T_cond_range, T_evap_range, COP_map, levels=20, cmap='RdYlGn')
plt.colorbar(label='COP')
plt.xlabel('Température condensation [°C]')
plt.ylabel('Température évaporation [°C]')
plt.title('Carte de COP')
plt.show()
Export et rapports
Les résultats peuvent être exportés dans divers formats :
Export Excel
import pandas as pd
from AHU.GenericAHU import GenericAHU
ahu = GenericAHU()
results = ahu.run_simulation('config.xlsx',
'1. Air Recycling AHU Input',
output_file='resultats.xlsx')
# Les résultats sont automatiquement écrits dans resultats.xlsx
Export CSV
# Sauvegarder les résultats en CSV
results.to_csv('resultats.csv', index=False)
Génération de rapports PDF
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from PinchAnalysis import PinchAnalysis
pinch = PinchAnalysis.Object(df)
# Créer le PDF
c = canvas.Canvas("rapport_pinch.pdf", pagesize=A4)
c.drawString(100, 800, "Rapport d'Analyse Pinch")
c.drawString(100, 780, f"Point Pinch : {pinch.T_pinch}°C")
c.drawString(100, 760, f"Utilité chaude : {pinch.Qh_min} kW")
c.drawString(100, 740, f"Utilité froide : {pinch.Qc_min} kW")
# Ajouter les graphiques
pinch.plot_composites_curves()
plt.savefig('temp_composite.png', dpi=150)
c.drawImage('temp_composite.png', 100, 400, width=400, height=300)
c.save()
Dashboards interactifs
Intégration avec Plotly Dash
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.graph_objs as go
from ThermodynamicCycles.Compressor import Compressor
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1("Dashboard Compresseur"),
html.Label("Pression évaporation [bar]:"),
dcc.Slider(id='p-evap', min=1, max=5, value=2.5, step=0.1),
html.Label("Pression condensation [bar]:"),
dcc.Slider(id='p-cond', min=5, max=15, value=8, step=0.1),
dcc.Graph(id='cop-graph')
])
@app.callback(
Output('cop-graph', 'figure'),
[Input('p-evap', 'value'),
Input('p-cond', 'value')]
)
def update_graph(p_evap, p_cond):
compressor = Compressor.Object()
# ... calculs ...
fig = go.Figure()
fig.add_trace(go.Indicator(
mode="gauge+number",
value=compressor.COP,
title={'text': "COP"},
gauge={'axis': {'range': [None, 6]}}
))
return fig
if __name__ == '__main__':
app.run_server(debug=True)
Intégration avec Streamlit
import streamlit as st
from AHU.HeatingCoil import HeatingCoil
from AHU.FreshAir import FreshAir
st.title("Dimensionnement Batterie de Chauffage")
# Inputs
T_ext = st.slider("Température extérieure [°C]", -20, 15, -5)
RH_ext = st.slider("Humidité relative", 0.0, 1.0, 0.8)
debit = st.number_input("Débit d'air [kg/s]", 0.1, 5.0, 1.0)
T_soufflage = st.slider("Température soufflage [°C]", 15, 25, 18)
# Calcul
air = FreshAir.Object()
air.T_C = T_ext
air.RH = RH_ext
air.F_dry = debit
air.calculate()
heating = HeatingCoil.Object()
heating.inlet_air = air
heating.outlet_T_C = T_soufflage
heating.calculate()
# Résultats
st.header("Résultats")
col1, col2, col3 = st.columns(3)
col1.metric("Puissance", f"{heating.Q_th:.2f} kW")
col2.metric("ΔT", f"{T_soufflage - T_ext}°C")
col3.metric("HR sortie", f"{heating.outlet_RH*100:.1f}%")
# Visualisation
st.line_chart({
'Température': [T_ext, T_soufflage],
'Humidité relative': [RH_ext*100, heating.outlet_RH*100]
})
Conseils d’utilisation
Performance
Les interfaces graphiques peuvent être gourmandes en ressources
Désactivez les animations pour améliorer les performances
Utilisez le mode « batch » pour les simulations longues
Personnalisation
Tous les graphiques matplotlib sont personnalisables
Les interfaces PyQt5 peuvent être modifiées via Qt Designer
Les thèmes peuvent être changés
Accessibilité
Support du clavier pour toutes les interfaces
Contraste élevé disponible
Taille de police ajustable
Support multi-plateforme
Windows : ✅ Support complet
macOS : ✅ Support complet (PyQt5 uniquement)
Linux : ✅ Support complet
Dépannage
Problèmes courants
« QApplication not found »
→ Installer PyQt5 : pip install PyQt5
« Tkinter not available »
→ Sur Linux : sudo apt-get install python3-tk
Graphiques ne s’affichent pas
→ Utiliser un backend matplotlib approprié : matplotlib.use('Qt5Agg')
Interface freeze
→ Les calculs lourds doivent être dans des threads séparés
Ressources
Tutoriels PyQt5 : https://doc.qt.io/qt-5/
Documentation Matplotlib : https://matplotlib.org/
Exemples Tkinter : https://docs.python.org/3/library/tkinter.html
Dash documentation : https://dash.plotly.com/
Streamlit docs : https://docs.streamlit.io/