@open3cl/engine
v1.8.8
Published
Open Source 3CL-DPE engine
Readme
Donnez-lui un DPE au format XML ou JSON, il vous rend les consommations, les émissions et les étiquettes.
🌍 À propos du projet
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 GPL-3.0, développée au grand jour |
Ce que fait le moteur
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"]| É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 |
Périmètre couvert
| 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.
L'écosystème Open3CL
| Ressource | Description | | :-------------------------------------------------------------------- | :-------------------------------------------------------- | | open3cl.fr | Le site du projet | | Rapports de corpus | Le tableau de bord interactif des résultats sur DPE réels | | @open3cl/engine | Le paquet npm |
🚀 Démarrage
Pré-requis
| 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).
Installation
npm install @open3cl/engineyarn add @open3cl/engine
pnpm add @open3cl/engineEn 30 secondes
import { 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.
🛠️ Utilisation
API publique
| 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 |
Options de calcul
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. |
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.
Lire le résultat
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 |
🧪 Tests de corpus
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.
Le rapport interactif
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.
[!NOTE] GitHub neutralise les scripts et les
iframedans les fichiers markdown : le rapport ne peut donc pas être intégré tel quel dans ce README. Il est affiché ici sous forme d'aperçu cliquable, et reste consultable en ligne ou en local :npm run reports:preview # sert dist/reports/corpus et ouvre le navigateur
Lancer un 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 : test/corpus/files/corpus_dpe.csv) |
| 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_PATHune fois pour toutes plutôt que de répéterdpes-folder-path. Les DPE absents du cache sont téléchargés depuis l'API de l'ADEME — pensez aux quotas.
Résultats corpus
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.7· branchemain· généré le 2026-10-02 Seuil de tolérance 5%
| | Corpus | Réussite | | DPE conformes |
| :-: | :---------------------------------------------------------------------------------------------------------------------- | ----------: | :--------------------- | -------------: |
| 🔴 | Généralistecorpus_dpe.csv | 46,23 % | █████████░░░░░░░░░░░ | 4 623 / 10 000 |
| 🟢 | Appartement · chauffage individuel (2025)dpe_appartement_individuel_chauffage_individuel_2025.csv | 91,76 % | ██████████████████░░ | 9 176 / 10 000 |
| 🟢 | Logement individuel (2025)dpe_logement_individuel_2025.csv | 88,40 % | ██████████████████░░ | 8 833 / 9 992 |
| 🟢 | Maison individuelle (2025)dpe_maison_individuelle_2025.csv | 88,38 % | ██████████████████░░ | 8 838 / 10 000 |
| 🟡 | Immeuble · chauffage individueldpe_immeuble_chauffage_individuel.csv | 74,11 % | ███████████████░░░░░ | 7 410 / 9 999 |
| 🟡 | Appartement · chauffage collectif (2025)dpe_appartement_individuel_chauffage_collectif_2025.csv | 69,74 % | ██████████████░░░░░░ | 6 974 / 10 000 |
| 🟡 | Immeuble · chauffage collectifdpe_immeuble_chauffage_collectif.csv | 62,44 % | ████████████░░░░░░░░ | 6 243 / 9 999 |
| 🔴 | Immeuble · chauffage mixtedpe_immeuble_chauffage_mixte.csv | 49,04 % | ██████████░░░░░░░░░░ | 4 904 / 10 000 |
| 🔴 | Individuel généré depuis l'immeuble (2026)dpe_individuel_a_partir_dpe_immeuble_2026.csv | 27,39 % | █████░░░░░░░░░░░░░░░ | 2 739 / 10 000 |
🟢 ≥ 85 % · 🟡 ≥ 60 % · 🔴 < 60 %
Temps d’exécution
Durée de l’appel à
calcul_3clpar DPE, sur 89 950 calculs. La copie défensive de l’entrée et la lecture du fichier sont exclues de la mesure.
| Corpus | Moyenne | Médiane | Min | Max | p95 | p99 | | :--------------------------------------------- | ------: | ------: | ------: | -------: | ------: | ------: | | Généraliste | 4,33 ms | 3,90 ms | 0,20 ms | 36,9 ms | 7,87 ms | 11,1 ms | | Appartement · chauffage individuel (2025) | 3,48 ms | 3,15 ms | 1,06 ms | 34,8 ms | 6,09 ms | 7,83 ms | | Logement individuel (2025) | 4,86 ms | 4,30 ms | 1,30 ms | 29,8 ms | 9,41 ms | 13,1 ms | | Maison individuelle (2025) | 5,48 ms | 4,96 ms | 1,65 ms | 35,8 ms | 9,87 ms | 12,8 ms | | Immeuble · chauffage individuel | 5,89 ms | 5,04 ms | 0,11 ms | 75,0 ms | 11,9 ms | 18,7 ms | | Appartement · chauffage collectif (2025) | 3,86 ms | 3,58 ms | 1,18 ms | 31,7 ms | 6,29 ms | 7,87 ms | | Immeuble · chauffage collectif | 5,21 ms | 4,43 ms | 0,11 ms | 110,0 ms | 9,58 ms | 16,9 ms | | Immeuble · chauffage mixte | 4,89 ms | 4,01 ms | 0,20 ms | 518,4 ms | 10,0 ms | 17,0 ms | | Individuel généré depuis l'immeuble (2026) | 5,22 ms | 4,47 ms | 1,61 ms | 40,6 ms | 9,86 ms | 15,4 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
🗺️ Roadmap
flowchart TD
subgraph fait ["✅ Fait"]
A1["Site Open3CL"]
A2["Rapports de corpus interactifs"]
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 | | Rapports de tests | ✅ Terminé | Tableau de bord interactif publié à 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.
🤝 Contribuer
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.
📄 Licence
Distribué sous licence GPL-3.0. Voir le fichier LICENSE pour plus d'informations.
📬 Contact
Pour toute question : [email protected]
🙏 Remerciements
Les contributeurs
Merci à toutes les personnes qui ont écrit, testé, relu ou corrigé une ligne de ce moteur.
Les organisations qui soutiennent le projet
Les ressources
- 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
