@open3cl/engine 1.0.6 → 1.0.8
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/11_nadeq.spec.js +3 -2
- package/16.2_production_enr.spec.js +1 -0
- package/3.2.1_mur.spec.js +1 -0
- package/3.2.2_plancher_bas.spec.js +1 -0
- package/3.3_baie_vitree.spec.js +1 -0
- package/6.1_apport_gratuit.spec.js +1 -0
- package/7_inertie.spec.js +4 -3
- package/9_chauffage.spec.js +1 -0
- package/9_conso_ch.spec.js +1 -0
- package/9_generateur_ch.spec.js +1 -0
- package/conso.spec.js +1 -0
- package/core/assets/domain/synchronize-assets.spec.js +9 -9
- package/core/assets/domain/synchronize-c1-tables.spec.js +4 -4
- package/core/assets/domain/synchronize-dpe-ges-limit-values-tables.spec.js +6 -6
- package/core/assets/domain/synchronize-enum-tables.spec.js +10 -10
- package/core/assets/domain/synchronize-solicitations-tables.spec.js +6 -6
- package/core/assets/domain/synchronize-valeur-tables.spec.js +14 -14
- package/core/file/infrastructure/adapter/file.store.spec.js +5 -4
- package/core/tv/infrastructure/tvs.store.spec.js +3 -2
- package/core/util/infrastructure/object-util.spec.js +2 -1
- package/core/util/logger/log-service.js +47 -0
- package/features/dpe/domain/models/baie-ets.model.ts +12 -0
- package/features/dpe/domain/models/baie-vitree.model.ts +97 -0
- package/features/dpe/domain/models/climatisation.model.ts +25 -0
- package/features/dpe/domain/models/dpe.model.ts +194 -0
- package/features/dpe/domain/models/ets.model.ts +19 -0
- package/features/dpe/domain/models/installation-chauffage.model.ts +101 -0
- package/features/dpe/domain/models/installation-ecs.model.ts +76 -0
- package/features/dpe/domain/models/mur.model.ts +37 -0
- package/features/dpe/domain/models/plancher-bas.model.ts +38 -0
- package/features/dpe/domain/models/plancher-haut.model.ts +33 -0
- package/features/dpe/domain/models/pont-thermique.model.ts +21 -0
- package/features/dpe/domain/models/porte.model.ts +31 -0
- package/features/dpe/domain/models/production-elec-enr.model.ts +27 -0
- package/features/dpe/domain/models/sortie.model.ts +178 -0
- package/features/dpe/domain/models/type-habitation.model.js +8 -0
- package/features/dpe/domain/models/type-ventilation.model.js +8 -0
- package/features/dpe/domain/models/ventilation.model.ts +33 -0
- package/features/dpe/infrastructure/baieVitreeTv.store.js +292 -0
- package/features/dpe/infrastructure/baieVitreeTv.store.spec.js +352 -0
- package/features/dpe/infrastructure/tv.store.js +356 -0
- package/features/dpe/infrastructure/tv.store.spec.js +607 -0
- package/features/engine/domain/constants.js +1 -0
- package/features/engine/domain/contexte.builder.js +140 -0
- package/features/engine/domain/contexte.builder.spec.js +152 -0
- package/features/engine/domain/engine.service.js +139 -0
- package/features/engine/domain/engine.service.spec.js +7 -0
- package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.js +292 -0
- package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.spec.js +484 -0
- package/features/engine/domain/enveloppe/deperdition-enveloppe.service.js +278 -0
- package/features/engine/domain/enveloppe/deperdition-enveloppe.service.spec.js +282 -0
- package/features/engine/domain/enveloppe/deperdition.service.js +101 -0
- package/features/engine/domain/enveloppe/mur/deperdition-mur.service.js +168 -0
- package/features/engine/domain/enveloppe/mur/deperdition-mur.service.spec.js +345 -0
- package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.js +169 -0
- package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +200 -0
- package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.js +136 -0
- package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.spec.js +211 -0
- package/features/engine/domain/enveloppe/porte/deperdition-porte.service.js +56 -0
- package/features/engine/domain/enveloppe/porte/deperdition-porte.service.spec.js +116 -0
- package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.js +338 -0
- package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.spec.js +442 -0
- package/features/engine/domain/models/contexte.model.ts +10 -0
- package/features/engine/domain/models/deperdition.model.ts +8 -0
- package/features/normalizer/domain/dpe-normalizer.service.js +24 -0
- package/features/normalizer/domain/dpe-normalizer.service.spec.js +3 -0
- package/ficheTechnique.spec.js +4 -3
- package/output.js +1 -0
- package/package.json +9 -8
- package/tv-v2.js +79121 -0
- package/utils.js +2 -2
- package/utils.spec.js +4 -3
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { inject } from 'dioma';
|
|
2
|
+
import { DeperditionMurService } from './mur/deperdition-mur.service.js';
|
|
3
|
+
import { DeperditionPorteService } from './porte/deperdition-porte.service.js';
|
|
4
|
+
import { DeperditionPlancherBasService } from './plancher_bas/deperdition-plancher-bas.service.js';
|
|
5
|
+
import { DeperditionPlancherHautService } from './plancher_haut/deperdition-plancher-haut.service.js';
|
|
6
|
+
import { DeperditionVentilationService } from './ventilation/deperdition-ventilation.service.js';
|
|
7
|
+
import { DeperditionBaieVitreeService } from './baie_vitree/deperdition-baie-vitree.service.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Calcul des déperditions de l’enveloppe
|
|
11
|
+
* @see Méthode de calcul 3CL-DPE 2021 (cotobre 2021) chapitre 3
|
|
12
|
+
*/
|
|
13
|
+
export class DeperditionEnveloppeService {
|
|
14
|
+
/**
|
|
15
|
+
* @type {DeperditionMurService}
|
|
16
|
+
*/
|
|
17
|
+
#deperditionMurService;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @type {DeperditionPorteService}
|
|
21
|
+
*/
|
|
22
|
+
#deperditionPorteService;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @type {DeperditionPlancherBasService}
|
|
26
|
+
*/
|
|
27
|
+
#deperditionPlancherBasService;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @type {DeperditionPlancherHautService}
|
|
31
|
+
*/
|
|
32
|
+
#deperditionPlancherHautService;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @type {DeperditionBaieVitreeService}
|
|
36
|
+
*/
|
|
37
|
+
#deperditionBaieVitreeService;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @type {DeperditionVentilationService}
|
|
41
|
+
*/
|
|
42
|
+
#deperditionVentilationService;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @type {number}
|
|
46
|
+
*/
|
|
47
|
+
#surfaceDeperditive;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @type {number}
|
|
51
|
+
*/
|
|
52
|
+
#surfaceIsolee;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @type {number}
|
|
56
|
+
*/
|
|
57
|
+
#surfaceNonIsolee;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @type {number}
|
|
61
|
+
*/
|
|
62
|
+
#surfaceMenuiserieAvecJoint;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @type {number}
|
|
66
|
+
*/
|
|
67
|
+
#surfaceMenuiserieSansJoint;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
*
|
|
71
|
+
* @param deperditionMurService {DeperditionMurService}
|
|
72
|
+
* @param deperditionPorteService {DeperditionPorteService}
|
|
73
|
+
* @param deperditionPlancherBasService {DeperditionPlancherBasService}
|
|
74
|
+
* @param deperditionPlancherHautService {DeperditionPlancherHautService}
|
|
75
|
+
* @param deperditionBaieVitreeService {DeperditionBaieVitreeService}
|
|
76
|
+
* @param deperditionVentilationService {DeperditionVentilationService}
|
|
77
|
+
*/
|
|
78
|
+
constructor(
|
|
79
|
+
deperditionMurService = inject(DeperditionMurService),
|
|
80
|
+
deperditionPorteService = inject(DeperditionPorteService),
|
|
81
|
+
deperditionPlancherBasService = inject(DeperditionPlancherBasService),
|
|
82
|
+
deperditionPlancherHautService = inject(DeperditionPlancherHautService),
|
|
83
|
+
deperditionBaieVitreeService = inject(DeperditionBaieVitreeService),
|
|
84
|
+
deperditionVentilationService = inject(DeperditionVentilationService)
|
|
85
|
+
) {
|
|
86
|
+
this.#deperditionMurService = deperditionMurService;
|
|
87
|
+
this.#deperditionPorteService = deperditionPorteService;
|
|
88
|
+
this.#deperditionPlancherBasService = deperditionPlancherBasService;
|
|
89
|
+
this.#deperditionPlancherHautService = deperditionPlancherHautService;
|
|
90
|
+
this.#deperditionBaieVitreeService = deperditionBaieVitreeService;
|
|
91
|
+
this.#deperditionVentilationService = deperditionVentilationService;
|
|
92
|
+
this.#surfaceDeperditive = 0;
|
|
93
|
+
this.#surfaceIsolee = 0;
|
|
94
|
+
this.#surfaceNonIsolee = 0;
|
|
95
|
+
this.#surfaceMenuiserieAvecJoint = 0;
|
|
96
|
+
this.#surfaceMenuiserieSansJoint = 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Calcul des déperditions de l’enveloppe
|
|
101
|
+
* @param ctx {Contexte}
|
|
102
|
+
* @param logement {Logement}
|
|
103
|
+
* @returns {{hvent: number, hperm: number, deperdition_renouvellement_air: number, deperdition_mur: number, deperdition_plancher_bas: number, deperdition_plancher_haut: number, deperdition_baie_vitree: number, deperdition_porte: number, deperdition_pont_thermique: number, deperdition_enveloppe: number}}
|
|
104
|
+
*/
|
|
105
|
+
deperditions(ctx, logement) {
|
|
106
|
+
const GV = this.#gv(ctx, logement.enveloppe);
|
|
107
|
+
const ventilation = this.#ventilation(ctx, logement);
|
|
108
|
+
return {
|
|
109
|
+
...GV,
|
|
110
|
+
...ventilation,
|
|
111
|
+
...{
|
|
112
|
+
deperdition_enveloppe:
|
|
113
|
+
GV.deperdition_mur +
|
|
114
|
+
GV.deperdition_plancher_bas +
|
|
115
|
+
GV.deperdition_plancher_haut +
|
|
116
|
+
GV.deperdition_baie_vitree +
|
|
117
|
+
GV.deperdition_porte +
|
|
118
|
+
GV.deperdition_pont_thermique +
|
|
119
|
+
ventilation.hvent +
|
|
120
|
+
ventilation.hperm
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Calcul des déperditions de l’enveloppe GV
|
|
127
|
+
*
|
|
128
|
+
* @param ctx {Contexte}
|
|
129
|
+
* @param enveloppe {Enveloppe}
|
|
130
|
+
*
|
|
131
|
+
* @return {Deperdition}
|
|
132
|
+
*/
|
|
133
|
+
#gv(ctx, enveloppe) {
|
|
134
|
+
this.#surfaceDeperditive = 0;
|
|
135
|
+
this.#surfaceIsolee = 0;
|
|
136
|
+
this.#surfaceNonIsolee = 0;
|
|
137
|
+
this.#surfaceMenuiserieAvecJoint = 0;
|
|
138
|
+
this.#surfaceMenuiserieSansJoint = 0;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @type {Deperdition}
|
|
142
|
+
*/
|
|
143
|
+
const deperditions = {
|
|
144
|
+
deperdition_mur: 0,
|
|
145
|
+
deperdition_plancher_bas: 0,
|
|
146
|
+
deperdition_plancher_haut: 0,
|
|
147
|
+
deperdition_baie_vitree: 0,
|
|
148
|
+
deperdition_porte: 0
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
enveloppe.mur_collection.mur?.forEach((m) => {
|
|
152
|
+
m.donnee_intermediaire = this.#deperditionMurService.execute(ctx, m.donnee_entree);
|
|
153
|
+
deperditions.deperdition_mur +=
|
|
154
|
+
m.donnee_intermediaire.b *
|
|
155
|
+
m.donnee_entree.surface_paroi_opaque *
|
|
156
|
+
m.donnee_intermediaire.umur;
|
|
157
|
+
|
|
158
|
+
if (m.donnee_intermediaire.b > 0) {
|
|
159
|
+
// Paroi déperditive si b != 0 et adjacence != 'local non déperditif'
|
|
160
|
+
if (m.donnee_entree.enum_type_adjacence_id !== '22') {
|
|
161
|
+
this.#surfaceDeperditive += m.donnee_entree.surface_paroi_opaque;
|
|
162
|
+
}
|
|
163
|
+
// Surface isolée si b != 0 et type d'isolation != 'inconnu' et != 'non isolé'
|
|
164
|
+
if (['1', '2'].includes(m.donnee_entree.enum_type_isolation_id)) {
|
|
165
|
+
this.#surfaceNonIsolee += m.donnee_entree.surface_paroi_opaque;
|
|
166
|
+
} else {
|
|
167
|
+
this.#surfaceIsolee += m.donnee_entree.surface_paroi_opaque;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
enveloppe.porte_collection.porte?.forEach((p) => {
|
|
173
|
+
p.donnee_intermediaire = this.#deperditionPorteService.execute(ctx, p.donnee_entree);
|
|
174
|
+
deperditions.deperdition_porte +=
|
|
175
|
+
p.donnee_intermediaire.b * p.donnee_entree.surface_porte * p.donnee_intermediaire.uporte;
|
|
176
|
+
|
|
177
|
+
// Surface de porte déperditive si b != 0
|
|
178
|
+
if (p.donnee_intermediaire.b > 0) {
|
|
179
|
+
this.#surfaceDeperditive += p.donnee_entree.surface_porte;
|
|
180
|
+
}
|
|
181
|
+
// Surface de porte avec ou sans joint
|
|
182
|
+
if (p.donnee_entree.presence_joint) {
|
|
183
|
+
this.#surfaceMenuiserieAvecJoint += p.donnee_entree.surface_porte;
|
|
184
|
+
} else {
|
|
185
|
+
this.#surfaceMenuiserieSansJoint += p.donnee_entree.surface_porte;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const plancherBas = enveloppe.plancher_bas_collection.plancher_bas || [];
|
|
190
|
+
plancherBas?.forEach((pb) => {
|
|
191
|
+
pb.donnee_intermediaire = this.#deperditionPlancherBasService.execute(
|
|
192
|
+
ctx,
|
|
193
|
+
pb.donnee_entree,
|
|
194
|
+
plancherBas
|
|
195
|
+
);
|
|
196
|
+
deperditions.deperdition_plancher_bas +=
|
|
197
|
+
pb.donnee_intermediaire.b *
|
|
198
|
+
pb.donnee_entree.surface_paroi_opaque *
|
|
199
|
+
pb.donnee_intermediaire.upb_final;
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
enveloppe.plancher_haut_collection.plancher_haut?.forEach((ph) => {
|
|
203
|
+
ph.donnee_intermediaire = this.#deperditionPlancherHautService.execute(ctx, ph.donnee_entree);
|
|
204
|
+
deperditions.deperdition_plancher_haut +=
|
|
205
|
+
ph.donnee_intermediaire.b *
|
|
206
|
+
ph.donnee_entree.surface_paroi_opaque *
|
|
207
|
+
ph.donnee_intermediaire.uph;
|
|
208
|
+
|
|
209
|
+
if (ph.donnee_intermediaire.b > 0) {
|
|
210
|
+
// Plancher déperditif si b != 0 et adjacence != 'local non déperditif'
|
|
211
|
+
if (ph.donnee_entree.enum_type_adjacence_id !== '22') {
|
|
212
|
+
this.#surfaceDeperditive += ph.donnee_entree.surface_paroi_opaque;
|
|
213
|
+
}
|
|
214
|
+
// Surface isolée si b != 0 et type d'isolation != 'inconnu' et != 'non isolé'
|
|
215
|
+
if (['1', '2'].includes(ph.donnee_entree.enum_type_isolation_id)) {
|
|
216
|
+
this.#surfaceNonIsolee += ph.donnee_entree.surface_paroi_opaque;
|
|
217
|
+
} else {
|
|
218
|
+
this.#surfaceIsolee += ph.donnee_entree.surface_paroi_opaque;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
enveloppe.baie_vitree_collection.baie_vitree?.forEach((bv) => {
|
|
224
|
+
bv.donnee_intermediaire = this.#deperditionBaieVitreeService.execute(ctx, bv);
|
|
225
|
+
deperditions.deperdition_baie_vitree +=
|
|
226
|
+
bv.donnee_intermediaire.b *
|
|
227
|
+
bv.donnee_entree.surface_totale_baie *
|
|
228
|
+
bv.donnee_intermediaire.u_menuiserie;
|
|
229
|
+
|
|
230
|
+
// Surface de baie vitrée déperditive si b != 0
|
|
231
|
+
if (bv.donnee_intermediaire.b > 0) {
|
|
232
|
+
this.#surfaceDeperditive += bv.donnee_entree.surface_totale_baie;
|
|
233
|
+
}
|
|
234
|
+
// Surface de baie vitrée avec ou sans joint
|
|
235
|
+
if (bv.donnee_entree.presence_joint) {
|
|
236
|
+
this.#surfaceMenuiserieAvecJoint += bv.donnee_entree.surface_totale_baie;
|
|
237
|
+
} else {
|
|
238
|
+
this.#surfaceMenuiserieSansJoint += bv.donnee_entree.surface_totale_baie;
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
return deperditions;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Calcul des déperditions par la ventilation
|
|
247
|
+
*
|
|
248
|
+
* @param ctx {Contexte}
|
|
249
|
+
* @param logement {Logement}
|
|
250
|
+
*
|
|
251
|
+
* @return {Deperdition}
|
|
252
|
+
*/
|
|
253
|
+
#ventilation(ctx, logement) {
|
|
254
|
+
/**
|
|
255
|
+
* @type {Deperdition}
|
|
256
|
+
*/
|
|
257
|
+
const deperditions = {
|
|
258
|
+
hperm: 0,
|
|
259
|
+
hvent: 0
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
logement.ventilation_collection.ventilation?.forEach((ventilation) => {
|
|
263
|
+
ventilation.donnee_intermediaire = this.#deperditionVentilationService.execute(
|
|
264
|
+
ctx,
|
|
265
|
+
ventilation.donnee_entree,
|
|
266
|
+
this.#surfaceDeperditive,
|
|
267
|
+
this.#surfaceIsolee,
|
|
268
|
+
this.#surfaceNonIsolee,
|
|
269
|
+
this.#surfaceMenuiserieAvecJoint,
|
|
270
|
+
this.#surfaceMenuiserieSansJoint
|
|
271
|
+
);
|
|
272
|
+
deperditions.hvent += ventilation.donnee_intermediaire.hvent;
|
|
273
|
+
deperditions.hperm += ventilation.donnee_intermediaire.hperm;
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
return deperditions;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { DeperditionEnveloppeService } from './deperdition-enveloppe.service.js';
|
|
2
|
+
import corpus from '../../../../../test/corpus-sano.json';
|
|
3
|
+
import { getAdemeFileJson } from '../../../../../test/test-helpers.js';
|
|
4
|
+
import { ContexteBuilder } from '../contexte.builder.js';
|
|
5
|
+
import { DeperditionPlancherBasService } from './plancher_bas/deperdition-plancher-bas.service.js';
|
|
6
|
+
import { DeperditionMurService } from './mur/deperdition-mur.service.js';
|
|
7
|
+
import { DeperditionPorteService } from './porte/deperdition-porte.service.js';
|
|
8
|
+
import { DeperditionPlancherHautService } from './plancher_haut/deperdition-plancher-haut.service.js';
|
|
9
|
+
import { DpeNormalizerService } from '../../../normalizer/domain/dpe-normalizer.service.js';
|
|
10
|
+
import { TvStore } from '../../../dpe/infrastructure/tv.store.js';
|
|
11
|
+
import { beforeEach, describe, expect, test } from 'vitest';
|
|
12
|
+
import b from '../../../../3.1_b.js';
|
|
13
|
+
|
|
14
|
+
/** @type {DeperditionPorteService} **/
|
|
15
|
+
let deperditionPorteService;
|
|
16
|
+
|
|
17
|
+
/** @type {DeperditionMurService} **/
|
|
18
|
+
let deperditionMurService;
|
|
19
|
+
|
|
20
|
+
/** @type {DeperditionPlancherBasService} **/
|
|
21
|
+
let deperditionPlancherBasService;
|
|
22
|
+
|
|
23
|
+
/** @type {DeperditionPlancherHautService} **/
|
|
24
|
+
let deperditionPlancherHautService;
|
|
25
|
+
|
|
26
|
+
/** @type {DpeNormalizerService} **/
|
|
27
|
+
let normalizerService;
|
|
28
|
+
|
|
29
|
+
/** @type {ContexteBuilder} **/
|
|
30
|
+
let contexteBuilder;
|
|
31
|
+
|
|
32
|
+
/** @type {TvStore} **/
|
|
33
|
+
let tvStore;
|
|
34
|
+
|
|
35
|
+
/** @type {DeperditionEnveloppeService} **/
|
|
36
|
+
let service;
|
|
37
|
+
|
|
38
|
+
describe('Calcul des déperditions', () => {
|
|
39
|
+
beforeEach(() => {
|
|
40
|
+
tvStore = new TvStore();
|
|
41
|
+
deperditionPorteService = new DeperditionPorteService(tvStore);
|
|
42
|
+
deperditionMurService = new DeperditionMurService(tvStore);
|
|
43
|
+
deperditionPlancherBasService = new DeperditionPlancherBasService(tvStore);
|
|
44
|
+
deperditionPlancherHautService = new DeperditionPlancherHautService(tvStore);
|
|
45
|
+
normalizerService = new DpeNormalizerService();
|
|
46
|
+
contexteBuilder = new ContexteBuilder();
|
|
47
|
+
|
|
48
|
+
service = new DeperditionEnveloppeService(
|
|
49
|
+
deperditionMurService,
|
|
50
|
+
deperditionPorteService,
|
|
51
|
+
deperditionPlancherBasService,
|
|
52
|
+
deperditionPlancherHautService
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe('Détermination du coefficient de réduction des déperditions b', () => {
|
|
57
|
+
test.each([
|
|
58
|
+
{ enumTypeAdjacenceId: '1', label: 'extérieur', bExpected: 1 },
|
|
59
|
+
{ enumTypeAdjacenceId: '2', label: 'paroi enterrée', bExpected: 1 },
|
|
60
|
+
{ enumTypeAdjacenceId: '3', label: 'vide sanitaire', bExpected: 1 },
|
|
61
|
+
{
|
|
62
|
+
enumTypeAdjacenceId: '4',
|
|
63
|
+
label: "bâtiment ou local à usage autre que d'habitation",
|
|
64
|
+
bExpected: 0.2
|
|
65
|
+
},
|
|
66
|
+
{ enumTypeAdjacenceId: '5', label: 'terre-plein', bExpected: 1 },
|
|
67
|
+
{ enumTypeAdjacenceId: '6', label: 'sous-sol non chauffé', bExpected: 1 },
|
|
68
|
+
{
|
|
69
|
+
enumTypeAdjacenceId: '7',
|
|
70
|
+
enumCfgIsolationLncId: '1',
|
|
71
|
+
label: 'locaux non chauffés non accessible',
|
|
72
|
+
bExpected: 0.95
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
enumTypeAdjacenceId: '8',
|
|
76
|
+
surfaceAiu: 14.75,
|
|
77
|
+
surfaceAue: 300,
|
|
78
|
+
enumCfgIsolationLncId: '2',
|
|
79
|
+
label: 'garage',
|
|
80
|
+
bExpected: 0.9
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
enumTypeAdjacenceId: '9',
|
|
84
|
+
surfaceAiu: 8.14,
|
|
85
|
+
surfaceAue: 22.8,
|
|
86
|
+
enumCfgIsolationLncId: '4',
|
|
87
|
+
label: 'cellier',
|
|
88
|
+
bExpected: 0.95
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
enumTypeAdjacenceId: '10',
|
|
92
|
+
surfaceAiu: 8.14,
|
|
93
|
+
surfaceAue: 22.8,
|
|
94
|
+
enumCfgIsolationLncId: '9',
|
|
95
|
+
label: 'espace tampon solarisé (véranda,loggia fermée)',
|
|
96
|
+
bExpected: undefined
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
enumTypeAdjacenceId: '10',
|
|
100
|
+
surfaceAiu: 8.14,
|
|
101
|
+
surfaceAue: 22.8,
|
|
102
|
+
zoneClimatiqueId: '5',
|
|
103
|
+
enumCfgIsolationLncId: '9',
|
|
104
|
+
label: 'espace tampon solarisé (véranda,loggia fermée)',
|
|
105
|
+
bExpected: 0.85
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
enumTypeAdjacenceId: '11',
|
|
109
|
+
surfaceAiu: 50.2,
|
|
110
|
+
surfaceAue: 60,
|
|
111
|
+
enumCfgIsolationLncId: '4',
|
|
112
|
+
label: 'comble fortement ventilé',
|
|
113
|
+
bExpected: 0.95
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
enumTypeAdjacenceId: '12',
|
|
117
|
+
surfaceAiu: 74,
|
|
118
|
+
surfaceAue: 110,
|
|
119
|
+
enumCfgIsolationLncId: '4',
|
|
120
|
+
label: 'comble faiblement ventilé',
|
|
121
|
+
bExpected: 0.95
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
enumTypeAdjacenceId: '13',
|
|
125
|
+
surfaceAiu: 30,
|
|
126
|
+
surfaceAue: 45,
|
|
127
|
+
enumCfgIsolationLncId: '2',
|
|
128
|
+
label: 'comble très faiblement ventilé',
|
|
129
|
+
bExpected: 0.65
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
enumTypeAdjacenceId: '14',
|
|
133
|
+
surfaceAiu: 22,
|
|
134
|
+
surfaceAue: 15,
|
|
135
|
+
enumCfgIsolationLncId: '2',
|
|
136
|
+
label: "circulation sans ouverture directe sur l'extérieur",
|
|
137
|
+
bExpected: 0.35
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
enumTypeAdjacenceId: '15',
|
|
141
|
+
surfaceAiu: 20,
|
|
142
|
+
surfaceAue: 2.5,
|
|
143
|
+
enumCfgIsolationLncId: '2',
|
|
144
|
+
label: "circulation avec ouverture directe sur l'extérieur",
|
|
145
|
+
bExpected: 0.15
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
enumTypeAdjacenceId: '16',
|
|
149
|
+
surfaceAiu: 120,
|
|
150
|
+
surfaceAue: 300,
|
|
151
|
+
enumCfgIsolationLncId: '3',
|
|
152
|
+
label: 'circulation avec bouche ou gaine de désenfumage ouverte en permanence',
|
|
153
|
+
bExpected: 0.7
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
enumTypeAdjacenceId: '17',
|
|
157
|
+
label: "hall d'entrée avec dispositif de fermeture automatique",
|
|
158
|
+
bExpected: 0
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
enumTypeAdjacenceId: '18',
|
|
162
|
+
surfaceAiu: 335.22,
|
|
163
|
+
surfaceAue: 29.18,
|
|
164
|
+
enumCfgIsolationLncId: '2',
|
|
165
|
+
label: "hall d'entrée sans dispositif de fermeture automatique",
|
|
166
|
+
bExpected: 0.15
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
enumTypeAdjacenceId: '19',
|
|
170
|
+
surfaceAiu: 49,
|
|
171
|
+
surfaceAue: 65,
|
|
172
|
+
enumCfgIsolationLncId: '2',
|
|
173
|
+
label: 'garage privé collectif',
|
|
174
|
+
bExpected: 0.7
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
enumTypeAdjacenceId: '20',
|
|
178
|
+
label: "local tertiaire à l'intérieur de l'immeuble en contact avec l'appartement",
|
|
179
|
+
bExpected: 0.2
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
enumTypeAdjacenceId: '21',
|
|
183
|
+
surfaceAiu: 4.94,
|
|
184
|
+
surfaceAue: 8.8,
|
|
185
|
+
enumCfgIsolationLncId: '2',
|
|
186
|
+
label: 'autres dépendances',
|
|
187
|
+
bExpected: 0.75
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
enumTypeAdjacenceId: '22',
|
|
191
|
+
label: "local non déperditif (local à usage d'habitation chauffé)",
|
|
192
|
+
bExpected: 0
|
|
193
|
+
}
|
|
194
|
+
])(
|
|
195
|
+
'$label (id:$enumTypeAdjacenceId)',
|
|
196
|
+
({
|
|
197
|
+
enumTypeAdjacenceId,
|
|
198
|
+
surfaceAiu = undefined,
|
|
199
|
+
surfaceAue = undefined,
|
|
200
|
+
zoneClimatiqueId = undefined,
|
|
201
|
+
enumCfgIsolationLncId = undefined,
|
|
202
|
+
bExpected
|
|
203
|
+
}) => {
|
|
204
|
+
const data = {
|
|
205
|
+
enumTypeAdjacenceId,
|
|
206
|
+
surfaceAiu,
|
|
207
|
+
surfaceAue,
|
|
208
|
+
enumCfgIsolationLncId,
|
|
209
|
+
zoneClimatiqueId
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const b = deperditionMurService.b(data);
|
|
213
|
+
expect(b).toBe(bExpected);
|
|
214
|
+
}
|
|
215
|
+
);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
describe.skip('Benchmark', () => {
|
|
219
|
+
test('reworked', () => {
|
|
220
|
+
const data = {
|
|
221
|
+
enumTypeAdjacenceId: '8',
|
|
222
|
+
surfaceAiu: 2.82,
|
|
223
|
+
surfaceAue: 300,
|
|
224
|
+
enumCfgIsolationLncId: '2',
|
|
225
|
+
label: 'garage'
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
for (let i = 0; i < 1000; i++) {
|
|
229
|
+
const b = deperditionMurService.b(data);
|
|
230
|
+
expect(b).toBe(0.9);
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test('legacy', () => {
|
|
235
|
+
const di = { b: undefined };
|
|
236
|
+
const de = {
|
|
237
|
+
enum_type_adjacence_id: '8',
|
|
238
|
+
surface_aiu: 2.82,
|
|
239
|
+
surface_aue: 300,
|
|
240
|
+
enum_cfg_isolation_lnc_id: '2'
|
|
241
|
+
};
|
|
242
|
+
const du = {};
|
|
243
|
+
const zc = '1';
|
|
244
|
+
|
|
245
|
+
for (let i = 0; i < 1000; i++) {
|
|
246
|
+
b(di, de, du, zc);
|
|
247
|
+
expect(di.b).toBe(0.9);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
describe("Test d'intégration de calcul des deperditions", () => {
|
|
253
|
+
test.each(corpus)('deperditions pour dpe %s', (ademeId) => {
|
|
254
|
+
let dpeRequest = getAdemeFileJson(ademeId);
|
|
255
|
+
dpeRequest = normalizerService.normalize(dpeRequest);
|
|
256
|
+
|
|
257
|
+
/** @type {Contexte} */
|
|
258
|
+
const ctx = contexteBuilder.fromDpe(dpeRequest);
|
|
259
|
+
/** @type {Logement} */
|
|
260
|
+
const logement = dpeRequest.logement;
|
|
261
|
+
/** @type {Deperdition} */
|
|
262
|
+
const deperditions = service.deperditions(ctx, logement);
|
|
263
|
+
|
|
264
|
+
expect(deperditions.deperdition_mur).toBeCloseTo(
|
|
265
|
+
dpeRequest.logement.sortie.deperdition.deperdition_mur,
|
|
266
|
+
1
|
|
267
|
+
);
|
|
268
|
+
expect(deperditions.deperdition_porte).toBeCloseTo(
|
|
269
|
+
dpeRequest.logement.sortie.deperdition.deperdition_porte,
|
|
270
|
+
1
|
|
271
|
+
);
|
|
272
|
+
expect(deperditions.deperdition_plancher_bas).toBeCloseTo(
|
|
273
|
+
dpeRequest.logement.sortie.deperdition.deperdition_plancher_bas,
|
|
274
|
+
1
|
|
275
|
+
);
|
|
276
|
+
expect(deperditions.deperdition_plancher_haut).toBeCloseTo(
|
|
277
|
+
dpeRequest.logement.sortie.deperdition.deperdition_plancher_haut,
|
|
278
|
+
1
|
|
279
|
+
);
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import enums from '../../../../enums.js';
|
|
2
|
+
import { logger } from '../../../../core/util/logger/log-service.js';
|
|
3
|
+
import { inject } from 'dioma';
|
|
4
|
+
import { TvStore } from '../../../dpe/infrastructure/tv.store.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Calcul des déperditions de l’enveloppe GV
|
|
8
|
+
* @see Méthode de calcul 3CL-DPE 2021 (cotobre 2021) chapitre 3
|
|
9
|
+
*/
|
|
10
|
+
export class DeperditionService {
|
|
11
|
+
/**
|
|
12
|
+
* @type {TvStore}
|
|
13
|
+
*/
|
|
14
|
+
tvStore;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param tvStore {TvStore}
|
|
18
|
+
*/
|
|
19
|
+
constructor(tvStore = inject(TvStore)) {
|
|
20
|
+
this.tvStore = tvStore;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Détermination des déperditions pour l'enveloppe concernée
|
|
25
|
+
* @param ctx {Contexte}
|
|
26
|
+
* @param de {DE}
|
|
27
|
+
* @return void
|
|
28
|
+
*/
|
|
29
|
+
/* eslint-disable no-unused-vars */
|
|
30
|
+
execute(ctx, de) {
|
|
31
|
+
throw new Error('Unsupported operation');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Détermination du coefficient de réduction des déperditions b
|
|
36
|
+
* @see Méthode de calcul 3CL-DPE 2021 (cotobre 2021) chapitre 3.1
|
|
37
|
+
*
|
|
38
|
+
* @param d {DeperditionData}
|
|
39
|
+
* @return {number|undefined} Retourne le coefficient de réduction des déperditions b ou undefined si le calcul est impossible
|
|
40
|
+
*/
|
|
41
|
+
b(d) {
|
|
42
|
+
let uVue,
|
|
43
|
+
zc,
|
|
44
|
+
rAiuAue = undefined;
|
|
45
|
+
let enumTypeAdjacenceId = d.enumTypeAdjacenceId;
|
|
46
|
+
|
|
47
|
+
if (
|
|
48
|
+
['8', '9', '11', '12', '13', '14', '15', '16', '17', '18', '19', '21'].includes(
|
|
49
|
+
enumTypeAdjacenceId
|
|
50
|
+
)
|
|
51
|
+
) {
|
|
52
|
+
if (!d.surfaceAue || d.surfaceAue === 0) {
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @see Méthode de calcul 3CL-DPE 2021 (cotobre 2021)
|
|
58
|
+
* chapitre 3.1 Détermination du coefficient de réduction des déperditions b
|
|
59
|
+
* 'Dans le cas de locaux non chauffés non accessibles (mitoyenneté, espace sans accès…), forfaitairement b = 0,95.'
|
|
60
|
+
*/
|
|
61
|
+
if (d.enumCfgIsolationLncId === '1') {
|
|
62
|
+
enumTypeAdjacenceId = undefined;
|
|
63
|
+
} else {
|
|
64
|
+
uVue = this.tvStore.getUVue(enumTypeAdjacenceId) || 0;
|
|
65
|
+
rAiuAue = d.surfaceAiu / d.surfaceAue;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Type d'adjacence 10: 'espace tampon solarisé (véranda,loggia fermée)'
|
|
71
|
+
* Prise en compte de la zone climatique
|
|
72
|
+
*/
|
|
73
|
+
if (['10'].includes(enumTypeAdjacenceId)) {
|
|
74
|
+
if (!d.zoneClimatiqueId) {
|
|
75
|
+
logger.warn(
|
|
76
|
+
`impossible de calculer b pour TypeAdjacenceId:${enumTypeAdjacenceId} sans zone climatique`
|
|
77
|
+
);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
zc = enums.zone_climatique[parseInt(d.zoneClimatiqueId)];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return this.tvStore.getB(enumTypeAdjacenceId, uVue, d.enumCfgIsolationLncId, rAiuAue, zc);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Si Année d'isolation connue alors on prend cette donnée.
|
|
88
|
+
* Sinon
|
|
89
|
+
* Si Année de construction ≤74 alors Année d’isolation = 75-77
|
|
90
|
+
* Sinon Année d’isolation = Année de construction
|
|
91
|
+
*
|
|
92
|
+
* @param enumPeriodeIsolationId {number}
|
|
93
|
+
* @param ctx {Contexte}
|
|
94
|
+
* @return {string} ID de la période d'isolation
|
|
95
|
+
*/
|
|
96
|
+
getEnumPeriodeIsolationId(enumPeriodeIsolationId, ctx) {
|
|
97
|
+
return (
|
|
98
|
+
enumPeriodeIsolationId || Math.max(parseInt(ctx.enumPeriodeConstructionId), 3).toString()
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|