@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.
Files changed (85) hide show
  1. package/10_besoin_fr.js +76 -0
  2. package/10_clim.js +45 -0
  3. package/11_besoin_ecs.js +25 -0
  4. package/11_ecs.js +95 -0
  5. package/11_nadeq.js +87 -0
  6. package/11_nadeq.spec.js +55 -0
  7. package/12.4_pac.js +54 -0
  8. package/13.2_generateur_combustion.js +295 -0
  9. package/13.2_generateur_combustion_bouilleur.js +173 -0
  10. package/13.2_generateur_combustion_ch.js +195 -0
  11. package/13.2_generateur_combustion_chaudiere.js +151 -0
  12. package/13.2_generateur_pac.js +36 -0
  13. package/13_rendement_distribution_ecs.js +12 -0
  14. package/14_generateur_ecs.js +388 -0
  15. package/15_conso_aux.js +257 -0
  16. package/16.2_production_enr.js +328 -0
  17. package/16.2_production_enr.spec.js +251 -0
  18. package/16_conso_eclairage.js +37 -0
  19. package/2021_04_13_confort_ete.js +61 -0
  20. package/2021_04_13_qualite_isolation.js +174 -0
  21. package/3.1_b.js +141 -0
  22. package/3.2.1_mur.js +331 -0
  23. package/3.2.1_mur.spec.js +46 -0
  24. package/3.2.2_plancher_bas.js +259 -0
  25. package/3.2.2_plancher_bas.spec.js +88 -0
  26. package/3.2.3_plancher_haut.js +158 -0
  27. package/3.3.1.4_porte.js +32 -0
  28. package/3.3_baie_vitree.js +308 -0
  29. package/3.3_baie_vitree.spec.js +333 -0
  30. package/3.4_pont_thermique.js +463 -0
  31. package/3_deperdition.js +258 -0
  32. package/4_ventilation.js +197 -0
  33. package/5_conso_ventilation.js +127 -0
  34. package/6.1_apport_gratuit.js +61 -0
  35. package/6.1_apport_gratuit.spec.js +181 -0
  36. package/6.2_surface_sud_equivalente.js +109 -0
  37. package/7_inertie.js +178 -0
  38. package/7_inertie.spec.js +263 -0
  39. package/8_intermittence.js +5 -0
  40. package/9_besoin_ch.js +198 -0
  41. package/9_chauffage.js +291 -0
  42. package/9_chauffage.spec.js +101 -0
  43. package/9_conso_ch.js +95 -0
  44. package/9_conso_ch.spec.js +255 -0
  45. package/9_emetteur_ch.js +122 -0
  46. package/9_generateur_ch.js +230 -0
  47. package/9_generateur_ch.spec.js +87 -0
  48. package/README.md +43 -0
  49. package/apport_et_besoin.js +55 -0
  50. package/conso.js +529 -0
  51. package/conso.spec.js +90 -0
  52. package/core/assets/domain/add-additionnal-ue-values-tables.js +57 -0
  53. package/core/assets/domain/synchronize-assets.js +29 -0
  54. package/core/assets/domain/synchronize-assets.spec.js +37 -0
  55. package/core/assets/domain/synchronize-c1-tables.js +61 -0
  56. package/core/assets/domain/synchronize-c1-tables.spec.js +35 -0
  57. package/core/assets/domain/synchronize-dpe-ges-limit-values-tables.js +73 -0
  58. package/core/assets/domain/synchronize-dpe-ges-limit-values-tables.spec.js +72 -0
  59. package/core/assets/domain/synchronize-enum-tables.js +77 -0
  60. package/core/assets/domain/synchronize-enum-tables.spec.js +31 -0
  61. package/core/assets/domain/synchronize-solicitations-tables.js +72 -0
  62. package/core/assets/domain/synchronize-solicitations-tables.spec.js +47 -0
  63. package/core/assets/domain/synchronize-valeur-tables.js +146 -0
  64. package/core/assets/domain/synchronize-valeur-tables.spec.js +54 -0
  65. package/core/conf/infrastructure/application.config.js +33 -0
  66. package/core/file/infrastructure/adapter/file.store.js +75 -0
  67. package/core/file/infrastructure/adapter/file.store.spec.js +30 -0
  68. package/core/tv/infrastructure/assets/additional-ue-values.js +69 -0
  69. package/core/tv/infrastructure/tvs.store.js +40 -0
  70. package/core/tv/infrastructure/tvs.store.spec.js +34 -0
  71. package/core/util/infrastructure/object-util.js +23 -0
  72. package/core/util/infrastructure/object-util.spec.js +25 -0
  73. package/engine.js +503 -0
  74. package/enums.js +1155 -0
  75. package/ficheTechnique.js +86 -0
  76. package/ficheTechnique.spec.js +181 -0
  77. package/index.js +4 -0
  78. package/package.json +87 -0
  79. package/tv/18.2_sollicitations_ext.ods +0 -0
  80. package/tv/18.5_c1.ods +0 -0
  81. package/tv/dpe_ges_limit_values.ods +0 -0
  82. package/tv.js +80811 -0
  83. package/tvs.d.ts +7 -0
  84. package/utils.js +500 -0
  85. package/utils.spec.js +36 -0
@@ -0,0 +1,258 @@
1
+ import enums from './enums.js';
2
+ import calc_mur from './3.2.1_mur.js';
3
+ import calc_pb from './3.2.2_plancher_bas.js';
4
+ import calc_ph from './3.2.3_plancher_haut.js';
5
+ import calc_bv from './3.3_baie_vitree.js';
6
+ import calc_porte from './3.3.1.4_porte.js';
7
+ import calc_pont_thermique from './3.4_pont_thermique.js';
8
+ import calc_ventilation from './4_ventilation.js';
9
+
10
+ function calc_Sdep(murs_list, porte_list, bv_list) {
11
+ const Smurs_dep = murs_list.reduce((acc, mur) => {
12
+ const type_adjacence = enums.type_adjacence[mur.donnee_entree.enum_type_adjacence_id];
13
+ if (mur.donnee_intermediaire.b === 0) return acc;
14
+ if (type_adjacence.includes('local non déperditif')) return acc;
15
+ else return acc + Number(mur.donnee_entree.surface_paroi_opaque);
16
+ }, 0);
17
+ const Sporte = porte_list.reduce((acc, porte) => {
18
+ if (porte.donnee_intermediaire.b === 0) return acc;
19
+ return acc + Number(porte.donnee_entree.surface_porte);
20
+ }, 0);
21
+ const Sbv = bv_list.reduce((acc, bv) => {
22
+ if (bv.donnee_intermediaire.b === 0) return acc;
23
+ return acc + Number(bv.donnee_entree.surface_totale_baie);
24
+ }, 0);
25
+ const Sdep = Smurs_dep + Sporte + Sbv;
26
+ return Sdep;
27
+ }
28
+
29
+ export function Umur(o) {
30
+ const de = o.donnee_entree;
31
+ const di = o.donnee_intermediaire;
32
+ return de.surface_paroi_opaque * di.umur * di.b;
33
+ }
34
+
35
+ export function Uph(o) {
36
+ const de = o.donnee_entree;
37
+ const di = o.donnee_intermediaire;
38
+ return de.surface_paroi_opaque * di.uph * di.b;
39
+ }
40
+
41
+ export function Upb(o) {
42
+ const de = o.donnee_entree;
43
+ const di = o.donnee_intermediaire;
44
+ return de.surface_paroi_opaque * di.upb_final * di.b;
45
+ }
46
+
47
+ export function Ubv(o) {
48
+ const de = o.donnee_entree;
49
+ const di = o.donnee_intermediaire;
50
+ return de.surface_totale_baie * di.u_menuiserie * di.b;
51
+ }
52
+
53
+ export function Uporte(o) {
54
+ const de = o.donnee_entree;
55
+ const di = o.donnee_intermediaire;
56
+ return de.surface_porte * di.uporte * di.b;
57
+ }
58
+
59
+ /**
60
+ * Compare la liste des ponts thermiques déclarés et calculés
61
+ * Retourne true si individuellement chacun des ponts thermiques est identique
62
+ * @param calculatedPTs
63
+ * @param declaredPTs
64
+ * @returns {boolean}
65
+ */
66
+ function verifyPontsThermiquesEquality(calculatedPTs, declaredPTs) {
67
+ /**
68
+ * Pour les ponts thermiques déclarés, le facteur deperdition_pont_thermique étant déjà pris en compte, seul k est considéré
69
+ */
70
+ const uptForCalculatedPTs = calculatedPTs.map(
71
+ (calculatedPT) =>
72
+ calculatedPT.donnee_intermediaire.k *
73
+ (calculatedPT.donnee_entree.pourcentage_valeur_pont_thermique || 1)
74
+ );
75
+ const uptForDeclaredPTs = declaredPTs.map((declaredPT) => declaredPT.donnee_intermediaire.k);
76
+
77
+ return (
78
+ calculatedPTs.length === declaredPTs.length &&
79
+ !uptForCalculatedPTs.some((val, i) => {
80
+ return (
81
+ val.toFixed(3) !== uptForDeclaredPTs[i].toFixed(3) &&
82
+ val.toFixed(3) !==
83
+ (
84
+ uptForDeclaredPTs[i] *
85
+ (calculatedPTs[i].donnee_entree.pourcentage_valeur_pont_thermique || 1)
86
+ ).toFixed(3)
87
+ );
88
+ })
89
+ );
90
+ }
91
+
92
+ /**
93
+ * Compare la liste des murs déclarés et calculés
94
+ * Retourne true si individuellement chacun des murs est identique
95
+ * @param calculatedMurs
96
+ * @param declaredMurs
97
+ * @returns {boolean}
98
+ */
99
+ function verifyMursEquality(calculatedMurs, declaredMurs) {
100
+ const uMurForCalculatedMurs = calculatedMurs.map(
101
+ (calculatedMur) =>
102
+ calculatedMur.donnee_entree.surface_paroi_opaque *
103
+ calculatedMur.donnee_intermediaire.umur *
104
+ calculatedMur.donnee_intermediaire.b
105
+ );
106
+ const uMurForDeclaredMurs = declaredMurs.map(
107
+ (declaredMur) =>
108
+ declaredMur.donnee_entree.surface_paroi_opaque *
109
+ declaredMur.donnee_intermediaire.umur *
110
+ declaredMur.donnee_intermediaire.b
111
+ );
112
+
113
+ return (
114
+ calculatedMurs.length === declaredMurs.length &&
115
+ !uMurForCalculatedMurs.some((val, i) => val.toFixed(3) !== uMurForDeclaredMurs[i].toFixed(3))
116
+ );
117
+ }
118
+
119
+ /**
120
+ * Calcul de la déperdition totale liée aux ponts thermiques
121
+ * @param dpe {FullDpe}
122
+ * @param calculatedPontsThermiques
123
+ * @param declaredPontsThermiques
124
+ * @return {number}
125
+ */
126
+ function totalDeperditionPontThermique(dpe, calculatedPontsThermiques, declaredPontsThermiques) {
127
+ // Total déclaré des déperditions des ponts thermiques
128
+ const declaredDeperditionPT = dpe.logement.sortie.deperdition.deperdition_pont_thermique;
129
+
130
+ /**
131
+ * Comparaison des valeurs intermédiaires calculées et déclarées pour chacun des ponts thermiques
132
+ * @type {boolean}
133
+ */
134
+ const sameValues = verifyPontsThermiquesEquality(
135
+ calculatedPontsThermiques,
136
+ declaredPontsThermiques
137
+ );
138
+
139
+ const calculatedDeperditionPT = calculatedPontsThermiques.reduce(
140
+ (acc, pt) => acc + Upt(pt) || 0,
141
+ 0
142
+ );
143
+
144
+ /**
145
+ * Si individuellement les ponts thermiques déclarés et calculés sont identiques, la déperdition totale devrait l'être également
146
+ * Pour certains DPE, il réside une différence que l'on prendra en compte pour la suite des calculs.
147
+ */
148
+ if (sameValues && calculatedDeperditionPT.toFixed(5) !== declaredDeperditionPT.toFixed(5)) {
149
+ console.error(
150
+ `Les valeurs des ponts thermiques calculées et déclarées pour le DPE ${dpe.numero_dpe} sont les mêmes mais le total des déperditions pour les ponts thermiques
151
+ ${declaredDeperditionPT} diffère du total calculé avec les mêmes valeurs ${declaredDeperditionPT}'. Le total déclaré est conservé.`
152
+ );
153
+ return declaredDeperditionPT;
154
+ }
155
+ return calculatedDeperditionPT;
156
+ }
157
+
158
+ /**
159
+ * Calcul de la déperdition totale liée aux murs
160
+ * @param dpe {FullDpe}
161
+ * @param calculatedMurs
162
+ * @param declaredMurs
163
+ * @return {number}
164
+ */
165
+ function totalDeperditionMurs(dpe, calculatedMurs, declaredMurs) {
166
+ // Total déclaré des déperditions des murs
167
+ const declaredDeperditionMurs = dpe.logement.sortie.deperdition.deperdition_mur;
168
+
169
+ /**
170
+ * Comparaison des valeurs intermédiaires calculées et déclarées pour chacun des murs
171
+ * @type {boolean}
172
+ */
173
+ const sameValues = verifyMursEquality(calculatedMurs, declaredMurs);
174
+
175
+ const calculatedDeperditionMur = calculatedMurs.reduce((acc, mur) => acc + Umur(mur) || 0, 0);
176
+
177
+ /**
178
+ * Si individuellement les murs déclarés et calculés sont identiques, la déperdition totale devrait l'être également
179
+ * Pour certains DPE, il réside une différence que l'on prendra en compte pour la suite des calculs.
180
+ */
181
+ if (sameValues && calculatedDeperditionMur.toFixed(5) !== declaredDeperditionMurs.toFixed(5)) {
182
+ if (declaredDeperditionMurs.toFixed(5) > calculatedDeperditionMur.toFixed(5)) {
183
+ console.error(
184
+ `Les valeurs des murs calculées et déclarées pour le DPE ${dpe.numero_dpe} sont les mêmes mais le total déclaré des déperditions pour les murs
185
+ '${declaredDeperditionMurs}' diffère et est supérieure au total calculé avec les mêmes valeurs '${calculatedDeperditionMur}'. Le total déclaré est conservé.`
186
+ );
187
+
188
+ return declaredDeperditionMurs;
189
+ } else {
190
+ console.error(
191
+ `Les valeurs des murs calculées et déclarées pour le DPE ${dpe.numero_dpe} sont les mêmes mais le total déclaré des déperditions pour les murs
192
+ '${declaredDeperditionMurs}' diffère et est inférieure au total calculé avec les mêmes valeurs '${calculatedDeperditionMur}'. Le total calculé est conservé.`
193
+ );
194
+
195
+ return calculatedDeperditionMur;
196
+ }
197
+ }
198
+ return calculatedDeperditionMur;
199
+ }
200
+
201
+ export function Upt(pt) {
202
+ const de = pt.donnee_entree;
203
+ const di = pt.donnee_intermediaire;
204
+
205
+ return de.l * di.k * (de.pourcentage_valeur_pont_thermique || 1);
206
+ }
207
+
208
+ export default function calc_deperdition(cg, zc, th, effetJoule, dpe, Sh) {
209
+ const pc = cg.enum_periode_construction_id;
210
+ const logement = dpe.logement;
211
+ const enveloppe = logement.enveloppe;
212
+
213
+ const mur_list = enveloppe.mur_collection.mur || [];
214
+ const declaredMurs = structuredClone(mur_list);
215
+ const pb_list = enveloppe.plancher_bas_collection.plancher_bas || [];
216
+ const ph_list = enveloppe.plancher_haut_collection.plancher_haut || [];
217
+ const porte_list = enveloppe.porte_collection.porte || [];
218
+ const bv_list = enveloppe.baie_vitree_collection.baie_vitree || [];
219
+ const pt_list = enveloppe.pont_thermique_collection.pont_thermique || [];
220
+ const declaredPontsThermiques = structuredClone(pt_list);
221
+ const vt_list = logement.ventilation_collection.ventilation || [];
222
+
223
+ mur_list.forEach((mur) => calc_mur(mur, zc, pc, effetJoule));
224
+ pb_list.forEach((pb) => calc_pb(pb, zc, pc, effetJoule, pb_list));
225
+ ph_list.forEach((ph) => calc_ph(ph, zc, pc, effetJoule));
226
+ bv_list.forEach((bv) => calc_bv(bv, zc));
227
+ porte_list.forEach((porte) => calc_porte(porte, zc));
228
+ pt_list.forEach((pt) => calc_pont_thermique(pt, pc, logement));
229
+
230
+ const murs_list = mur_list.concat(ph_list);
231
+ const Sdep = calc_Sdep(murs_list, porte_list, bv_list);
232
+
233
+ vt_list.forEach((vt) => {
234
+ calc_ventilation(vt, cg, th, Sdep, Sh, mur_list, ph_list, porte_list, bv_list);
235
+ });
236
+
237
+ const d_mur = totalDeperditionMurs(dpe, mur_list, declaredMurs);
238
+ const d_pb = pb_list.reduce((acc, pb) => acc + Upb(pb) || 0, 0);
239
+ const d_ph = ph_list.reduce((acc, ph) => acc + Uph(ph) || 0, 0);
240
+ const d_bv = bv_list.reduce((acc, bv) => acc + Ubv(bv) || 0, 0);
241
+ const d_porte = porte_list.reduce((acc, porte) => acc + Uporte(porte) || 0, 0);
242
+ const d_pt = totalDeperditionPontThermique(dpe, pt_list, declaredPontsThermiques);
243
+ const hvent = vt_list.reduce((acc, vt) => acc + vt.donnee_intermediaire.hvent || 0, 0);
244
+ const hperm = vt_list.reduce((acc, vt) => acc + vt.donnee_intermediaire.hperm || 0, 0);
245
+
246
+ return {
247
+ hvent,
248
+ hperm,
249
+ deperdition_renouvellement_air: hvent + hperm,
250
+ deperdition_mur: d_mur,
251
+ deperdition_plancher_bas: d_pb,
252
+ deperdition_plancher_haut: d_ph,
253
+ deperdition_baie_vitree: d_bv,
254
+ deperdition_porte: d_porte,
255
+ deperdition_pont_thermique: d_pt,
256
+ deperdition_enveloppe: d_mur + d_pb + d_ph + d_bv + d_porte + d_pt + hvent + hperm
257
+ };
258
+ }
@@ -0,0 +1,197 @@
1
+ import enums from './enums.js';
2
+ import { tv, requestInputID, requestInput, bug_for_bug_compat } from './utils.js';
3
+ import calc_pvent from './5_conso_ventilation.js';
4
+
5
+ function tv_debits_ventilation(di, de, du) {
6
+ const matcher = {
7
+ enum_type_ventilation_id: requestInputID(de, du, 'type_ventilation')
8
+ };
9
+
10
+ const row = tv('debits_ventilation', matcher);
11
+ if (row) {
12
+ di.qvarep_conv = Number(row.qvarep_conv);
13
+ di.qvasouf_conv = Number(row.qvasouf_conv);
14
+ di.smea_conv = Number(row.smea_conv);
15
+ de.tv_debits_ventilation_id = Number(row.tv_debits_ventilation_id);
16
+ } else {
17
+ console.error('!! pas de valeur forfaitaire trouvée pour debits_ventilation !!');
18
+ }
19
+ }
20
+
21
+ function tv_q4pa_conv(di, de, cg, mur_list, ph_list, porte_list, bv_list) {
22
+ const surfaces = mur_list.concat(ph_list);
23
+ const surface_isolee = surfaces.reduce((acc, s) => {
24
+ const type_isolation = enums.type_isolation[s.donnee_entree.enum_type_isolation_id];
25
+ if (s.donnee_intermediaire.b === 0) return acc;
26
+ if (['non isolé', 'inconnu'].includes(type_isolation)) return acc;
27
+ else return acc + s.donnee_entree.surface_paroi_opaque;
28
+ }, 0);
29
+ const surface_non_isolee = surfaces.reduce((acc, s) => {
30
+ const type_isolation = enums.type_isolation[s.donnee_entree.enum_type_isolation_id];
31
+ if (s.donnee_intermediaire.b === 0) return acc;
32
+ if (['non isolé', 'inconnu'].includes(type_isolation)) {
33
+ return acc + s.donnee_entree.surface_paroi_opaque;
34
+ } else return acc;
35
+ }, 0);
36
+ let isolation_surfaces = surface_isolee > surface_non_isolee ? '1' : '0';
37
+
38
+ // presence joints menuiserie
39
+ let surface_bv_avec_joint = bv_list.reduce((acc, bv) => {
40
+ if (bv.donnee_entree.presence_joint) return acc + bv.donnee_entree.surface_totale_baie;
41
+ else return acc;
42
+ }, 0);
43
+ surface_bv_avec_joint += porte_list.reduce((acc, porte) => {
44
+ if (porte.donnee_entree.presence_joint) return acc + porte.donnee_entree.surface_porte;
45
+ else return acc;
46
+ }, 0);
47
+ let surface_bv_sans_joint = bv_list.reduce((acc, bv) => {
48
+ if (!bv.donnee_entree.presence_joint) return acc + bv.donnee_entree.surface_totale_baie;
49
+ else return acc;
50
+ }, 0);
51
+ surface_bv_sans_joint += porte_list.reduce((acc, porte) => {
52
+ if (!porte.donnee_entree.presence_joint) return acc + porte.donnee_entree.surface_porte;
53
+ else return acc;
54
+ }, 0);
55
+ let pjt =
56
+ surface_bv_avec_joint / (surface_bv_avec_joint + surface_bv_sans_joint) > 0.5 ? '1' : '0';
57
+
58
+ if (bug_for_bug_compat && de.tv_q4pa_conv_id) {
59
+ const rowQ4paConv = tv('q4pa_conv', {
60
+ tv_q4pa_conv_id: de.tv_q4pa_conv_id
61
+ });
62
+
63
+ if (rowQ4paConv) {
64
+ if (rowQ4paConv.isolation_surfaces !== isolation_surfaces) {
65
+ console.error(
66
+ `Calcul de hperm pour la ventilation ${de.description}. Le DPE considère isolation_surfaces = ${rowQ4paConv.isolation_surfaces}
67
+ alors que ce devrait être isolation_surfaces = ${isolation_surfaces}. La valeur du DPE isolation_surfaces = ${rowQ4paConv.isolation_surfaces} est utilisée.`
68
+ );
69
+ }
70
+
71
+ if (rowQ4paConv.presence_joints_menuiserie !== pjt) {
72
+ console.error(
73
+ `Calcul de hperm pour la ventilation ${de.description}. Le DPE considère presence_joints_menuiserie = ${rowQ4paConv.presence_joints_menuiserie}
74
+ alors que ce devrait être presence_joints_menuiserie = ${pjt}. La valeur du DPE presence_joints_menuiserie = ${rowQ4paConv.presence_joints_menuiserie} est utilisée.`
75
+ );
76
+ }
77
+ }
78
+ }
79
+
80
+ const matcher = {
81
+ enum_periode_construction_id: cg.enum_periode_construction_id,
82
+ enum_methode_application_dpe_log_id: cg.enum_methode_application_dpe_log_id,
83
+ isolation_surfaces,
84
+ presence_joints_menuiserie: pjt
85
+ };
86
+ const row = tv('q4pa_conv', matcher);
87
+ if (row) {
88
+ di.q4pa_conv = Number(row.q4pa_conv);
89
+ de.tv_q4pa_conv_id = Number(row.tv_q4pa_conv_id);
90
+ } else {
91
+ console.error('!! pas de valeur forfaitaire trouvée pour q4pa_conv !!');
92
+ }
93
+ }
94
+
95
+ const e_tab = {
96
+ 1: 0.07,
97
+ 0: 0.02
98
+ };
99
+
100
+ const f_tab = {
101
+ 1: 15,
102
+ 0: 20
103
+ };
104
+
105
+ function calc_hperm(di, surface_ventile, Hsp, Sdep, pfe) {
106
+ const e = e_tab[pfe];
107
+ const f = f_tab[pfe];
108
+ const Q4pa_env = di.q4pa_conv * Sdep;
109
+ const Q4pa = Q4pa_env + 0.45 * di.smea_conv * surface_ventile;
110
+ const n50 = Q4pa / ((4 / 50) ** (2 / 3) * Hsp * surface_ventile);
111
+ const Qvinf =
112
+ (Hsp * surface_ventile * n50 * e) /
113
+ (1 + (f / e) * ((di.qvasouf_conv - di.qvarep_conv) / (Hsp * n50)) ** 2);
114
+ di.hperm = 0.34 * Qvinf;
115
+ }
116
+
117
+ export default function calc_ventilation(
118
+ vt,
119
+ cg,
120
+ th,
121
+ Sdep,
122
+ Sh,
123
+ mur_list,
124
+ ph_list,
125
+ porte_list,
126
+ bv_list
127
+ ) {
128
+ const de = vt.donnee_entree;
129
+ const du = {};
130
+ const di = {};
131
+
132
+ let surface_ventile = requestInput(de, du, 'surface_ventile', 'float');
133
+
134
+ if (!surface_ventile) {
135
+ surface_ventile = Sh;
136
+ } else if (surface_ventile !== Sh) {
137
+ // S'il y a une répartition alors c'est que la vmc est collective. La surface à prendre en compte est la surface de l'immeuble
138
+ surface_ventile /= de.cle_repartition_ventilation || 1;
139
+ }
140
+
141
+ const Hsp = cg.hsp;
142
+
143
+ tv_debits_ventilation(di, de, du);
144
+ tv_q4pa_conv(di, de, cg, mur_list, ph_list, porte_list, bv_list);
145
+
146
+ di.hvent = 0.34 * di.qvarep_conv * surface_ventile;
147
+
148
+ let pfe = requestInput(de, du, 'plusieurs_facade_exposee', 'bool');
149
+
150
+ /**
151
+ * Si une fiche technique pour cette variable est présente, elle est prise en compte
152
+ * Les valeurs de plusieurs_facade_exposee n'étant pas toujours utilisées de la même manière
153
+ * dans tous les DPEs (parfois 0 = 'Oui', d'autres 0 = 'Non')
154
+ */
155
+ if (de.ficheTechniqueFacadesExposees) {
156
+ const pfeFicheTechnique = ['non', 'une'].includes(
157
+ de.ficheTechniqueFacadesExposees.valeur.toLowerCase()
158
+ )
159
+ ? 0
160
+ : 1;
161
+
162
+ if (pfeFicheTechnique !== pfe) {
163
+ console.error(
164
+ `La valeur de la variable plusieurs_facade_exposee ne correspond pas à celle présente
165
+ dans la fiche technique "${de.ficheTechniqueFacadesExposees.description}".
166
+ La valeur de la fiche technique est prise en compte.`
167
+ );
168
+ }
169
+
170
+ pfe = pfeFicheTechnique;
171
+ }
172
+
173
+ /**
174
+ * Si une fiche technique pour cette variable est présente, elle est prise en compte
175
+ * Les valeurs de ventilation_post_2012 n'étant pas toujours utilisées de la même manière
176
+ * dans tous les DPEs (parfois 0 = 'Oui', d'autres 0 = 'Non')
177
+ */
178
+ if (de.ficheTechniqueVentilationPost2012 && de.ventilation_post_2012 === 0) {
179
+ console.error(
180
+ `La valeur de la variable ventilation_post_2012 ne correspond pas à celle présente
181
+ dans la fiche technique "${de.ficheTechniqueVentilationPost2012.description}".
182
+ La valeur de la fiche technique est prise en compte.`
183
+ );
184
+
185
+ de.ventilation_post_2012 = 1;
186
+ }
187
+
188
+ calc_hperm(di, surface_ventile, Hsp, Sdep, pfe);
189
+ calc_pvent(di, de, du, th);
190
+
191
+ delete di.qvarep_conv;
192
+ delete di.qvasouf_conv;
193
+ delete di.smea_conv;
194
+
195
+ vt.donnee_intermediaire = di;
196
+ vt.donnee_utilisateur = du;
197
+ }
@@ -0,0 +1,127 @@
1
+ import { requestInput } from './utils.js';
2
+
3
+ const pvent_moy_maison = {
4
+ 'simple flux auto': {
5
+ 0: 65,
6
+ 1: 35
7
+ },
8
+ 'simple flux hygro': {
9
+ 0: 50,
10
+ 1: 15
11
+ },
12
+ 'double flux': {
13
+ 0: 80,
14
+ 1: 35
15
+ }
16
+ };
17
+
18
+ const pvent_immeuble = {
19
+ 'simple flux auto': {
20
+ 0: 0.46,
21
+ 1: 0.25
22
+ },
23
+ 'simple flux hygro': {
24
+ 0: 0.46,
25
+ 1: 0.25
26
+ },
27
+ 'double flux': {
28
+ 0: 1.1,
29
+ 1: 0.6
30
+ }
31
+ };
32
+
33
+ /**
34
+ * 5 - Calcul des consommations d’auxiliaires de ventilation
35
+ * Retourne le coefficient en fonction du type d'habitation et du type de ventilation
36
+ * @param {string} th Type d'habitation (maison ou autre)
37
+ * @param {boolean} hybride Ventilation hybride ou pas
38
+ *
39
+ * @return {number}
40
+ */
41
+ function getCoefficient(th, hybride) {
42
+ if (!hybride) {
43
+ return 1;
44
+ }
45
+ const ratio = th === 'maison' ? 14 : 28;
46
+ return ratio / (24 * 7);
47
+ }
48
+
49
+ export default function calc_pvent(di, de, du, th) {
50
+ const tv = requestInput(de, du, 'type_ventilation');
51
+ let post_2012 = requestInput(de, du, 'ventilation_post_2012', 'bool');
52
+
53
+ // can't calculate without these
54
+ if (tv === undefined || post_2012 === undefined) return;
55
+
56
+ let hybride = false;
57
+ let type;
58
+ switch (tv) {
59
+ case 'ventilation par ouverture des fenêtres':
60
+ case "ventilation par entrées d'air hautes et basses":
61
+ case 'ventilation naturelle par conduit':
62
+ case "ventilation naturelle par conduit avec entrées d'air hygro":
63
+ case 'puits climatique sans échangeur avant 2013':
64
+ case 'puits climatique sans échangeur à partir de 2013':
65
+ case 'puits climatique avec échangeur avant 2013':
66
+ case 'puits climatique avec échangeur à partir de 2013':
67
+ di.conso_auxiliaire_ventilation = 0;
68
+ return;
69
+ case 'ventilation hybride avant 2001':
70
+ case 'ventilation hybride de 2001 à 2012':
71
+ case 'ventilation hybride après 2012':
72
+ case "ventilation hybride avec entrées d'air hygro avant 2001":
73
+ case "ventilation hybride avec entrées d'air hygro de 2001 à 2012":
74
+ case "ventilation hybride avec entrées d'air hygro après 2012":
75
+ hybride = true;
76
+ post_2012 = 0;
77
+ /**
78
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf, pages 41-42
79
+ * Les consommations d’auxiliaires pour une VMC hybride correspondent aux consommations d’une VMC
80
+ * classique autoréglable de 2001 à 2012 multipliées par le ratio du temps d’utilisation
81
+ */
82
+ type = 'simple flux auto';
83
+ break;
84
+ case 'ventilation mécanique sur conduit existant avant 2013':
85
+ case 'ventilation mécanique sur conduit existant à partir de 2013':
86
+ case 'vmc sf auto réglable avant 1982':
87
+ case 'vmc sf auto réglable de 1982 à 2000':
88
+ case 'vmc sf auto réglable de 2001 à 2012':
89
+ case 'vmc sf auto réglable après 2012':
90
+ type = 'simple flux auto';
91
+ break;
92
+ case 'vmc sf gaz avant 2001':
93
+ case 'vmc sf gaz de 2001 à 2012':
94
+ case 'vmc sf gaz après 2012':
95
+ console.error('vmc gaz ??');
96
+ return;
97
+ case 'vmc sf hygro b avant 2001':
98
+ case 'vmc sf hygro b de 2001 à 2012':
99
+ case 'vmc sf hygro b après 2012':
100
+ case 'vmc sf hygro a avant 2001':
101
+ case 'vmc sf hygro a de 2001 à 2012':
102
+ case 'vmc sf hygro a après 2012':
103
+ case 'vmc basse pression auto-réglable':
104
+ case 'vmc basse pression hygro a':
105
+ case 'vmc basse pression hygro b':
106
+ type = 'simple flux hygro';
107
+ break;
108
+ case 'vmc df individuelle avec échangeur avant 2013':
109
+ case 'vmc df individuelle avec échangeur à partir de 2013':
110
+ case 'vmc df collective avec échangeur avant 2013':
111
+ case 'vmc df collective avec échangeur à partir de 2013':
112
+ case 'vmc df sans échangeur avant 2013':
113
+ case 'vmc df sans échangeur après 2012':
114
+ type = 'double flux';
115
+ break;
116
+ }
117
+
118
+ const coef = getCoefficient(th, hybride);
119
+ if (th === 'maison') {
120
+ di.pvent_moy = pvent_moy_maison[type][post_2012] * coef;
121
+ } else {
122
+ const pvent = pvent_immeuble[type][post_2012];
123
+ const sv = requestInput(de, du, 'surface_ventile', 'float');
124
+ di.pvent_moy = pvent * di.qvarep_conv * sv * coef;
125
+ }
126
+ di.conso_auxiliaire_ventilation = 8.76 * di.pvent_moy;
127
+ }
@@ -0,0 +1,61 @@
1
+ import tvs from './tv.js';
2
+ import { mois_liste } from './utils.js';
3
+ import { calc_sse_j } from './6.2_surface_sud_equivalente.js';
4
+
5
+ export function calc_ai_j(Sh, nadeq, nrefj) {
6
+ /**
7
+ * L'unité retenue est le Wh conformément à la spécification, cependant
8
+ * il est possible de rencontrer des valeurs avec une unité en kWh dans les DPE.
9
+ */
10
+ return ((3.18 + 0.34) * Sh + 90 * (132 / 168) * nadeq) * nrefj;
11
+ }
12
+
13
+ export function calc_as_j(ssej, ej) {
14
+ /**
15
+ * L'unité retenue est le Wh conformément à la spécification, cependant
16
+ * il est possible de rencontrer des valeurs avec une unité en kWh dans les DPE.
17
+ */
18
+ return 1000 * ssej * ej;
19
+ }
20
+
21
+ export function calc_ai(ilpa, ca, zc, Sh, nadeq) {
22
+ const Nref19 = tvs.nref19[ilpa];
23
+ const Nref28 = tvs.nref28;
24
+
25
+ const ret = {
26
+ apport_interne_ch: 0,
27
+ /* apport_interne_ch_depensier: 0, */
28
+ apport_interne_fr: 0
29
+ /* apport_interne_fr_depensier: 0 */
30
+ };
31
+ for (const mois of mois_liste) {
32
+ const nref19 = Nref19[ca][mois][zc];
33
+ const nref28 = Nref28[ca][mois][zc];
34
+ ret.apport_interne_ch += calc_ai_j(Sh, nadeq, nref19);
35
+ /* ret.apport_interne_ch_depensier += calc_ai_j(Sh, nadeq, nref21) */
36
+ ret.apport_interne_fr += calc_ai_j(Sh, nadeq, nref28);
37
+ /* ret.apport_interne_fr_depensier += calc_ai_j(Sh, nadeq, nref26) */
38
+ }
39
+ return ret;
40
+ }
41
+
42
+ export function calc_as(ilpa, ca, zc, bv, ets) {
43
+ const e = tvs.e[ilpa];
44
+ const e_fr_28 = tvs.e_fr_28;
45
+
46
+ const ret = {
47
+ apport_solaire_ch: 0,
48
+ apport_solaire_fr: 0
49
+ /* apport_solaire_fr_depensier: 0 */
50
+ };
51
+ for (const mois of mois_liste) {
52
+ const ssej = calc_sse_j(bv, ets, ca, zc, mois);
53
+ const ej = e[ca][mois][zc];
54
+ const ej_fr_28 = e_fr_28[ca][mois][zc];
55
+
56
+ ret.apport_solaire_ch += calc_as_j(ssej, ej);
57
+ ret.apport_solaire_fr += calc_as_j(ssej, ej_fr_28);
58
+ /* ret.apport_solaire_fr_depensier += calc_as_j(ssej, ej_fr_26) */
59
+ }
60
+ return ret;
61
+ }