@open3cl/engine 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/10_besoin_fr.js +76 -0
- package/10_clim.js +45 -0
- package/11_besoin_ecs.js +25 -0
- package/11_ecs.js +95 -0
- package/11_nadeq.js +87 -0
- package/11_nadeq.spec.js +55 -0
- package/12.4_pac.js +54 -0
- package/13.2_generateur_combustion.js +295 -0
- package/13.2_generateur_combustion_bouilleur.js +173 -0
- package/13.2_generateur_combustion_ch.js +195 -0
- package/13.2_generateur_combustion_chaudiere.js +151 -0
- package/13.2_generateur_pac.js +36 -0
- package/13_rendement_distribution_ecs.js +12 -0
- package/14_generateur_ecs.js +388 -0
- package/15_conso_aux.js +257 -0
- package/16.2_production_enr.js +328 -0
- package/16.2_production_enr.spec.js +251 -0
- package/16_conso_eclairage.js +37 -0
- package/2021_04_13_confort_ete.js +61 -0
- package/2021_04_13_qualite_isolation.js +174 -0
- package/3.1_b.js +141 -0
- package/3.2.1_mur.js +331 -0
- package/3.2.1_mur.spec.js +46 -0
- package/3.2.2_plancher_bas.js +259 -0
- package/3.2.2_plancher_bas.spec.js +88 -0
- package/3.2.3_plancher_haut.js +158 -0
- package/3.3.1.4_porte.js +32 -0
- package/3.3_baie_vitree.js +308 -0
- package/3.3_baie_vitree.spec.js +333 -0
- package/3.4_pont_thermique.js +463 -0
- package/3_deperdition.js +258 -0
- package/4_ventilation.js +197 -0
- package/5_conso_ventilation.js +127 -0
- package/6.1_apport_gratuit.js +61 -0
- package/6.1_apport_gratuit.spec.js +181 -0
- package/6.2_surface_sud_equivalente.js +109 -0
- package/7_inertie.js +178 -0
- package/7_inertie.spec.js +263 -0
- package/8_intermittence.js +5 -0
- package/9_besoin_ch.js +198 -0
- package/9_chauffage.js +291 -0
- package/9_chauffage.spec.js +101 -0
- package/9_conso_ch.js +95 -0
- package/9_conso_ch.spec.js +255 -0
- package/9_emetteur_ch.js +122 -0
- package/9_generateur_ch.js +230 -0
- package/9_generateur_ch.spec.js +87 -0
- package/README.md +43 -0
- package/apport_et_besoin.js +55 -0
- package/conso.js +529 -0
- package/conso.spec.js +90 -0
- package/core/assets/domain/add-additionnal-ue-values-tables.js +57 -0
- package/core/assets/domain/synchronize-assets.js +29 -0
- package/core/assets/domain/synchronize-assets.spec.js +37 -0
- package/core/assets/domain/synchronize-c1-tables.js +61 -0
- package/core/assets/domain/synchronize-c1-tables.spec.js +35 -0
- package/core/assets/domain/synchronize-dpe-ges-limit-values-tables.js +73 -0
- package/core/assets/domain/synchronize-dpe-ges-limit-values-tables.spec.js +72 -0
- package/core/assets/domain/synchronize-enum-tables.js +77 -0
- package/core/assets/domain/synchronize-enum-tables.spec.js +31 -0
- package/core/assets/domain/synchronize-solicitations-tables.js +72 -0
- package/core/assets/domain/synchronize-solicitations-tables.spec.js +47 -0
- package/core/assets/domain/synchronize-valeur-tables.js +146 -0
- package/core/assets/domain/synchronize-valeur-tables.spec.js +54 -0
- package/core/conf/infrastructure/application.config.js +33 -0
- package/core/file/infrastructure/adapter/file.store.js +75 -0
- package/core/file/infrastructure/adapter/file.store.spec.js +30 -0
- package/core/tv/infrastructure/assets/additional-ue-values.js +69 -0
- package/core/tv/infrastructure/tvs.store.js +40 -0
- package/core/tv/infrastructure/tvs.store.spec.js +34 -0
- package/core/util/infrastructure/object-util.js +23 -0
- package/core/util/infrastructure/object-util.spec.js +25 -0
- package/engine.js +503 -0
- package/enums.js +1155 -0
- package/ficheTechnique.js +86 -0
- package/ficheTechnique.spec.js +181 -0
- package/index.js +4 -0
- package/package.json +87 -0
- package/tv/18.2_sollicitations_ext.ods +0 -0
- package/tv/18.5_c1.ods +0 -0
- package/tv/dpe_ges_limit_values.ods +0 -0
- package/tv.js +80811 -0
- package/tvs.d.ts +7 -0
- package/utils.js +500 -0
- package/utils.spec.js +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Open3CL
|
|
2
|
+
|
|
3
|
+
Le méthode 3CL, décrite dans [ce PDF](https://rt-re-batiment.developpement-durable.gouv.fr/IMG/pdf/consolide_annexe_1_arrete_du_31_03_2021_relatif_aux_methodes_et_procedures_applicables.pdf), est la base de calcul pour les DPE.
|
|
4
|
+
|
|
5
|
+
Open3CL est un projet d'exploration pour mieux comprendre le DPE et la méthode de calcul 3CL, il est encore en développement, veuillez suivre [la progression ici](./test/).
|
|
6
|
+
|
|
7
|
+
## Modèle de données
|
|
8
|
+
|
|
9
|
+
Les DPE dans la base de l'ademe sont au format XML. Open3CL fonctionne en json, car c'est un format plus simple pour travailler au quotidien. Le fichier [xml_to_json.js](./test/xml_to_json.js) permet de transformer un DPE xml en format json utilisable par Open3CL.
|
|
10
|
+
|
|
11
|
+
## Ressources
|
|
12
|
+
|
|
13
|
+
- [PDF Méthode 3CL v1.3](https://rt-re-batiment.developpement-durable.gouv.fr/IMG/pdf/consolide_annexe_1_arrete_du_31_03_2021_relatif_aux_methodes_et_procedures_applicables.pdf)
|
|
14
|
+
- [Gitlab Observatoire DPE](https://gitlab.com/observatoire-dpe/observatoire-dpe/-/blob/master/README.md)
|
|
15
|
+
- [Légifrance 13/04/2021 ajout d'indicateur de confort thermique dans la sortie du DPE](https://www.legifrance.gouv.fr/download/pdf?id=doxMrRr0wbfJVvtWjfDP4qE7zNsiFZL-4wqNyqoY-CA=)
|
|
16
|
+
- [Légifrance 13/04/2021 valeurs GES](https://www.legifrance.gouv.fr/download/pdf?id=doxMrRr0wbfJVvtWjfDP4gHzzERt1iX0PtobthCE6A0=)
|
|
17
|
+
- [CSTB Procédure de certification](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwjH-fG2-s7_AhXLaqQEHTP8CwMQFnoECA4QAQ&url=https%3A%2F%2Frt-re-batiment.developpement-durable.gouv.fr%2FIMG%2Fpdf%2Freglement_evaluation_logiciel_dpe_2021_-_audit_energetique-13122022_v2.pdf&usg=AOvVaw3SWv8drhqbgMMT8K9m6a2C&opi=89978449)
|
|
18
|
+
- [Valeurs des étiquettes énergétiques](https://docs.google.com/spreadsheets/d/1QVXUOLP8aJukA-PLBGyVB0ZJTWmLEE1WbflXUfsT_jU/edit#gid=0)
|
|
19
|
+
|
|
20
|
+
## Quelques DPE intéressants
|
|
21
|
+
|
|
22
|
+
En travaillant sur les DPE je suis tombé sur quelques cas de DPE intéressants
|
|
23
|
+
|
|
24
|
+
- `2307E3075089A` chaudiere a condensation + climatiseur
|
|
25
|
+
- `2344E2258429L` DPE generé a partir des données immeuble
|
|
26
|
+
- `2362E3036179P` poele a charbon
|
|
27
|
+
- `2369E2991011Q` 1 radiateur à gaz + fenetres avec masques lointains
|
|
28
|
+
- `2387E0402213E` methode_application 'maison_individuelle' mais les portes sont saisie depuis une étude rt2012/rt2020
|
|
29
|
+
- `2387E0576340J` 2 gen ch
|
|
30
|
+
- `2387E0888781I` inertie lourde + paroi anciennes (tableaux de valeurs différents)
|
|
31
|
+
- `2387E1742056P` 2 emetteur ch
|
|
32
|
+
- `2387E2058698D` ventil hybride
|
|
33
|
+
- `2387E2603968B` inertie lourde + parois ancienne (différentes periode de chauffe)
|
|
34
|
+
- `2387E2899635W` 2 installation_ch
|
|
35
|
+
- `2387E2923777K` pas d’ECS, pas de portes
|
|
36
|
+
- `2387E3074987E` bouclage ECS
|
|
37
|
+
- `2387E3092820B` pas de pancher_haut
|
|
38
|
+
- `2387E3103131Q` Analysimmo 4.1.1 incohérence ventil calculée comme si presence_joint_menuiserie=1 alors qu’aucune menuiserie n’a de joints
|
|
39
|
+
- `2387E3103505A` Analysimmo 4.1.1 incohérence pont thermique, PB considéré pont ITI+ITE ??
|
|
40
|
+
- `2187E1039187C` toiture terrasse
|
|
41
|
+
- `2387E0291550X` probleme ubat/uph comble amenagés
|
|
42
|
+
- `2287E1724516Y` pour un meme generateur, position_volume_chauffe = 0 ou 1 selon si c'est le gen_ecs ou le gen_ch
|
|
43
|
+
- `2387E3092820B`, `2287E1043883T` et plein d'autres dpe. Le diagnostiqueur override la valeur forfaitaire de pveil pour le mettre a 0 car il n'y a pas de veilleuse sur la chaudiere, or pour le moteur il n'y a aucun moyen de savoir si donnee_intermediaire.pveil a ete saisi ou s'il faut aller chercher une valeur dans le tableau.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import enums from './enums.js';
|
|
2
|
+
import { calc_sse } from './6.2_surface_sud_equivalente.js';
|
|
3
|
+
import calc_besoin_fr from './10_besoin_fr.js';
|
|
4
|
+
import calc_besoin_ecs from './11_besoin_ecs.js';
|
|
5
|
+
import { Nadeq } from './11_nadeq.js';
|
|
6
|
+
import { calc_ai, calc_as } from './6.1_apport_gratuit.js';
|
|
7
|
+
|
|
8
|
+
const nadeqService = new Nadeq();
|
|
9
|
+
|
|
10
|
+
export default function calc_apport_et_besoin(
|
|
11
|
+
logement,
|
|
12
|
+
th,
|
|
13
|
+
ecs,
|
|
14
|
+
clim,
|
|
15
|
+
Sh,
|
|
16
|
+
Nb_lgt,
|
|
17
|
+
GV,
|
|
18
|
+
ilpa,
|
|
19
|
+
ca_id,
|
|
20
|
+
zc_id
|
|
21
|
+
) {
|
|
22
|
+
const zc = enums.zone_climatique[zc_id];
|
|
23
|
+
const ca = enums.classe_altitude[ca_id];
|
|
24
|
+
|
|
25
|
+
const enveloppe = logement.enveloppe;
|
|
26
|
+
const inertie = enums.classe_inertie[enveloppe.inertie.enum_classe_inertie_id];
|
|
27
|
+
|
|
28
|
+
const bv = enveloppe.baie_vitree_collection.baie_vitree;
|
|
29
|
+
const ets = enveloppe.ets_collection.ets;
|
|
30
|
+
|
|
31
|
+
const nadeq = nadeqService.calculateNadeq(logement);
|
|
32
|
+
|
|
33
|
+
const besoin_ecs = calc_besoin_ecs(ca, zc, nadeq);
|
|
34
|
+
const besoin_fr = calc_besoin_fr(ca, zc, Sh, nadeq, GV, inertie, bv, ets);
|
|
35
|
+
const apport_interne = calc_ai(ilpa, ca, zc, Sh, nadeq);
|
|
36
|
+
const apport_solaire = calc_as(ilpa, ca, zc, bv, ets);
|
|
37
|
+
|
|
38
|
+
if (clim.length === 0) {
|
|
39
|
+
besoin_fr.besoin_fr = 0;
|
|
40
|
+
besoin_fr.besoin_fr_depensier = 0;
|
|
41
|
+
apport_interne.apport_interne_fr = 0;
|
|
42
|
+
apport_solaire.apport_solaire_fr = 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
nadeq,
|
|
47
|
+
v40_ecs_journalier: nadeq * 56,
|
|
48
|
+
v40_ecs_journalier_depensier: nadeq * 79,
|
|
49
|
+
surface_sud_equivalente: calc_sse(ca, zc, bv, ets),
|
|
50
|
+
...besoin_ecs,
|
|
51
|
+
...apport_interne,
|
|
52
|
+
...apport_solaire,
|
|
53
|
+
...besoin_fr
|
|
54
|
+
};
|
|
55
|
+
}
|
package/conso.js
ADDED
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
import enums from './enums.js';
|
|
2
|
+
import calc_conso_eclairage from './16_conso_eclairage.js';
|
|
3
|
+
import tvs from './tv.js';
|
|
4
|
+
import { tv } from './utils.js';
|
|
5
|
+
|
|
6
|
+
const coef_ep = {
|
|
7
|
+
'électricité ch': 2.3,
|
|
8
|
+
'électricité ecs': 2.3,
|
|
9
|
+
'électricité fr': 2.3,
|
|
10
|
+
'électricité éclairage': 2.3,
|
|
11
|
+
'électricité auxiliaire': 2.3
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// 31 mars 2021
|
|
15
|
+
// https://www.legifrance.gouv.fr/download/pdf?id=doxMrRr0wbfJVvtWjfDP4gHzzERt1iX0PtobthCE6A0=
|
|
16
|
+
const coef_ges = {
|
|
17
|
+
'bois – bûches': 0.03,
|
|
18
|
+
'bois – granulés (pellets) ou briquettes': 0.03,
|
|
19
|
+
'bois – plaquettes forestières': 0.024,
|
|
20
|
+
'bois – plaquettes d’industrie': 0.024,
|
|
21
|
+
'gaz naturel': 0.227,
|
|
22
|
+
'fioul domestique': 0.324,
|
|
23
|
+
charbon: 0.385,
|
|
24
|
+
propane: 0.272,
|
|
25
|
+
butane: 0.272,
|
|
26
|
+
gpl: 0.272,
|
|
27
|
+
"électricité d'origine renouvelable utilisée dans le bâtiment": 0,
|
|
28
|
+
'électricité ch': 0.079,
|
|
29
|
+
'électricité ecs': 0.065,
|
|
30
|
+
'électricité fr': 0.064,
|
|
31
|
+
'électricité éclairage': 0.069,
|
|
32
|
+
'électricité auxiliaire': 0.064
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// annexe 7
|
|
36
|
+
// https://www.legifrance.gouv.fr/download/file/doxMrRr0wbfJVvtWjfDP4qE7zNsiFZL-4wqNyqoY-CA=/JOE_TEXTE
|
|
37
|
+
const coef_cout = {
|
|
38
|
+
'fioul domestique': 0.09142,
|
|
39
|
+
'réseau de chauffage urbain': 0.0787,
|
|
40
|
+
propane: 0.14305,
|
|
41
|
+
butane: 0.20027,
|
|
42
|
+
charbon: 0.02372,
|
|
43
|
+
'bois – granulés (pellets) ou briquettes': 0.05991,
|
|
44
|
+
'bois – bûches': 0.03201,
|
|
45
|
+
'bois – plaquettes forestières': 0.03201,
|
|
46
|
+
'bois – plaquettes d’industrie': 0.03201,
|
|
47
|
+
// https://www.legifrance.gouv.fr/download/pdf?id=7hpbVyq228foxHzNM7WleDImAyXlPNb9zULelSY01V8=
|
|
48
|
+
'gaz naturel': cout_gaz_naturel,
|
|
49
|
+
"électricité d'origine renouvelable utilisée dans le bâtiment": cout_electricite,
|
|
50
|
+
'électricité ch': cout_electricite,
|
|
51
|
+
'électricité ecs': cout_electricite,
|
|
52
|
+
'électricité fr': cout_electricite,
|
|
53
|
+
'électricité éclairage': cout_electricite,
|
|
54
|
+
'électricité auxiliaire': cout_electricite
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Fonction utilitaire pour générer la clef à utiliser pour la table `coef_ges`.
|
|
59
|
+
* Le type_energie 'électricté' nécessite un suffixe : en fonction la destination d'usage,
|
|
60
|
+
* le coefficient est différent.
|
|
61
|
+
*
|
|
62
|
+
* @param type_energie {string} label de l'enum type_energie
|
|
63
|
+
* @param destination {'ch' | 'ecs' | 'éclairage'}
|
|
64
|
+
* @return {string} la clef à utiliser pour récupérer le coefficient depuis la table `coef_ges`
|
|
65
|
+
*/
|
|
66
|
+
function getCoefKey(type_energie, destination) {
|
|
67
|
+
if (type_energie === 'électricité') {
|
|
68
|
+
if (!['ch', 'ecs', 'éclairage'].includes(destination)) {
|
|
69
|
+
console.error(`Type d'électricité inconnu: ${destination}`);
|
|
70
|
+
}
|
|
71
|
+
return `électricité ${destination}`;
|
|
72
|
+
}
|
|
73
|
+
return type_energie;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function cout_gaz_naturel(cef) {
|
|
77
|
+
if (cef < 5009) return 0.11121 * cef;
|
|
78
|
+
else if (cef < 50055) return 230 + 0.06533 * cef;
|
|
79
|
+
else return 415 + 0.06164 * cef;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function cout_electricite(cef) {
|
|
83
|
+
if (cef < 1000) return 0.29007 * cef;
|
|
84
|
+
else if (cef < 2500) return 149 + 0.14066 * cef;
|
|
85
|
+
else if (cef < 5000) return 122 + 0.15176 * cef;
|
|
86
|
+
else if (cef < 15000) return 94 + 0.15735 * cef;
|
|
87
|
+
else return 56 + 0.15989 * cef;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function getConso(coef, type_energie, conso) {
|
|
91
|
+
// is coef is a function, execute it
|
|
92
|
+
if (!coef) return conso;
|
|
93
|
+
const coef_val = coef[type_energie];
|
|
94
|
+
if (typeof coef_val === 'function') {
|
|
95
|
+
const val = coef_val(conso);
|
|
96
|
+
return val;
|
|
97
|
+
}
|
|
98
|
+
if (coef_val) return coef_val * conso;
|
|
99
|
+
return conso;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Récupération du coefficient d'émission GES pour le générateur
|
|
104
|
+
* @param gen_ch {GenerateurChauffageItem||GenerateurEcsItem}
|
|
105
|
+
* @param suffix {'ch'|'ecs'}
|
|
106
|
+
* @returns {number}
|
|
107
|
+
*/
|
|
108
|
+
function getGesCoeffForGenerateur(gen_ch, suffix) {
|
|
109
|
+
const typeEnergie = getTypeEnergie(gen_ch.donnee_entree, suffix);
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Cas spécifique des réseaux de chaleur urbain qui ont des coefficients différents en fonction de réseau de distribution
|
|
113
|
+
*/
|
|
114
|
+
if (typeEnergie === 'réseau de chauffage urbain') {
|
|
115
|
+
const identifiant_reseau = gen_ch.donnee_entree.identifiant_reseau_chaleur;
|
|
116
|
+
|
|
117
|
+
if (identifiant_reseau) {
|
|
118
|
+
const row = tv('reseau_chaleur_2022', { identifiant_reseau });
|
|
119
|
+
|
|
120
|
+
if (row) {
|
|
121
|
+
return row.contenu_co2_acv;
|
|
122
|
+
} else {
|
|
123
|
+
console.error(`
|
|
124
|
+
Aucun coefficient GES trouvé pour le réseau de chaleur ${identifiant_reseau}
|
|
125
|
+
`);
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
// Prendre la valeur pour "AUTRES RESEAUX DE CHALEUR"
|
|
129
|
+
return 0.385;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return coef_ges[typeEnergie] ?? 1;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export default function calc_conso(
|
|
137
|
+
Sh,
|
|
138
|
+
zc_id,
|
|
139
|
+
ca_id,
|
|
140
|
+
vt,
|
|
141
|
+
ch,
|
|
142
|
+
ecs,
|
|
143
|
+
fr,
|
|
144
|
+
prorataECS,
|
|
145
|
+
prorataChauffage
|
|
146
|
+
) {
|
|
147
|
+
const gen_ch = ch.reduce((acc, ch) => {
|
|
148
|
+
const generateur_chauffage = ch.generateur_chauffage_collection.generateur_chauffage;
|
|
149
|
+
generateur_chauffage.forEach((value) => {
|
|
150
|
+
// S'il existe une clé de repartition de chauffage, utilisation de celle-ci pour répartir la conso chauffage collectif à l'appartement
|
|
151
|
+
if (ch.donnee_entree.cle_repartition_ch === 1) {
|
|
152
|
+
value.donnee_entree.cle_repartition_ch = prorataChauffage;
|
|
153
|
+
} else {
|
|
154
|
+
value.donnee_entree.cle_repartition_ch =
|
|
155
|
+
ch.donnee_entree.cle_repartition_ch || prorataChauffage;
|
|
156
|
+
}
|
|
157
|
+
value.donnee_entree.enum_methode_calcul_conso_id =
|
|
158
|
+
ch.donnee_entree.enum_methode_calcul_conso_id;
|
|
159
|
+
value.donnee_entree.enum_type_installation_id = ch.donnee_entree.enum_type_installation_id;
|
|
160
|
+
(value.donnee_utilisateur = value.donnee_utilisateur || {}).coeffEmissionGes =
|
|
161
|
+
getGesCoeffForGenerateur(value, 'ch');
|
|
162
|
+
});
|
|
163
|
+
return acc.concat(generateur_chauffage);
|
|
164
|
+
}, []);
|
|
165
|
+
|
|
166
|
+
const gen_ecs = ecs.reduce((acc, ecs) => {
|
|
167
|
+
const generateur_ecs = ecs.generateur_ecs_collection.generateur_ecs;
|
|
168
|
+
if (prorataECS === 1) {
|
|
169
|
+
// S'il existe une clé de repartition ECS, utilisation de celle-ci pour répartir la conso ECS collective à l'appartement
|
|
170
|
+
generateur_ecs.forEach((value) => {
|
|
171
|
+
value.donnee_entree.cle_repartition_ecs =
|
|
172
|
+
(ecs.donnee_entree.cle_repartition_ecs || 1) * (ecs.donnee_entree.rdim || 1);
|
|
173
|
+
(value.donnee_utilisateur = value.donnee_utilisateur || {}).coeffEmissionGes =
|
|
174
|
+
getGesCoeffForGenerateur(value, 'ecs');
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return acc.concat(generateur_ecs);
|
|
178
|
+
}, []);
|
|
179
|
+
|
|
180
|
+
const ret = {
|
|
181
|
+
ef_conso: calc_conso_pond(
|
|
182
|
+
Sh,
|
|
183
|
+
zc_id,
|
|
184
|
+
vt,
|
|
185
|
+
gen_ch,
|
|
186
|
+
gen_ecs,
|
|
187
|
+
fr,
|
|
188
|
+
'conso',
|
|
189
|
+
null,
|
|
190
|
+
prorataECS,
|
|
191
|
+
prorataChauffage
|
|
192
|
+
),
|
|
193
|
+
ep_conso: calc_conso_pond(
|
|
194
|
+
Sh,
|
|
195
|
+
zc_id,
|
|
196
|
+
vt,
|
|
197
|
+
gen_ch,
|
|
198
|
+
gen_ecs,
|
|
199
|
+
fr,
|
|
200
|
+
'ep_conso',
|
|
201
|
+
coef_ep,
|
|
202
|
+
prorataECS,
|
|
203
|
+
prorataChauffage
|
|
204
|
+
),
|
|
205
|
+
emission_ges: calc_conso_pond(
|
|
206
|
+
Sh,
|
|
207
|
+
zc_id,
|
|
208
|
+
vt,
|
|
209
|
+
gen_ch,
|
|
210
|
+
gen_ecs,
|
|
211
|
+
fr,
|
|
212
|
+
'emission_ges',
|
|
213
|
+
coef_ges,
|
|
214
|
+
prorataECS,
|
|
215
|
+
prorataChauffage
|
|
216
|
+
),
|
|
217
|
+
cout: calc_conso_pond(
|
|
218
|
+
Sh,
|
|
219
|
+
zc_id,
|
|
220
|
+
vt,
|
|
221
|
+
gen_ch,
|
|
222
|
+
gen_ecs,
|
|
223
|
+
fr,
|
|
224
|
+
'cout',
|
|
225
|
+
coef_cout,
|
|
226
|
+
prorataECS,
|
|
227
|
+
prorataChauffage
|
|
228
|
+
)
|
|
229
|
+
};
|
|
230
|
+
ret.ep_conso.classe_bilan_dpe = classe_bilan_dpe(
|
|
231
|
+
ret.ep_conso.ep_conso_5_usages_m2,
|
|
232
|
+
zc_id,
|
|
233
|
+
ca_id,
|
|
234
|
+
Sh
|
|
235
|
+
);
|
|
236
|
+
ret.emission_ges.classe_emission_ges = classe_emission_ges(
|
|
237
|
+
ret.emission_ges.emission_ges_5_usages_m2,
|
|
238
|
+
zc_id,
|
|
239
|
+
ca_id,
|
|
240
|
+
Sh
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
const energie_ids = [];
|
|
244
|
+
// find all type_energies in gen_ch and gen_ecs
|
|
245
|
+
gen_ch.forEach((gen_ch) => {
|
|
246
|
+
const id = gen_ch.donnee_entree.enum_type_energie_id;
|
|
247
|
+
if (!energie_ids.includes(id)) energie_ids.push(id);
|
|
248
|
+
});
|
|
249
|
+
gen_ecs.forEach((gen_ecs) => {
|
|
250
|
+
const id = gen_ecs.donnee_entree.enum_type_energie_id;
|
|
251
|
+
if (!energie_ids.includes(id)) energie_ids.push(id);
|
|
252
|
+
});
|
|
253
|
+
if (!energie_ids.includes('1')) energie_ids.push('1');
|
|
254
|
+
// calculate calc_conso_pond for each energy type
|
|
255
|
+
ret.sortie_par_energie_collection = {};
|
|
256
|
+
ret.sortie_par_energie_collection.sortie_par_energie = energie_ids.reduce((acc, energie_id) => {
|
|
257
|
+
const type_energie = enums.type_energie[energie_id];
|
|
258
|
+
let vt_en, fr_en;
|
|
259
|
+
if (type_energie === 'électricité') {
|
|
260
|
+
vt_en = vt;
|
|
261
|
+
fr_en = fr;
|
|
262
|
+
} else {
|
|
263
|
+
vt_en = [];
|
|
264
|
+
fr_en = [];
|
|
265
|
+
}
|
|
266
|
+
const gen_ch_en = gen_ch.filter(
|
|
267
|
+
(gen_ch) => gen_ch.donnee_entree.enum_type_energie_id === energie_id
|
|
268
|
+
);
|
|
269
|
+
const gen_ecs_en = gen_ecs.filter(
|
|
270
|
+
(gen_ecs) => gen_ecs.donnee_entree.enum_type_energie_id === energie_id
|
|
271
|
+
);
|
|
272
|
+
let conso_en = calc_conso_pond(
|
|
273
|
+
Sh,
|
|
274
|
+
zc_id,
|
|
275
|
+
vt_en,
|
|
276
|
+
gen_ch_en,
|
|
277
|
+
gen_ecs_en,
|
|
278
|
+
fr_en,
|
|
279
|
+
'',
|
|
280
|
+
null,
|
|
281
|
+
prorataECS,
|
|
282
|
+
prorataChauffage
|
|
283
|
+
);
|
|
284
|
+
conso_en = {
|
|
285
|
+
conso_ch: conso_en._ch,
|
|
286
|
+
conso_ecs: conso_en._ecs,
|
|
287
|
+
conso_5_usages: conso_en._5_usages,
|
|
288
|
+
emission_ges_ch: conso_en._ch * coef_ges[getCoefKey(type_energie, 'ch')],
|
|
289
|
+
emission_ges_ecs: conso_en._ecs * coef_ges[getCoefKey(type_energie, 'ecs')],
|
|
290
|
+
emission_ges_5_usages: conso_en._5_usages * coef_ges[type_energie] // TODO elec
|
|
291
|
+
};
|
|
292
|
+
conso_en.enum_type_energie_id = energie_id;
|
|
293
|
+
return acc.concat(conso_en);
|
|
294
|
+
}, []);
|
|
295
|
+
return ret;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function classe_bilan_dpe(ep_conso_5_usages_m2, zc_id, ca_id, Sh) {
|
|
299
|
+
const ca = enums.classe_altitude[ca_id];
|
|
300
|
+
|
|
301
|
+
const cut = tvs.dpe_class_limit[ca][Math.round(Sh)] ?? [];
|
|
302
|
+
|
|
303
|
+
if (!ep_conso_5_usages_m2) return null;
|
|
304
|
+
if (ep_conso_5_usages_m2 < (cut['A'] ?? 70)) return 'A';
|
|
305
|
+
if (ep_conso_5_usages_m2 < (cut['B'] ?? 110)) return 'B';
|
|
306
|
+
if (ep_conso_5_usages_m2 < (cut['C'] ?? 180)) return 'C';
|
|
307
|
+
if (ep_conso_5_usages_m2 < (cut['D'] ?? 250)) return 'D';
|
|
308
|
+
|
|
309
|
+
const zc = enums.zone_climatique[zc_id];
|
|
310
|
+
|
|
311
|
+
if (['h1b', 'h1c', 'h2d'].includes(zc) && ca === 'supérieur à 800m') {
|
|
312
|
+
if (ep_conso_5_usages_m2 < (cut['E'] ?? 390)) return 'E';
|
|
313
|
+
if (ep_conso_5_usages_m2 < (cut['F'] ?? 500)) return 'F';
|
|
314
|
+
} else {
|
|
315
|
+
if (ep_conso_5_usages_m2 < (cut['E'] ?? 330)) return 'E';
|
|
316
|
+
if (ep_conso_5_usages_m2 < (cut['F'] ?? 420)) return 'F';
|
|
317
|
+
}
|
|
318
|
+
return 'G';
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function classe_emission_ges(emission_ges_5_usages_m2, zc_id, ca_id, Sh) {
|
|
322
|
+
const ca = enums.classe_altitude[ca_id];
|
|
323
|
+
|
|
324
|
+
const cut = tvs.ges_class_limit[ca][Math.round(Sh)] ?? [];
|
|
325
|
+
|
|
326
|
+
if (!emission_ges_5_usages_m2) return null;
|
|
327
|
+
if (emission_ges_5_usages_m2 < (cut['A'] ?? 6)) return 'A';
|
|
328
|
+
if (emission_ges_5_usages_m2 < (cut['B'] ?? 11)) return 'B';
|
|
329
|
+
if (emission_ges_5_usages_m2 < (cut['C'] ?? 30)) return 'C';
|
|
330
|
+
if (emission_ges_5_usages_m2 < (cut['D'] ?? 50)) return 'D';
|
|
331
|
+
|
|
332
|
+
const zc = enums.zone_climatique[zc_id];
|
|
333
|
+
|
|
334
|
+
if (['h1b', 'h1c', 'h2d'].includes(zc) && ca === 'supérieur à 800m') {
|
|
335
|
+
if (emission_ges_5_usages_m2 < (cut['E'] ?? 80)) return 'E';
|
|
336
|
+
if (emission_ges_5_usages_m2 < (cut['F'] ?? 110)) return 'F';
|
|
337
|
+
} else {
|
|
338
|
+
if (emission_ges_5_usages_m2 < (cut['E'] ?? 70)) return 'E';
|
|
339
|
+
if (emission_ges_5_usages_m2 < (cut['F'] ?? 100)) return 'F';
|
|
340
|
+
}
|
|
341
|
+
return 'G';
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
Calcul de la consommation globale d'ECS
|
|
346
|
+
* @param gen_ecs {Generateur_ecs_collection}
|
|
347
|
+
* @param field {string}
|
|
348
|
+
* @param coef {number}
|
|
349
|
+
* @param prorataECS {number}
|
|
350
|
+
* @param prefix {string}
|
|
351
|
+
* @returns {number}
|
|
352
|
+
*/
|
|
353
|
+
function getEcsConso(gen_ecs, field, coef, prorataECS, prefix) {
|
|
354
|
+
return gen_ecs.reduce((acc, gen_ecs) => {
|
|
355
|
+
const conso = gen_ecs.donnee_intermediaire[field];
|
|
356
|
+
const typeEnergie = getTypeEnergie(gen_ecs.donnee_entree, 'ecs');
|
|
357
|
+
|
|
358
|
+
let coeffConsoEcs = { ...coef };
|
|
359
|
+
|
|
360
|
+
if (prefix === 'emission_ges') {
|
|
361
|
+
coeffConsoEcs[typeEnergie] = gen_ecs.donnee_utilisateur.coeffEmissionGes;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return (
|
|
365
|
+
acc +
|
|
366
|
+
getConso(coeffConsoEcs, typeEnergie, conso) *
|
|
367
|
+
(gen_ecs.donnee_entree.cle_repartition_ecs || prorataECS)
|
|
368
|
+
);
|
|
369
|
+
}, 0);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Calcul de la consommation globale de chauffage
|
|
374
|
+
* @param gen_ch {Generateur_chauffage_collection}
|
|
375
|
+
* @param field {string}
|
|
376
|
+
* @param coef {number}
|
|
377
|
+
* @param prorataChauffage {number}
|
|
378
|
+
* @param prefix {string}
|
|
379
|
+
* @returns {number}
|
|
380
|
+
*/
|
|
381
|
+
function getChauffageConso(gen_ch, field, coef, prorataChauffage, prefix) {
|
|
382
|
+
return gen_ch.reduce((acc, gen_ch) => {
|
|
383
|
+
const conso = gen_ch.donnee_intermediaire[field];
|
|
384
|
+
const typeEnergie = getTypeEnergie(gen_ch.donnee_entree, 'ch');
|
|
385
|
+
|
|
386
|
+
// La clé de répartition n'est utilisée que dans le cadre des chauffages collectifs
|
|
387
|
+
const repartition =
|
|
388
|
+
gen_ch.donnee_entree.enum_type_installation_id !== '1'
|
|
389
|
+
? gen_ch.donnee_entree.cle_repartition_ch || prorataChauffage
|
|
390
|
+
: prorataChauffage;
|
|
391
|
+
|
|
392
|
+
let coeffConsoChauffage = { ...coef };
|
|
393
|
+
|
|
394
|
+
if (prefix === 'emission_ges') {
|
|
395
|
+
coeffConsoChauffage[typeEnergie] = gen_ch.donnee_utilisateur.coeffEmissionGes;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return acc + getConso(coeffConsoChauffage, typeEnergie, conso) * repartition;
|
|
399
|
+
}, 0);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function calc_conso_pond(
|
|
403
|
+
Sh,
|
|
404
|
+
zc_id,
|
|
405
|
+
vt_list,
|
|
406
|
+
gen_ch,
|
|
407
|
+
gen_ecs,
|
|
408
|
+
fr_list,
|
|
409
|
+
prefix,
|
|
410
|
+
coef,
|
|
411
|
+
prorataECS,
|
|
412
|
+
prorataChauffage
|
|
413
|
+
) {
|
|
414
|
+
const ret = {};
|
|
415
|
+
ret.auxiliaire_ventilation = vt_list.reduce((acc, vt) => {
|
|
416
|
+
let conso = vt.donnee_intermediaire.conso_auxiliaire_ventilation || 0;
|
|
417
|
+
|
|
418
|
+
if (vt.donnee_entree.cle_repartition_ventilation) {
|
|
419
|
+
conso *= vt.donnee_entree.cle_repartition_ventilation;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return acc + getConso(coef, 'électricité auxiliaire', conso);
|
|
423
|
+
}, 0);
|
|
424
|
+
|
|
425
|
+
const conso_eclairage = calc_conso_eclairage(zc_id) * Sh;
|
|
426
|
+
ret.eclairage = getConso(coef, 'électricité éclairage', conso_eclairage);
|
|
427
|
+
|
|
428
|
+
// aux ch
|
|
429
|
+
ret.auxiliaire_generation_ch = gen_ch.reduce((acc, gen_ch) => {
|
|
430
|
+
const conso = gen_ch.donnee_intermediaire.conso_auxiliaire_generation_ch || 0;
|
|
431
|
+
return acc + getConso(coef, 'électricité auxiliaire', conso);
|
|
432
|
+
}, 0);
|
|
433
|
+
|
|
434
|
+
ret.auxiliaire_generation_ch_depensier = gen_ch.reduce((acc, gen_ch) => {
|
|
435
|
+
const conso = gen_ch.donnee_intermediaire.conso_auxiliaire_generation_ch_depensier || 0;
|
|
436
|
+
return acc + getConso(coef, 'électricité auxiliaire', conso);
|
|
437
|
+
}, 0);
|
|
438
|
+
|
|
439
|
+
ret.auxiliaire_distribution_ch = gen_ch.reduce((acc, gen_ch) => {
|
|
440
|
+
let conso = gen_ch.donnee_intermediaire.conso_auxiliaire_distribution_ch || 0;
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* enum_methode_calcul_conso_id
|
|
444
|
+
* 2 : 'installation collective rapportée à un logement : cas générateur à combustion virtuel ou ecs collective virtuelle'
|
|
445
|
+
*/
|
|
446
|
+
if (
|
|
447
|
+
['2', '4'].includes(gen_ch.donnee_entree.enum_methode_calcul_conso_id) &&
|
|
448
|
+
gen_ch.donnee_entree.cle_repartition_ch
|
|
449
|
+
) {
|
|
450
|
+
conso *= gen_ch.donnee_entree.cle_repartition_ch;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
return acc + getConso(coef, 'électricité auxiliaire', conso);
|
|
454
|
+
}, 0);
|
|
455
|
+
|
|
456
|
+
ret.ch = getChauffageConso(gen_ch, 'conso_ch', coef, prorataChauffage, prefix);
|
|
457
|
+
|
|
458
|
+
ret.ch_depensier = getChauffageConso(
|
|
459
|
+
gen_ch,
|
|
460
|
+
'conso_ch_depensier',
|
|
461
|
+
coef,
|
|
462
|
+
prorataChauffage,
|
|
463
|
+
prefix
|
|
464
|
+
);
|
|
465
|
+
|
|
466
|
+
ret.auxiliaire_generation_ecs = gen_ecs.reduce((acc, gen_ecs) => {
|
|
467
|
+
const conso = gen_ecs.donnee_intermediaire.conso_auxiliaire_generation_ecs || 0;
|
|
468
|
+
return acc + getConso(coef, 'électricité auxiliaire', conso);
|
|
469
|
+
}, 0);
|
|
470
|
+
|
|
471
|
+
ret.auxiliaire_generation_ecs_depensier = gen_ecs.reduce((acc, gen_ecs) => {
|
|
472
|
+
const conso = gen_ecs.donnee_intermediaire.conso_auxiliaire_generation_ecs_depensier || 0;
|
|
473
|
+
return acc + getConso(coef, 'électricité auxiliaire', conso);
|
|
474
|
+
}, 0);
|
|
475
|
+
|
|
476
|
+
ret.auxiliaire_distribution_ecs = 0;
|
|
477
|
+
|
|
478
|
+
ret.ecs = getEcsConso(gen_ecs, 'conso_ecs', coef, prorataECS, prefix);
|
|
479
|
+
|
|
480
|
+
ret.ecs_depensier = getEcsConso(gen_ecs, 'conso_ecs_depensier', coef, prorataECS, prefix);
|
|
481
|
+
|
|
482
|
+
ret.fr = fr_list.reduce((acc, fr) => {
|
|
483
|
+
const conso = fr.donnee_intermediaire.conso_fr;
|
|
484
|
+
const typeEnergie = getTypeEnergie(fr.donnee_entree, 'fr');
|
|
485
|
+
|
|
486
|
+
return acc + getConso(coef, typeEnergie, conso);
|
|
487
|
+
}, 0);
|
|
488
|
+
|
|
489
|
+
ret.fr_depensier = fr_list.reduce((acc, fr) => {
|
|
490
|
+
const conso = fr.donnee_intermediaire.conso_fr_depensier;
|
|
491
|
+
const typeEnergie = getTypeEnergie(fr.donnee_entree, 'fr');
|
|
492
|
+
|
|
493
|
+
return acc + getConso(coef, typeEnergie, conso);
|
|
494
|
+
}, 0);
|
|
495
|
+
|
|
496
|
+
let tot_aux;
|
|
497
|
+
if (prefix === 'cout') tot_aux = 'total_auxiliaire';
|
|
498
|
+
else tot_aux = 'totale_auxiliaire';
|
|
499
|
+
ret[tot_aux] =
|
|
500
|
+
ret.auxiliaire_ventilation +
|
|
501
|
+
ret.auxiliaire_generation_ch +
|
|
502
|
+
ret.auxiliaire_generation_ecs +
|
|
503
|
+
ret.auxiliaire_distribution_ch +
|
|
504
|
+
ret.auxiliaire_distribution_ecs;
|
|
505
|
+
ret['5_usages'] = ret.ch + ret.ecs + ret.fr + ret[tot_aux] + ret.eclairage;
|
|
506
|
+
if (prefix !== 'cout') ret['5_usages_m2'] = Math.floor(ret['5_usages'] / Sh);
|
|
507
|
+
|
|
508
|
+
// add prefix_ to all ret keys
|
|
509
|
+
Object.keys(ret).forEach((key) => {
|
|
510
|
+
ret[`${prefix}_${key}`] = ret[key];
|
|
511
|
+
delete ret[key];
|
|
512
|
+
});
|
|
513
|
+
return ret;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Retourne le type d'énergie utilisé.
|
|
518
|
+
* 1 - Electricité par défaut si la donnée n'est pas définie
|
|
519
|
+
* @param donneeEntree {Donnee_entree}
|
|
520
|
+
* @param suffix {string} Suffix à ajouter au type électricité
|
|
521
|
+
* @return {string}
|
|
522
|
+
*/
|
|
523
|
+
function getTypeEnergie(donneeEntree, suffix) {
|
|
524
|
+
let type_energie = enums.type_energie[donneeEntree.enum_type_energie_id || 1];
|
|
525
|
+
|
|
526
|
+
if (type_energie === 'électricité') type_energie = `électricité ${suffix}`;
|
|
527
|
+
|
|
528
|
+
return type_energie;
|
|
529
|
+
}
|