@open3cl/engine 1.0.6 → 1.0.7
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 +95 -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/tv.store.js +389 -0
- package/features/dpe/infrastructure/tv.store.spec.js +690 -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/deperdition-enveloppe.service.js +262 -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 +393 -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,345 @@
|
|
|
1
|
+
import corpus from '../../../../../../test/corpus-sano.json';
|
|
2
|
+
import { getAdemeFileJson } from '../../../../../../test/test-helpers.js';
|
|
3
|
+
import { DeperditionMurService } from './deperdition-mur.service.js';
|
|
4
|
+
import { ContexteBuilder } from '../../contexte.builder.js';
|
|
5
|
+
import { DpeNormalizerService } from '../../../../normalizer/domain/dpe-normalizer.service.js';
|
|
6
|
+
import { TvStore } from '../../../../dpe/infrastructure/tv.store.js';
|
|
7
|
+
import { beforeEach, describe, expect, test } from 'vitest';
|
|
8
|
+
|
|
9
|
+
/** @type {DeperditionMurService} **/
|
|
10
|
+
let service;
|
|
11
|
+
|
|
12
|
+
/** @type {DpeNormalizerService} **/
|
|
13
|
+
let normalizerService;
|
|
14
|
+
|
|
15
|
+
/** @type {ContexteBuilder} **/
|
|
16
|
+
let contexteBuilder;
|
|
17
|
+
|
|
18
|
+
describe('Calcul de déperdition des murs', () => {
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
service = new DeperditionMurService(new TvStore());
|
|
21
|
+
normalizerService = new DpeNormalizerService();
|
|
22
|
+
contexteBuilder = new ContexteBuilder();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('Determination de uMur et uMur0', () => {
|
|
26
|
+
test.each([
|
|
27
|
+
{
|
|
28
|
+
label: 'cas 2187E1039187C mur 1',
|
|
29
|
+
enumMateriauxStructureMurId: '2',
|
|
30
|
+
enumMethodeSaisieUId: '8',
|
|
31
|
+
enumMethodeSaisieU0Id: '2',
|
|
32
|
+
paroiAncienne: false,
|
|
33
|
+
epaisseurStructure: 60,
|
|
34
|
+
enumTypeIsolationId: '9',
|
|
35
|
+
enumTypeDoublageId: '2',
|
|
36
|
+
enumPeriodeConstructionId: '2',
|
|
37
|
+
zoneClimatiqueId: '3',
|
|
38
|
+
umurExpected: 1,
|
|
39
|
+
umur0Expected: 1.8
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
label:
|
|
43
|
+
"(2287E0577966W) Mur 2 Sud, Est, Ouest (p1) - Mur en blocs de béton creux d'épaisseur ≥ 25 cm avec un doublage rapporté donnant sur l'extérieur",
|
|
44
|
+
enumMateriauxStructureMurId: '12',
|
|
45
|
+
enumMethodeSaisieUId: '7',
|
|
46
|
+
enumMethodeSaisieU0Id: '2',
|
|
47
|
+
paroiAncienne: false,
|
|
48
|
+
enumTypeIsolationId: '1',
|
|
49
|
+
enumTypeDoublageId: '4',
|
|
50
|
+
enumPeriodeConstructionId: '1',
|
|
51
|
+
enumIsolationId: '5',
|
|
52
|
+
epaisseurStructure: 25,
|
|
53
|
+
zoneClimatiqueId: '3',
|
|
54
|
+
umurExpected: 0.8, // 0.7 dans le DPE original, mais certainement lié à une erreur
|
|
55
|
+
umur0Expected: 1.55091
|
|
56
|
+
}
|
|
57
|
+
])(
|
|
58
|
+
'$label',
|
|
59
|
+
({
|
|
60
|
+
enumMateriauxStructureMurId,
|
|
61
|
+
enumMethodeSaisieUId,
|
|
62
|
+
enumMethodeSaisieU0Id,
|
|
63
|
+
enumTypeDoublageId,
|
|
64
|
+
enumTypeIsolationId,
|
|
65
|
+
umurSaisi,
|
|
66
|
+
epaisseurStructure,
|
|
67
|
+
paroiAncienne,
|
|
68
|
+
resistanceIsolation,
|
|
69
|
+
umurExpected,
|
|
70
|
+
umur0Expected,
|
|
71
|
+
enumPeriodeConstructionId = 1,
|
|
72
|
+
enumIsolationId,
|
|
73
|
+
effetJoule = false,
|
|
74
|
+
zoneClimatiqueId = '1'
|
|
75
|
+
}) => {
|
|
76
|
+
/** @type {Contexte} */
|
|
77
|
+
const ctx = {
|
|
78
|
+
effetJoule,
|
|
79
|
+
enumPeriodeConstructionId,
|
|
80
|
+
zoneClimatiqueId
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/** @type {MurDE} */
|
|
84
|
+
const de = {
|
|
85
|
+
enum_materiaux_structure_mur_id: enumMateriauxStructureMurId,
|
|
86
|
+
enum_methode_saisie_u_id: enumMethodeSaisieUId,
|
|
87
|
+
enum_methode_saisie_u0_id: enumMethodeSaisieU0Id,
|
|
88
|
+
umur_saisi: umurSaisi,
|
|
89
|
+
resistance_isolation: resistanceIsolation,
|
|
90
|
+
paroi_ancienne: paroiAncienne,
|
|
91
|
+
epaisseur_structure: epaisseurStructure,
|
|
92
|
+
enum_type_doublage_id: enumTypeDoublageId,
|
|
93
|
+
enum_type_isolation_id: enumTypeIsolationId,
|
|
94
|
+
enum_periode_isolation_id: enumIsolationId
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const di = service.execute(ctx, de);
|
|
98
|
+
expect(di.umur0).toBe(umur0Expected);
|
|
99
|
+
expect(di.umur).toBeCloseTo(umurExpected);
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
test("Mur 1 Sud, Est, Ouest (p1) - Mur en blocs de béton pleins d'épaisseur ≤ 20 cm avec isolation intérieure (10 cm) donnant sur l'extérieur", () => {
|
|
104
|
+
/** @type {Contexte} */
|
|
105
|
+
const ctx = {
|
|
106
|
+
effetJoule: false,
|
|
107
|
+
enumPeriodeConstructionId: '6',
|
|
108
|
+
zoneClimatiqueId: '3'
|
|
109
|
+
};
|
|
110
|
+
/** @type {MurDE} */
|
|
111
|
+
const de = {
|
|
112
|
+
enum_materiaux_structure_mur_id: '11',
|
|
113
|
+
enum_methode_saisie_u_id: '3',
|
|
114
|
+
enum_methode_saisie_u0_id: '2',
|
|
115
|
+
paroi_ancienne: false,
|
|
116
|
+
epaisseur_structure: 20,
|
|
117
|
+
enum_type_doublage_id: '2',
|
|
118
|
+
enum_type_isolation_id: '3',
|
|
119
|
+
epaisseur_isolation: 10
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const di = service.execute(ctx, de);
|
|
123
|
+
expect(di.umur0).toBe(2.5);
|
|
124
|
+
expect(di.umur).toBeCloseTo(0.3448275862068969);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('Mur 1 Nord - Mur en pierre de taille et moellons avec remplissage tout venant d'épaisseur 70 cm avec isolation intérieure (10 cm) donnant sur l'extérieur', () => {
|
|
128
|
+
/** @type {Contexte} */
|
|
129
|
+
const ctx = {
|
|
130
|
+
effetJoule: false,
|
|
131
|
+
enumPeriodeConstructionId: '6',
|
|
132
|
+
zoneClimatiqueId: '3'
|
|
133
|
+
};
|
|
134
|
+
/** @type {MurDE} */
|
|
135
|
+
const de = {
|
|
136
|
+
enum_materiaux_structure_mur_id: '3',
|
|
137
|
+
enum_methode_saisie_u_id: '3',
|
|
138
|
+
enum_methode_saisie_u0_id: '2',
|
|
139
|
+
paroi_ancienne: true,
|
|
140
|
+
epaisseur_structure: 70,
|
|
141
|
+
enum_type_doublage_id: '2',
|
|
142
|
+
enum_type_isolation_id: '3',
|
|
143
|
+
epaisseur_isolation: 10
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const di = service.execute(ctx, de);
|
|
147
|
+
expect(di.umur0).toBe(1.45);
|
|
148
|
+
expect(di.umur).toBeCloseTo(0.31351351351351353);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test("(2387E0430619S) Mur 3 Nord, Est (p1) - Mur en placoplatre isolé par l'intérieur (environ 10 cm) avec isolation intérieure donnant sur des circulations avec ouverture directe sur l'extérieur", () => {
|
|
152
|
+
/** @type {Contexte} */
|
|
153
|
+
const ctx = {
|
|
154
|
+
effetJoule: false,
|
|
155
|
+
enumPeriodeConstructionId: '6',
|
|
156
|
+
zoneClimatiqueId: '3'
|
|
157
|
+
};
|
|
158
|
+
/** @type {MurDE} */
|
|
159
|
+
const de = {
|
|
160
|
+
enum_materiaux_structure_mur_id: '23',
|
|
161
|
+
enum_methode_saisie_u_id: '9',
|
|
162
|
+
enum_methode_saisie_u0_id: '5',
|
|
163
|
+
paroi_ancienne: false,
|
|
164
|
+
enum_type_doublage_id: '2',
|
|
165
|
+
enum_type_isolation_id: '3',
|
|
166
|
+
umur_saisi: 0.32
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const di = service.execute(ctx, de);
|
|
170
|
+
expect(di.umur0).toBeUndefined();
|
|
171
|
+
expect(di.umur).toBeCloseTo(0.32);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("Mur 1 Nord, Sud, Ouest (p1) - Mur en pierre de taille et moellons avec remplissage tout venant d'épaisseur 50 cm non isolé donnant sur l'extérieur", () => {
|
|
175
|
+
/** @type {Contexte} */
|
|
176
|
+
const ctx = {
|
|
177
|
+
effetJoule: false,
|
|
178
|
+
enumPeriodeConstructionId: '6',
|
|
179
|
+
zoneClimatiqueId: '3'
|
|
180
|
+
};
|
|
181
|
+
/** @type {MurDE} */
|
|
182
|
+
const de = {
|
|
183
|
+
enum_materiaux_structure_mur_id: '3',
|
|
184
|
+
enum_methode_saisie_u_id: '1',
|
|
185
|
+
enum_methode_saisie_u0_id: '2',
|
|
186
|
+
enduit_isolant_paroi_ancienne: true,
|
|
187
|
+
epaisseur_structure: 50,
|
|
188
|
+
enum_type_doublage_id: '2',
|
|
189
|
+
enum_type_isolation_id: '2'
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const di = service.execute(ctx, de);
|
|
193
|
+
expect(di.umur0).toBeCloseTo(0.81545);
|
|
194
|
+
expect(di.umur).toBeCloseTo(0.81545);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test("Mur 8 Est - Mur en pierre de taille et moellons avec remplissage tout venant d'épaisseur 50 cm avec un doublage rapporté non isolé donnant sur l'extérieur", () => {
|
|
198
|
+
/** @type {Contexte} */
|
|
199
|
+
const ctx = {
|
|
200
|
+
effetJoule: false,
|
|
201
|
+
enumPeriodeConstructionId: '6',
|
|
202
|
+
zoneClimatiqueId: '3'
|
|
203
|
+
};
|
|
204
|
+
/** @type {MurDE} */
|
|
205
|
+
const de = {
|
|
206
|
+
enum_materiaux_structure_mur_id: '3',
|
|
207
|
+
enum_methode_saisie_u_id: '1',
|
|
208
|
+
enum_methode_saisie_u0_id: '2',
|
|
209
|
+
paroi_ancienne: true,
|
|
210
|
+
epaisseur_structure: 50,
|
|
211
|
+
enum_type_doublage_id: '3',
|
|
212
|
+
enum_type_isolation_id: '2'
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
const di = service.execute(ctx, de);
|
|
216
|
+
expect(di.umur0).toBeCloseTo(1.59664);
|
|
217
|
+
expect(di.umur).toBeCloseTo(1.59664);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
test('(2287E0577966W) umur 0.7 au lieu de 0.8', () => {
|
|
221
|
+
/** @type {Contexte} */
|
|
222
|
+
const ctx = {
|
|
223
|
+
effetJoule: true,
|
|
224
|
+
enumPeriodeConstructionId: '1',
|
|
225
|
+
zoneClimatiqueId: '3'
|
|
226
|
+
};
|
|
227
|
+
/** @type {MurDE} */
|
|
228
|
+
const de = {
|
|
229
|
+
enum_materiaux_structure_mur_id: '12',
|
|
230
|
+
enum_methode_saisie_u_id: '7',
|
|
231
|
+
enum_methode_saisie_u0_id: '2',
|
|
232
|
+
paroi_ancienne: false,
|
|
233
|
+
epaisseur_structure: 25,
|
|
234
|
+
enum_type_doublage_id: '4',
|
|
235
|
+
enum_type_isolation_id: '1',
|
|
236
|
+
enum_periode_isolation_id: '5'
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const di = service.execute(ctx, de);
|
|
240
|
+
expect(di.umur0).toBeCloseTo(1.55091);
|
|
241
|
+
expect(di.umur).toBeCloseTo(0.7); // 0.7 dans le DPE d'origine, comme si effet joule
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test("(2387E0430619S) Mur 3 Nord, Est (p1) - Mur en placoplatre isolé par l'intérieur (environ 10 cm) avec isolation intérieure donnant sur des circulations avec ouverture directe sur l'extérieur", () => {
|
|
245
|
+
/** @type {Contexte} */
|
|
246
|
+
const ctx = {
|
|
247
|
+
effetJoule: true,
|
|
248
|
+
enumPeriodeConstructionId: '1',
|
|
249
|
+
zoneClimatiqueId: '3'
|
|
250
|
+
};
|
|
251
|
+
/** @type {MurDE} */
|
|
252
|
+
const de = {
|
|
253
|
+
enum_materiaux_structure_mur_id: '23',
|
|
254
|
+
enum_methode_saisie_u_id: '9',
|
|
255
|
+
enum_methode_saisie_u0_id: '5',
|
|
256
|
+
paroi_ancienne: false,
|
|
257
|
+
umur_saisi: 0.32,
|
|
258
|
+
epaisseur_structure: 25,
|
|
259
|
+
enum_type_doublage_id: '2',
|
|
260
|
+
enum_type_isolation_id: '3'
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const di = service.execute(ctx, de);
|
|
264
|
+
expect(di.umur0).toBeUndefined(); // umur saisie directement
|
|
265
|
+
expect(di.umur).toBeCloseTo(0.32);
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
test('(2287E1724516Y) Mur 4 Nord, Sud (p1) - Mur en pan de bois sans remplissage tout venant d'épaisseur 18 cm avec isolation intérieure (R=2.5m².K/W) donnant sur l'extérieur', () => {
|
|
269
|
+
/** @type {Contexte} */
|
|
270
|
+
const ctx = {
|
|
271
|
+
effetJoule: false,
|
|
272
|
+
enumPeriodeConstructionId: '1',
|
|
273
|
+
zoneClimatiqueId: '3'
|
|
274
|
+
};
|
|
275
|
+
/** @type {MurDE} */
|
|
276
|
+
const de = {
|
|
277
|
+
enum_materiaux_structure_mur_id: '5',
|
|
278
|
+
enum_methode_saisie_u_id: '6',
|
|
279
|
+
enum_methode_saisie_u0_id: '2',
|
|
280
|
+
enduit_isolant_paroi_ancienne: true,
|
|
281
|
+
epaisseur_structure: 18,
|
|
282
|
+
resistance_isolation: 2.5,
|
|
283
|
+
enum_type_doublage_id: '2',
|
|
284
|
+
enum_type_isolation_id: '3'
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
const di = service.execute(ctx, de);
|
|
288
|
+
expect(di.umur0).toBeCloseTo(0.82983999999999991);
|
|
289
|
+
expect(di.umur).toBeCloseTo(0.26990177584075975);
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
test('(2187E0982013C) Mur Nord, Sud, Est, Ouest - Mur en pierre de taille et moellons avec remplissage tout venant d'épaisseur 50 cm non isolé donnant sur l'extérieur', () => {
|
|
293
|
+
/** @type {Contexte} */
|
|
294
|
+
const ctx = {
|
|
295
|
+
effetJoule: false,
|
|
296
|
+
enumPeriodeConstructionId: '1',
|
|
297
|
+
zoneClimatiqueId: '3'
|
|
298
|
+
};
|
|
299
|
+
/** @type {MurDE} */
|
|
300
|
+
const de = {
|
|
301
|
+
enum_type_adjacence_id: '1',
|
|
302
|
+
enum_materiaux_structure_mur_id: '3',
|
|
303
|
+
enum_methode_saisie_u_id: '1',
|
|
304
|
+
enum_methode_saisie_u0_id: '2',
|
|
305
|
+
enduit_isolant_paroi_ancienne: true,
|
|
306
|
+
epaisseur_structure: 18,
|
|
307
|
+
resistance_isolation: 2.5,
|
|
308
|
+
enum_type_doublage_id: '2',
|
|
309
|
+
enum_type_isolation_id: '2'
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
const di = service.execute(ctx, de);
|
|
313
|
+
expect(di.umur0).toBeCloseTo(0.81545);
|
|
314
|
+
expect(di.umur).toBeCloseTo(0.81545);
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
describe("Test d'intégration de mur", () => {
|
|
319
|
+
test.each(corpus)('vérification des DI des murs pour dpe %s', (ademeId) => {
|
|
320
|
+
let dpeRequest = getAdemeFileJson(ademeId);
|
|
321
|
+
dpeRequest = normalizerService.normalize(dpeRequest);
|
|
322
|
+
|
|
323
|
+
/** @type {Contexte} */
|
|
324
|
+
const ctx = contexteBuilder.fromDpe(dpeRequest);
|
|
325
|
+
|
|
326
|
+
const murs = dpeRequest.logement.enveloppe.mur_collection?.mur || [];
|
|
327
|
+
|
|
328
|
+
murs.forEach((m) => {
|
|
329
|
+
// dans ces cas de figure, les données paroi_ancienne sont bien traitées
|
|
330
|
+
if (['2187E0982013C', '2287E2336469P', '2387E0045247S'].includes(ademeId)) {
|
|
331
|
+
m.donnee_entree.enduit_isolant_paroi_ancienne = m.donnee_entree.paroi_ancienne;
|
|
332
|
+
}
|
|
333
|
+
const di = service.execute(ctx, m.donnee_entree);
|
|
334
|
+
|
|
335
|
+
if (m.donnee_intermediaire.umur0) {
|
|
336
|
+
expect(di.umur0).toBeCloseTo(m.donnee_intermediaire.umur0, 2);
|
|
337
|
+
} else {
|
|
338
|
+
expect(di.umur0).toBeUndefined();
|
|
339
|
+
}
|
|
340
|
+
expect(di.umur).toBeCloseTo(m.donnee_intermediaire.umur, 2);
|
|
341
|
+
expect(di.b).toBeCloseTo(m.donnee_intermediaire.b, 2);
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
});
|
|
345
|
+
});
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { inject } from 'dioma';
|
|
2
|
+
import { PRECISION } from '../../constants.js';
|
|
3
|
+
import { DeperditionService } from '../deperdition.service.js';
|
|
4
|
+
import { TvStore } from '../../../../dpe/infrastructure/tv.store.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Calcul des déperditions de l’enveloppe GV
|
|
8
|
+
* Chapitre 3.2.2 Calcul des planchers bas
|
|
9
|
+
*
|
|
10
|
+
* Méthode de calcul 3CL-DPE 2021
|
|
11
|
+
* Octobre 2021
|
|
12
|
+
* @see consolide_anne…arrete_du_31_03_2021_relatif_aux_methodes_et_procedures_applicables.pdf
|
|
13
|
+
*/
|
|
14
|
+
export class DeperditionPlancherBasService extends DeperditionService {
|
|
15
|
+
/**
|
|
16
|
+
* @param tvStore {TvStore}
|
|
17
|
+
*/
|
|
18
|
+
constructor(tvStore = inject(TvStore)) {
|
|
19
|
+
super(tvStore);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param ctx {Contexte}
|
|
24
|
+
* @param pbDE {PlancherBasDE}
|
|
25
|
+
* @param plancherBas {PlancherBas[]}
|
|
26
|
+
* @return {PlancherBasDI}
|
|
27
|
+
*/
|
|
28
|
+
execute(ctx, pbDE, plancherBas) {
|
|
29
|
+
const upb0 = this.#upb0(pbDE);
|
|
30
|
+
const upb = this.#upb(pbDE, upb0, ctx);
|
|
31
|
+
const upb_final = this.#upbFinal(pbDE, upb, ctx, plancherBas);
|
|
32
|
+
const b = this.b({
|
|
33
|
+
enumTypeAdjacenceId: pbDE.enum_type_adjacence_id,
|
|
34
|
+
surfaceAiu: pbDE.surface_aiu,
|
|
35
|
+
surfaceAue: pbDE.surface_aue,
|
|
36
|
+
enumCfgIsolationLncId: pbDE.enum_cfg_isolation_lnc_id,
|
|
37
|
+
zoneClimatiqueId: ctx.zoneClimatiqueId
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
/** @type {PlancherBasDI} */
|
|
41
|
+
return { upb0, upb, upb_final, b };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @param pbDE {PlancherBasDE}
|
|
46
|
+
* @param upb0 {number}
|
|
47
|
+
* @param ctx {Contexte}
|
|
48
|
+
* @return {number|undefined}
|
|
49
|
+
*/
|
|
50
|
+
#upb(pbDE, upb0, ctx) {
|
|
51
|
+
// On determine upb_nu (soit upb0 soit 2 comme valeur minimale forfaitaire)
|
|
52
|
+
const upbNu = Math.min(upb0, 2);
|
|
53
|
+
|
|
54
|
+
const enumPeriodeIsolationId = this.getEnumPeriodeIsolationId(
|
|
55
|
+
pbDE.enum_periode_isolation_id,
|
|
56
|
+
ctx
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
// Selon l'isolation, on applique un calcul au upb nu pour simuler son isolation
|
|
60
|
+
let upb;
|
|
61
|
+
switch (pbDE.enum_methode_saisie_u_id) {
|
|
62
|
+
case '1': // non isolé
|
|
63
|
+
upb = upbNu;
|
|
64
|
+
break;
|
|
65
|
+
case '2': // isolation inconnue (table forfaitaire)
|
|
66
|
+
case '7': // année d'isolation différente de l'année de construction
|
|
67
|
+
case '8': // année de construction saisie
|
|
68
|
+
upb = Math.min(
|
|
69
|
+
upbNu,
|
|
70
|
+
this.tvStore.getUpb(enumPeriodeIsolationId, ctx.zoneClimatiqueId, ctx.effetJoule)
|
|
71
|
+
);
|
|
72
|
+
break;
|
|
73
|
+
case '3': // epaisseur isolation saisie justifiée par mesure ou observation
|
|
74
|
+
case '4': // epaisseur isolation saisie (en cm)
|
|
75
|
+
upb = 1 / (1 / upbNu + (pbDE.epaisseur_isolation * 0.01) / 0.042);
|
|
76
|
+
break;
|
|
77
|
+
case '5':
|
|
78
|
+
case '6': // resistance isolation saisie
|
|
79
|
+
upb = 1 / (1 / upbNu + pbDE.resistance_isolation);
|
|
80
|
+
break;
|
|
81
|
+
default: // saisie direct de la valeur de u
|
|
82
|
+
upb = pbDE.upb_saisi;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return Math.round(parseFloat(upb) * PRECISION) / PRECISION;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @param pbDE {PlancherBasDE}
|
|
91
|
+
* @return {number|undefined}
|
|
92
|
+
*/
|
|
93
|
+
#upb0(pbDE) {
|
|
94
|
+
let upb0;
|
|
95
|
+
switch (pbDE.enum_methode_saisie_u0_id) {
|
|
96
|
+
case '1': // 'type de paroi inconnu (valeur par défaut)'
|
|
97
|
+
case '2': // 'déterminé selon le matériau et épaisseur à partir de la table de valeur forfaitaire'
|
|
98
|
+
upb0 = this.tvStore.getUpb0(pbDE.enum_type_plancher_bas_id);
|
|
99
|
+
break;
|
|
100
|
+
case '5': // 'u0 non saisi car le u est saisi connu et justifié.'
|
|
101
|
+
return;
|
|
102
|
+
default: // Valeur saisie
|
|
103
|
+
return pbDE.upb0_saisi;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return upb0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Pour les vides sanitaires, les sous-sol non chauffés et terre-plein, le calcul des déperditions se fait avec un coefficient
|
|
111
|
+
* Ue en remplacement de Upb.
|
|
112
|
+
*
|
|
113
|
+
* @param pbDE {PlancherBasDE}
|
|
114
|
+
* @param upb {number}
|
|
115
|
+
* @param ctx {Contexte}
|
|
116
|
+
* @param plancherBas {PlancherBas[]}
|
|
117
|
+
* @return {number|undefined}
|
|
118
|
+
*/
|
|
119
|
+
#upbFinal(pbDE, upb, ctx, plancherBas) {
|
|
120
|
+
if (pbDE.calcul_ue === 1) {
|
|
121
|
+
return pbDE.ue;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* 3 - vide sanitaire
|
|
126
|
+
* 5 - terre-plein
|
|
127
|
+
* 6 - sous-sol non chauffé
|
|
128
|
+
*/
|
|
129
|
+
if (!['3', '5', '6'].includes(pbDE.enum_type_adjacence_id)) {
|
|
130
|
+
return upb;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* La surface Ue est la surface de tous les planchers bas ayant le même type d'adjacence
|
|
135
|
+
* Le périmètre Ue est le périmètre de tous les planchers bas ayant le même type d'adjacence
|
|
136
|
+
*/
|
|
137
|
+
const { surfaceUe, perimetreUe } = plancherBas
|
|
138
|
+
.filter(
|
|
139
|
+
(plancherBas) =>
|
|
140
|
+
pbDE.enum_type_adjacence_id === plancherBas.donnee_entree.enum_type_adjacence_id
|
|
141
|
+
)
|
|
142
|
+
.reduce(
|
|
143
|
+
(acc, plancherBas) => {
|
|
144
|
+
acc.surfaceUe +=
|
|
145
|
+
plancherBas.donnee_entree.surface_ue || plancherBas.donnee_entree.surface_paroi_opaque;
|
|
146
|
+
acc.perimetreUe += plancherBas.donnee_entree.perimetre_ue || 0;
|
|
147
|
+
return acc;
|
|
148
|
+
},
|
|
149
|
+
{ surfaceUe: 0, perimetreUe: 0 }
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
const available2sp = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20];
|
|
153
|
+
let dsp = perimetreUe ? Math.round((2 * surfaceUe) / perimetreUe) : 1;
|
|
154
|
+
|
|
155
|
+
// Recherche de la valeur la plus proche dans les valeurs disponibles
|
|
156
|
+
dsp = available2sp.reduce((prev, curr) => {
|
|
157
|
+
return Math.abs(curr - dsp) < Math.abs(prev - dsp) ? curr : prev;
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const upbFinal = this.tvStore.getUeByUpd(
|
|
161
|
+
pbDE.enum_type_adjacence_id,
|
|
162
|
+
ctx.enumPeriodeConstructionId,
|
|
163
|
+
dsp,
|
|
164
|
+
upb
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
return Math.round(parseFloat(upbFinal) * PRECISION) / PRECISION;
|
|
168
|
+
}
|
|
169
|
+
}
|