Implémentation open source du moteur Open3CL de l'ADEME.
Créer un bug · Créer une feature · 🏠 Démo 3D en ligne
Donnez-lui un DPE au format XML ou JSON, il vous rend les consommations, les émissions et les étiquettes.
Chargez le DPE d'un logement : Open3CL le recalcule dans le navigateur et en reconstruit la maquette 3D. Chaque paroi, fenêtre et équipement s'affiche avec ses déperditions — consultables et modifiables en direct.
open3cl_3D_demo_resized.webm
📚 Sommaire
Open3CL est une librairie JavaScript open source qui calcule un Diagnostic de Performance Énergétique (DPE). Elle implémente la méthode 3CL-DPE 2021 définie dans l'annexe 1 de l'arrêté du 31 mars 2021, la même méthode que celle utilisée par les logiciels certifiés du marché.
Concrètement : vous lui fournissez les données d'entrée d'un DPE (l'enveloppe du bâtiment, les systèmes de chauffage, d'ECS, de ventilation, de climatisation) et elle recalcule l'intégralité des sorties — déperditions, besoins, consommations, émissions de gaz à effet de serre, coûts et étiquettes.
| 🎯 Conforme | Implémente la méthode réglementaire 3CL-DPE 2021, article par article |
| 🔍 Vérifiable | ~90 000 DPE réels rejoués à chaque version, résultats publiés (voir Résultats corpus) |
| 🧩 Sans dépendance | Pure JavaScript (ESM), aucun service externe, fonctionne en Node.js comme dans un navigateur |
| 📦 Prête à intégrer | Entrée XML ADEME ou objet JSON, sortie JSON complète |
| 🆓 Libre | Licence MIT, développée au grand jour |
flowchart LR
A["📄 DPE<br/>XML ou JSON"] --> B["🧹 Sanitisation<br/>normalisation des entrées"]
B --> C["🧱 Enveloppe<br/>déperditions, inertie,<br/>ponts thermiques"]
C --> D["🌡️ Besoins<br/>chauffage, ECS,<br/>refroidissement"]
D --> E["⚙️ Systèmes<br/>générateurs, émetteurs,<br/>auxiliaires"]
E --> F["🔌 Consommations<br/>EF, EP, GES, coûts"]
F --> G["🏷️ Étiquettes<br/>DPE & climat"]
Le détail des étapes de calcul
| Étape | Ce qui est calculé |
|---|---|
| Sanitisation | Normalisation et correction des données d'entrée incohérentes (optionnelle) |
| Enveloppe | Déperditions des murs, planchers, baies, portes, ponts thermiques, renouvellement d'air, perméabilité |
| Inertie & confort | Classe d'inertie, confort d'été, qualité d'isolation |
| Besoins | Besoins de chauffage et d'ECS mensuels, apports solaires et internes, besoin de refroidissement |
| Systèmes | Rendements de génération / distribution / émission / stockage, pertes, intermittence |
| Auxiliaires | Consommations des auxiliaires de génération et de distribution (chauffage et ECS) |
| Consommations | Énergie finale, énergie primaire, émissions de GES, coûts par usage et par énergie |
| Étiquettes | Classe énergie et classe climat, y compris la projection avec le coefficient EP 1,7 |
| Type de DPE | Statut |
|---|---|
| Maison individuelle | ✅ Supporté |
| Appartement (chauffage individuel) | ✅ Supporté |
| Appartement (chauffage collectif ou mixte) | ✅ Supporté |
| Immeuble collectif | ✅ Supporté |
| Appartement généré à partir d'un DPE immeuble | 🚧 En cours de fiabilisation |
| Photovoltaïque | 🚧 En cours |
Note
Le moteur vise la reproduction fidèle des sorties des logiciels certifiés, y compris certains de leurs écarts à la méthode.
| Ressource | Description |
|---|---|
| Démo 3D | Visualisation 3D des déperditions d'un DPE, recalculées dans le navigateur |
| Rapports de corpus | Rapport HTML sur les corpus DPE |
| open3cl.fr | Le site du projet |
| @open3cl/engine | Le paquet npm |
| Outil | Version |
|---|---|
| Node.js | ≥ 24.14.1 |
| npm | ≥ 11.11.0 |
La version exacte utilisée en développement et en CI est fixée dans .nvmrc (nvm use).
npm install @open3cl/engineAvec un autre gestionnaire de paquets
yarn add @open3cl/engine
pnpm add @open3cl/engineimport { calcul_3cl_xml } from '@open3cl/engine';
import { readFileSync } from 'node:fs';
const dpe = calcul_3cl_xml(readFileSync('./mon-dpe.xml', 'utf8'));
const { ep_conso, emission_ges } = dpe.logement.sortie;
console.log(`Étiquette énergie : ${ep_conso.classe_bilan_dpe}`);
console.log(`Consommation : ${ep_conso.ep_conso_5_usages_m2} kWh/m²/an`);
console.log(`Étiquette climat : ${emission_ges.classe_emission_ges}`);
console.log(`Émissions : ${emission_ges.emission_ges_5_usages_m2} kgCO₂/m²/an`);Étiquette énergie : D
Consommation : 174 kWh/m²/an
Étiquette climat : C
Émissions : 30 kgCO₂/m²/an
Tip
Les fichiers XML de n'importe quel DPE publié sont téléchargeables depuis l'observatoire de l'ADEME. C'est le moyen le plus simple de tester le moteur sur un cas réel.
| Fonction | Entrée | Description |
|---|---|---|
calcul_3cl(dpe, options?) |
Objet JSON | Calcule un DPE et renvoie l'objet enrichi de ses sorties |
calcul_3cl_xml(xml, options?) |
Chaîne XML | Parse le XML puis appelle calcul_3cl |
get_classe_ges_dpe(dpe) |
DPE calculé | Recalcule les étiquettes énergie et climat |
get_conso_coeff_1_7_2027(dpe) |
DPE calculé | Projette la consommation avec le coefficient EP 1,7 (2027) |
getVersion() |
– | Version du moteur utilisée |
import { calcul_3cl, calcul_3cl_xml } from '@open3cl/engine';
// Depuis un objet JSON — sanitisation activée par défaut
const a = calcul_3cl(dpeData);
const b = calcul_3cl(dpeData, { sanitize: true }); // équivalent
// Sans pré-transformation : les données d'entrée sont utilisées telles quelles
const c = calcul_3cl(dpeData, { sanitize: false });
// Depuis un XML ADEME
const d = calcul_3cl_xml(xmlString);
const e = calcul_3cl_xml(xmlString, { sanitize: false });| Option | Défaut | Effet |
|---|---|---|
sanitize |
true |
Normalise et corrige les incohérences du DPE d'entrée avant calcul. Désactivez-le pour un calcul brut. |
Exemple d'objet JSON d'entrée (partiel)
const dpeData = {
numero_dpe: '2113E1018248X',
statut: 'ACTIF',
logement: {
caracteristique_generale: {
annee_construction: 1948,
surface_habitable_logement: 49.96
},
installation_chauffage_collection: {
installation_chauffage: [
{
description: 'Chaudière individuelle gaz standard',
surface_chauffee: 49.96,
generateur_chauffage_collection: {
generateur_chauffage: [{ description: '...' }]
}
}
]
}
}
};La structure attendue est celle du XML DPE de l'ADEME, converti en JSON. Les types complets sont décrits dans
types.d.ts.
Le DPE renvoyé est l'objet d'entrée, enrichi de logement.sortie :
| Chemin | Contenu |
|---|---|
sortie.deperdition |
Déperditions par paroi et déperdition d'enveloppe (GV) |
sortie.apport_et_besoin |
Besoins de chauffage et d'ECS, apports, nadeq |
sortie.ef_conso |
Consommations en énergie finale, par usage |
sortie.ep_conso |
Énergie primaire, classe_bilan_dpe, projection 2027 |
sortie.emission_ges |
Émissions de GES et classe_emission_ges |
sortie.cout |
Coûts annuels par usage |
sortie.confort_ete / qualite_isolation |
Indicateurs de confort d'été et de qualité d'isolation |
sortie.production_electricite |
Production photovoltaïque |
Un corpus, c'est une liste de numéros de DPE réels. Le moteur les rejoue tous, compare ses sorties à celles du DPE publié, et en tire un taux de conformité. C'est le principal indicateur de qualité du projet.
flowchart LR
A["📋 Liste de<br/>numéros DPE"] --> B["⬇️ Téléchargement<br/>API ADEME<br/><sub>ou cache local</sub>"]
B --> C["⚙️ Calcul<br/>Open3CL"]
C --> D["📐 Comparaison<br/><sub>écart ≤ 5 %</sub>"]
D --> E["📊 Rapports<br/>JSON · CSV · HTML"]
22 grandeurs sont comparées pour chaque DPE. Quatre d'entre elles sont bloquantes : un DPE n'est déclaré conforme que si toutes restent sous le seuil de tolérance de 5 %.
| Contrôle bloquant | Ce que c'est |
|---|---|
sortie.ef_conso.conso_ecs |
Consommation d'eau chaude sanitaire |
sortie.ef_conso.conso_ch |
Consommation de chauffage |
sortie.ep_conso.ep_conso_5_usages (ou _m2) |
Consommation en énergie primaire |
sortie.emission_ges.emission_ges_5_usages (ou _m2) |
Émissions de gaz à effet de serre |
📖 Guide complet : docs/CORPUS.md — liste des corpus, contrôles informatifs, variables d'environnement, quotas de l'API ADEME, structure des rapports.
Chaque exécution produit un tableau de bord HTML : jauge de réussite, ratio par contrôle, liste des DPE au-dessus du
seuil avec le détail des propriétés en écart, et comparaison entre deux branches. Il est écrit dans
dist/reports/corpus et se consulte en local :
npm run reports:preview # sert dist/reports/corpus et ouvre le navigateurLes chiffres de la dernière exécution sont repris ci-dessous, dans Résultats corpus.
# Tous les corpus, puis mise à jour automatique des résultats dans ce README
npm run test:corpus:all
# Un seul corpus
npm run test:corpus
# Un corpus précis
npm run test:corpus -- corpus-file-path=corpus.csv
# Un seul DPE, pour investiguer
npm run test:corpus -- dpes-code=2592E1233185X| Argument | Description |
|---|---|
corpus-file-path=<path> |
Fichier de corpus à analyser (défaut : tous les fichiers de test/corpus/files) |
dpes-folder-path=<path> |
Dossier de cache des DPE. Un DPE déjà présent n'est pas retéléchargé |
dpes-code=<code> |
Ne rejoue qu'un seul DPE |
Tip
Définissez DPE_FOLDER_PATH une fois pour toutes plutôt que de répéter dpes-folder-path. Les DPE absents du cache
sont téléchargés depuis l'API de l'ADEME — pensez aux quotas.
Ces résultats sont générés automatiquement à la fin de npm run test:corpus:all par
scripts/generate_corpus_readme.js. Ne les modifiez pas à la main.
Version
1.8.67· branchemain· généré le 2026-10-16 Seuil de tolérance 5%
| 9 corpus |
88 475 DPE analysés |
75 663 DPE conformes |
85,52 % réussite globale |
| Corpus | Réussite | DPE conformes | ||
|---|---|---|---|---|
| 🟢 | Appartement · chauffage individuel (2025)dpe_appartement_individuel_chauffage_individuel_2025.csv |
95,39 % | ███████████████████░ |
9 437 / 9 893 |
| 🟢 | Appartement · chauffage collectif (2025)dpe_appartement_individuel_chauffage_collectif_2025.csv |
94,54 % | ███████████████████░ |
9 384 / 9 926 |
| 🟢 | Logement individuel (2025)dpe_logement_individuel_2025.csv |
93,29 % | ███████████████████░ |
9 173 / 9 833 |
| 🟢 | Maison individuelle (2025)dpe_maison_individuelle_2025.csv |
92,03 % | ██████████████████░░ |
8 992 / 9 771 |
| 🟢 | Maison individuelle (2026)dpe_maison_individuelle_2026.csv |
90,41 % | ██████████████████░░ |
9 041 / 10 000 |
| 🟢 | Immeuble · chauffage collectifdpe_immeuble_chauffage_collectif.csv |
89,10 % | ██████████████████░░ |
8 677 / 9 739 |
| 🟢 | Immeuble · chauffage individueldpe_immeuble_chauffage_individuel.csv |
86,00 % | █████████████████░░░ |
8 535 / 9 924 |
| 🟡 | Immeuble · chauffage mixtedpe_immeuble_chauffage_mixte.csv |
70,48 % | ██████████████░░░░░░ |
6 746 / 9 571 |
| 🔴 | Individuel généré depuis l'immeuble (2026)dpe_individuel_a_partir_dpe_immeuble_2026.csv |
57,83 % | ████████████░░░░░░░░ |
5 678 / 9 818 |
🟢 ≥ 85 % · 🟡 ≥ 60 % · 🔴 < 60 %
Durée de l’appel à
calcul_3clpar DPE, sur 88 460 calculs. La copie défensive de l’entrée et la lecture du fichier sont exclues de la mesure.
| 10,2 ms moyenne |
8,72 ms médiane |
0,18 ms min |
618,1 ms max |
| Corpus | Moyenne | Médiane | Min | Max | p95 | p99 |
|---|---|---|---|---|---|---|
| Appartement · chauffage individuel (2025) | 6,87 ms | 6,25 ms | 1,73 ms | 79,3 ms | 12,0 ms | 17,0 ms |
| Appartement · chauffage collectif (2025) | 7,91 ms | 6,85 ms | 2,08 ms | 66,2 ms | 15,1 ms | 21,7 ms |
| Logement individuel (2025) | 9,05 ms | 8,08 ms | 2,03 ms | 104,0 ms | 16,9 ms | 24,1 ms |
| Maison individuelle (2025) | 11,2 ms | 9,96 ms | 2,50 ms | 109,6 ms | 20,2 ms | 30,4 ms |
| Maison individuelle (2026) | 11,8 ms | 10,3 ms | 2,74 ms | 120,6 ms | 22,7 ms | 34,3 ms |
| Immeuble · chauffage collectif | 12,0 ms | 9,62 ms | 0,21 ms | 197,5 ms | 25,2 ms | 42,9 ms |
| Immeuble · chauffage individuel | 12,2 ms | 10,3 ms | 0,18 ms | 228,3 ms | 24,6 ms | 39,3 ms |
| Immeuble · chauffage mixte | 9,68 ms | 7,89 ms | 0,35 ms | 618,1 ms | 20,2 ms | 33,5 ms |
| Individuel généré depuis l'immeuble (2026) | 10,8 ms | 9,27 ms | 2,42 ms | 114,5 ms | 20,3 ms | 34,2 ms |
La moyenne est tirée vers le haut par les DPE collectifs, dont le coût atteint plusieurs dizaines de fois la médiane : c’est la médiane qui décrit le cas courant, et p95/p99 le cas défavorable réel.
📈 Historique complet des versions : docs/CORPUS-HISTORY.md
flowchart TD
subgraph fait ["✅ Fait"]
A1["Site Open3CL"]
A2["Rapports de corpus interactifs"]
A3["Démo 3D en ligne"]
end
subgraph cours ["🚧 En cours"]
B1["Refonte technique"]
B2["DPE à l'immeuble"]
B3["Certification ADEME"]
end
fait --> cours
| Étape | Statut | Détail |
|---|---|---|
| Site Open3CL | ✅ Terminé | open3cl.fr |
| Démo 3D en ligne | ✅ Terminé | Visualisation 3D des déperditions, publiée sur GitHub Pages |
| Rapports de tests | ✅ Terminé | Tableau de bord interactif généré à chaque exécution |
| Refonte technique | 🚧 En cours | Découpage par article de la méthode, couverture de tests à 100 % |
| DPE à l'immeuble | 🚧 En cours | Fiabilisation des appartements générés depuis un DPE immeuble |
| Certification ADEME | 🚧 En cours | Objectif de long terme |
Le détail complet des bugs et fonctionnalités en cours est dans les issues.
Toutes les contributions sont les bienvenues : correction d'un écart de calcul, ajout de tests, documentation, ou simplement le signalement d'un DPE qui ne passe pas.
git clone https://github.com/Open3CL/engine.git
cd engine
npm ci
npm run test:unit # tests unitaires
npm run qa:lint # analyse statique
npm run qa:format # formatage| Vous voulez… | Allez voir |
|---|---|
| Signaler un bug | Ouvrir un bug |
| Proposer une fonctionnalité | Ouvrir une feature |
| Soumettre du code | CONTRIBUTING.md |
| Comprendre les tests de corpus | docs/CORPUS.md |
📖 Le guide de contribution détaillé — conventions de commit, règles de code, cycle d'une pull request, méthode de debug d'un écart de calcul — est dans CONTRIBUTING.fr.md.
Distribué sous licence MIT. Voir le fichier LICENSE pour plus d'informations.
Pour toute question : open3cl@redfroggy.fr
Merci à toutes les personnes qui ont écrit, testé, relu ou corrigé une ligne de ce moteur.
|
RedFroggy
À l'initiative du projet et de sa maintenance. Studio de développement web et mobile. |
Kardino
Accompagnement à la rénovation énergétique des logements. |
Check DPE
Vérification et analyse de DPE en ligne. |
- L'ADEME pour la publication de la méthode 3CL-DPE 2021 et l'ouverture des données DPE
- L'observatoire DPE-Audit qui rend possible les tests de corpus