@open3cl/engine 1.0.7 → 1.0.9

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 (24) hide show
  1. package/features/dpe/domain/models/baie-vitree.model.ts +8 -6
  2. package/features/dpe/domain/models/dpe.model.ts +7 -3
  3. package/features/dpe/domain/models/{plancher-bas.model.ts → plancher.model.ts} +31 -7
  4. package/features/dpe/infrastructure/baieVitreeTv.store.js +292 -0
  5. package/features/dpe/infrastructure/baieVitreeTv.store.spec.js +352 -0
  6. package/features/dpe/infrastructure/pontThermiqueTv.store.js +112 -0
  7. package/features/dpe/infrastructure/pontThermiqueTv.store.spec.js +134 -0
  8. package/features/dpe/infrastructure/tv.store.js +0 -33
  9. package/features/dpe/infrastructure/tv.store.spec.js +0 -83
  10. package/features/engine/domain/engine.service.js +2 -1
  11. package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.js +292 -0
  12. package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.spec.js +484 -0
  13. package/features/engine/domain/enveloppe/deperdition-enveloppe.service.js +38 -0
  14. package/features/engine/domain/enveloppe/mur/deperdition-mur.service.js +28 -0
  15. package/features/engine/domain/enveloppe/mur/deperdition-mur.service.spec.js +61 -0
  16. package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.js +46 -0
  17. package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +85 -0
  18. package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.js +33 -0
  19. package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.spec.js +61 -0
  20. package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.js +439 -0
  21. package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.spec.js +636 -0
  22. package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.spec.js +49 -0
  23. package/package.json +1 -1
  24. package/features/dpe/domain/models/plancher-haut.model.ts +0 -33
@@ -451,89 +451,6 @@ describe('Lecture des tables de valeurs', () => {
451
451
  });
452
452
  });
453
453
 
454
- describe('lecture des valeurs de ug', () => {
455
- test.each([
456
- {
457
- label: 'Simple vitrage',
458
- enumTypeVitrageId: '1',
459
- expected: 5.8
460
- },
461
- {
462
- label: "Survitrage non traité avec lame d'air 6mm",
463
- enumTypeVitrageId: '4',
464
- epaisseurLame: 6,
465
- expected: 3.4
466
- },
467
- {
468
- label: "Survitrage non traité avec lame d'air 20mm",
469
- enumTypeVitrageId: '4',
470
- epaisseurLame: 20,
471
- expected: 2.8
472
- },
473
- {
474
- label: "Double vitrage vertical traité avec lame d'air argon 14mm",
475
- enumTypeVitrageId: '2',
476
- epaisseurLame: 14,
477
- enumTypeGazLameId: '2',
478
- enumInclinaisonVitrageId: '1',
479
- vitrageVir: true,
480
- expected: 1.2
481
- },
482
- {
483
- label: "Double vitrage vertical non traité avec lame d'air argon 14mm",
484
- enumTypeVitrageId: '2',
485
- epaisseurLame: 14,
486
- enumTypeGazLameId: '2',
487
- enumInclinaisonVitrageId: '1',
488
- vitrageVir: false,
489
- expected: 2.8
490
- },
491
- {
492
- label: "Double vitrage horizontal non traité avec lame d'air inconnu 15mm",
493
- enumTypeVitrageId: '2',
494
- epaisseurLame: 15,
495
- enumTypeGazLameId: '3',
496
- enumInclinaisonVitrageId: '4',
497
- vitrageVir: false,
498
- expected: 2.9
499
- },
500
- {
501
- label: "Double vitrage horizontal non traité avec lame d'air inconnu 12mm",
502
- enumTypeVitrageId: '2',
503
- epaisseurLame: 12,
504
- enumTypeGazLameId: '3',
505
- enumInclinaisonVitrageId: '4',
506
- vitrageVir: false,
507
- expected: 3.1
508
- }
509
- ])(
510
- `ug pour baie vitrée $label`,
511
- ({
512
- enumTypeVitrageId,
513
- enumTypeGazLameId = undefined,
514
- enumInclinaisonVitrageId = undefined,
515
- vitrageVir = undefined,
516
- epaisseurLame = undefined,
517
- expected
518
- }) => {
519
- expect(
520
- tvStore.getUg(
521
- enumTypeVitrageId,
522
- enumTypeGazLameId,
523
- enumInclinaisonVitrageId,
524
- vitrageVir,
525
- epaisseurLame
526
- )
527
- ).toBe(expected);
528
- }
529
- );
530
-
531
- test('pas de valeur de ug', () => {
532
- const ug = tvStore.getUg('0', '0', '0', false, 0);
533
- expect(ug).toBeUndefined();
534
- });
535
- });
536
-
537
454
  describe('lecture des valeurs de debits_ventilation', () => {
538
455
  test.each([
539
456
  {
@@ -1,6 +1,7 @@
1
1
  import { inject } from 'dioma';
2
2
  import { ContexteBuilder } from './contexte.builder.js';
3
3
  import { DeperditionEnveloppeService } from './enveloppe/deperdition-enveloppe.service.js';
4
+ import { logger } from '../../../core/util/logger/log-service.js';
4
5
 
5
6
  export class EngineService {
6
7
  /**
@@ -33,7 +34,7 @@ export class EngineService {
33
34
  /** @type {Dpe} */
34
35
  const proceededDpe = this.#removeComputedData(JSON.parse(JSON.stringify(dpe)));
35
36
 
36
- console.error(`Process DPE ${proceededDpe.numero_dpe}`);
37
+ logger.info(`Process DPE ${proceededDpe.numero_dpe}`);
37
38
 
38
39
  proceededDpe.logement.sortie = {
39
40
  deperdition: undefined,
@@ -0,0 +1,292 @@
1
+ import { DeperditionService } from '../deperdition.service.js';
2
+ import { inject } from 'dioma';
3
+ import { BaieVitreeTvStore } from '../../../../dpe/infrastructure/baieVitreeTv.store.js';
4
+
5
+ /**
6
+ * Calcul des déperditions des baies vitrées
7
+ * Chapitre 3.3 Calcul des parois vitrées
8
+ *
9
+ * Méthode de calcul 3CL-DPE 2021
10
+ * Octobre 2021
11
+ * @see consolide_anne…arrete_du_31_03_2021_relatif_aux_methodes_et_procedures_applicables.pdf
12
+ */
13
+ export class DeperditionBaieVitreeService extends DeperditionService {
14
+ /**
15
+ * @param tvStore {BaieVitreeTvStore}
16
+ */
17
+ constructor(tvStore = inject(BaieVitreeTvStore)) {
18
+ super(tvStore);
19
+ }
20
+
21
+ /**
22
+ * @param ctx {Contexte}
23
+ * @param bv {BaieVitree}
24
+ * @return {BaieVitreeDI}
25
+ */
26
+ execute(ctx, bv) {
27
+ const bvDE = bv.donnee_entree;
28
+
29
+ const b = this.b({
30
+ enumTypeAdjacenceId: bvDE.enum_type_adjacence_id,
31
+ surfaceAiu: bvDE.surface_aiu,
32
+ surfaceAue: bvDE.surface_aue,
33
+ enumCfgIsolationLncId: bvDE.enum_cfg_isolation_lnc_id,
34
+ zoneClimatiqueId: ctx.zoneClimatiqueId
35
+ });
36
+
37
+ let sw = this.sw(bv);
38
+ const ug = this.ug(bvDE);
39
+ let uw = this.uw(bv, ug);
40
+
41
+ /**
42
+ * Si le type de fermeture n'est pas '1: abscence de fermeture pour la baie vitrée',
43
+ * c'est qu'il y a présence d'une fermeture devant la fenêtre. Il faut prendre en compte la résistance de cette fermeture
44
+ */
45
+ let u_menuiserie = uw;
46
+ let ujn;
47
+ if (parseInt(bvDE.enum_type_fermeture_id) !== 1) {
48
+ ujn = this.ujn(bvDE, uw);
49
+ u_menuiserie = ujn;
50
+ }
51
+
52
+ const [fe1, fe2] = this.fe(bvDE);
53
+
54
+ /** @type {BaieVitreeDI} */
55
+ return {
56
+ b,
57
+ ug,
58
+ uw,
59
+ ujn,
60
+ u_menuiserie,
61
+ sw,
62
+ fe1,
63
+ fe2
64
+ };
65
+ }
66
+
67
+ /**
68
+ * Coefficient de transmission thermique du vitrage (W/(m².K))
69
+ *
70
+ * @param bvDE {BaieVitreeDE|BaieVitreeDoubleFenetreDE}
71
+ * @return {number|undefined}
72
+ */
73
+ ug(bvDE) {
74
+ if (bvDE.ug_saisi) {
75
+ return bvDE.ug_saisi;
76
+ }
77
+
78
+ // Pas de valeur ug pour les parois en brique de verre ou polycarbonate
79
+ if (parseInt(bvDE.enum_type_baie_id) < 4) {
80
+ return;
81
+ }
82
+
83
+ const enumTypeVitrageId = bvDE.enum_type_vitrage_id;
84
+ let e, enumTypeGazLameId, enumInclinaisonVitrageId, enumVitrageVir;
85
+
86
+ // Pas de type_gaz_lame, inclinaison_vitrage ou vitrage_vir pour un simple vitrage
87
+ if (enumTypeVitrageId !== '1') {
88
+ e = Math.min(bvDE.epaisseur_lame, 20);
89
+
90
+ const availableEpaisseurs = this.tvStore.getEpaisseurAvailableForUg();
91
+ if (e && !availableEpaisseurs.includes(e)) {
92
+ // 3.3.1 Détermination de la performance du vitrage Ug
93
+ // Attention : si la valeur de l’épaisseur de la lame d’air n’est pas dans le tableau présenté, prendre la valeur directement
94
+ // inférieure qui s’y trouve.
95
+ e = availableEpaisseurs.reduce(
96
+ (closest, num) => (num < e && num > closest ? num : closest),
97
+ -Infinity
98
+ );
99
+ }
100
+
101
+ enumTypeGazLameId = bvDE.enum_type_gaz_lame_id;
102
+ enumInclinaisonVitrageId = bvDE.enum_inclinaison_vitrage_id;
103
+ enumVitrageVir = bvDE.vitrage_vir;
104
+ }
105
+
106
+ /**
107
+ * Le Ug d’un survitrage est déterminé en apportant une majoration de 0,1 W/(m².K) au Ug du double vitrage rempli à
108
+ * l’air sec ayant la même épaisseur de lame d’air. Les épaisseurs des lames d’air pour le survitrage sont plafonnées à
109
+ * 20mm. C'est-à-dire que toute lame d’air d’un survitrage d’épaisseur supérieure à 20mm sera traitée dans les calculs
110
+ * comme une lame d’air de 20mm d’épaisseur.
111
+ */
112
+ if (enumTypeVitrageId === '4') {
113
+ const ug = this.tvStore.getUg('2', '1', enumInclinaisonVitrageId, enumVitrageVir, e);
114
+
115
+ return ug + 0.1;
116
+ } else {
117
+ return this.tvStore.getUg(
118
+ enumTypeVitrageId,
119
+ enumTypeGazLameId,
120
+ enumInclinaisonVitrageId,
121
+ enumVitrageVir,
122
+ e
123
+ );
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Proportion d’énergie solaire incidente qui pénètre dans le logement par la paroi vitrée en prenant en compte
129
+ * les doubles-fenêtres si existantes
130
+ *
131
+ * @param bv {BaieVitree}
132
+ * @return {number|undefined}
133
+ */
134
+ sw(bv) {
135
+ const bvDE = bv.donnee_entree;
136
+ let sw = this.#sw(bvDE);
137
+
138
+ /**
139
+ * S'il existe une double-fenêtre, calcul des facteurs sw et uw équivalents
140
+ * 6.2.1 Détermination du facteur solaire
141
+ */
142
+ if (bvDE.double_fenetre === 1 && bv.baie_vitree_double_fenetre) {
143
+ sw *= this.#sw(bv.baie_vitree_double_fenetre.donnee_entree) || 1;
144
+ }
145
+
146
+ return sw;
147
+ }
148
+
149
+ /**
150
+ * Proportion d’énergie solaire incidente qui pénètre dans le logement par la paroi vitrée
151
+ *
152
+ * @param bvDE {BaieVitreeDE|BaieVitreeDoubleFenetreDE}
153
+ * @return {number|undefined}
154
+ */
155
+ #sw(bvDE) {
156
+ if (bvDE.sw_saisi) {
157
+ return bvDE.sw_saisi;
158
+ }
159
+
160
+ /**
161
+ * 6.2.1 Détermination du facteur solaire
162
+ * Les champs vitrage_vir et enum_type_pose_id ne sont pas présentes pour les matériaux 'brique de verre' et 'polycarbonate'
163
+ *
164
+ * enum_type_materiaux_menuiserie_id
165
+ * 1 - brique de verre
166
+ * 2 - polycarbonate
167
+ */
168
+ let vitrageVir, typePose;
169
+ const typeMateriaux = bvDE.enum_type_materiaux_menuiserie_id;
170
+
171
+ if (![1, 2].includes(parseInt(typeMateriaux))) {
172
+ vitrageVir = bvDE.vitrage_vir;
173
+ typePose = bvDE.enum_type_pose_id;
174
+ }
175
+
176
+ return this.tvStore.getSw(
177
+ bvDE.enum_type_vitrage_id,
178
+ bvDE.enum_type_baie_id,
179
+ typeMateriaux,
180
+ vitrageVir,
181
+ typePose
182
+ );
183
+ }
184
+
185
+ /**
186
+ * Coefficient de transmission thermique de la fenêtre ou de la porte-fenêtre (vitrage + menuiserie) (W/(m².K)) en prenant en compte
187
+ * les doubles-fenêtres si existantes
188
+ *
189
+ * @param bv {BaieVitree}
190
+ * @param ug {number|undefined}
191
+ * @return {number|undefined}
192
+ */
193
+ uw(bv, ug) {
194
+ const bvDE = bv.donnee_entree;
195
+ let uw = this.#uw(bvDE, ug);
196
+
197
+ /**
198
+ * S'il existe une double-fenêtre, calcul des facteurs sw et uw équivalents
199
+ * 3.3.2 Coefficients Uw des fenêtres / portes-fenêtres - Traitement des doubles fenêtre
200
+ */
201
+ if (bvDE.double_fenetre === 1 && bv.baie_vitree_double_fenetre) {
202
+ const bvDoubleFenetreDE = bv.baie_vitree_double_fenetre.donnee_entree;
203
+ uw = 1 / (1 / uw + 1 / (this.#uw(bvDoubleFenetreDE, this.ug(bvDoubleFenetreDE)) || 1) + 0.07);
204
+ }
205
+
206
+ return uw;
207
+ }
208
+
209
+ /**
210
+ * Coefficient de transmission thermique de la fenêtre ou de la porte-fenêtre (vitrage + menuiserie) (W/(m².K))
211
+ *
212
+ * @param bvDE {BaieVitreeDE|BaieVitreeDoubleFenetreDE}
213
+ * @param ug {number|undefined}
214
+ * @return {number|undefined}
215
+ */
216
+ #uw(bvDE, ug) {
217
+ if (bvDE.uw_saisi) {
218
+ return bvDE.uw_saisi;
219
+ }
220
+
221
+ return this.tvStore.getUw(bvDE.enum_type_baie_id, bvDE.enum_type_materiaux_menuiserie_id, ug);
222
+ }
223
+
224
+ /**
225
+ * 3.3.3 Coefficients Ujn des fenêtres/portes-fenêtres
226
+ * La présence de volets aux fenêtres et portes-fenêtres leur apporte un supplément d’isolation avec une résistance
227
+ * additionnelle ΔR
228
+ *
229
+ * @param bvDE {BaieVitreeDE}
230
+ * @param uw {number}
231
+ * @return {number|undefined}
232
+ */
233
+ ujn(bvDE, uw) {
234
+ if (bvDE.ujn_saisi) {
235
+ return bvDE.ujn_saisi;
236
+ }
237
+
238
+ return this.tvStore.getUjn(bvDE.enum_type_fermeture_id, uw);
239
+ }
240
+
241
+ /**
242
+ * 6.2.2 Détermination du facteur d’ensoleillement
243
+ * Prise en comptes des masques qui peuvent faire de l'ombre sur les baies vitrées et influencé le facteur d'ensoleillement
244
+ *
245
+ * @param bvDE {BaieVitreeDE}
246
+ *
247
+ * @return {number[]}
248
+ */
249
+ fe(bvDE) {
250
+ let fe1 = 1,
251
+ fe2 = 1;
252
+
253
+ // Calcul des incidences des masques non homogènes
254
+ if (bvDE.masque_lointain_non_homogene_collection) {
255
+ let masquesLointainNonHomogene =
256
+ bvDE.masque_lointain_non_homogene_collection.masque_lointain_non_homogene || [];
257
+
258
+ if (!Array.isArray(masquesLointainNonHomogene)) {
259
+ masquesLointainNonHomogene = [masquesLointainNonHomogene];
260
+ }
261
+
262
+ fe2 = Math.max(
263
+ 0,
264
+ masquesLointainNonHomogene.reduce(
265
+ (acc, masqueLointainNonHomogene) => acc - this.calcOmbre(masqueLointainNonHomogene) / 100,
266
+ 1
267
+ )
268
+ );
269
+ }
270
+
271
+ // Calcul des incidences des masques proches
272
+ if (bvDE.tv_coef_masque_proche_id) {
273
+ fe1 = this.tvStore.getMasqueProche(bvDE.tv_coef_masque_proche_id);
274
+ }
275
+
276
+ // Calcul des incidences des masques proches
277
+ if (bvDE.tv_coef_masque_lointain_homogene_id) {
278
+ fe2 = this.tvStore.getMasqueLointainHomogene(bvDE.tv_coef_masque_lointain_homogene_id);
279
+ }
280
+
281
+ return [fe1, fe2];
282
+ }
283
+
284
+ /**
285
+ * Calcul de l'ombre apportée par un masque lointain non homogène
286
+ * @param masqueLointainNonHomogene {MasqueLointainNonHomogene}
287
+ * @returns {number}
288
+ */
289
+ calcOmbre(masqueLointainNonHomogene) {
290
+ return this.tvStore.getOmbre(masqueLointainNonHomogene.tv_coef_masque_lointain_non_homogene_id);
291
+ }
292
+ }