@open3cl/engine 1.7.0 → 1.7.1

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 (48) hide show
  1. package/10_besoin_fr.spec.js +1 -0
  2. package/10_clim.spec.js +1 -0
  3. package/11_besoin_ecs.spec.js +1 -0
  4. package/11_ecs.spec.js +1 -0
  5. package/12.4_pac.spec.js +1 -0
  6. package/13.2_generateur_combustion.spec.js +3 -3
  7. package/13.2_generateur_combustion_ch.spec.js +3 -3
  8. package/14_generateur_ecs.spec.js +1 -0
  9. package/15_conso_aux.spec.js +3 -3
  10. package/2021_04_13_confort_ete.spec.js +1 -0
  11. package/3.1_b.spec.js +1 -0
  12. package/3.2.1_mur.spec.js +1 -0
  13. package/3.2.2_plancher_bas.spec.js +1 -0
  14. package/3.2.3_plancher_haut.spec.js +1 -0
  15. package/3.3.1.4_porte.spec.js +1 -0
  16. package/3.3_baie_vitree.spec.js +1 -0
  17. package/3.4_pont_thermique.spec.js +1 -0
  18. package/4_ventilation.spec.js +1 -0
  19. package/5_conso_ventilation.spec.js +1 -0
  20. package/6.2_surface_sud_equivalente.spec.js +1 -0
  21. package/9_besoin_ch.spec.js +1 -0
  22. package/9_chauffage.spec.js +3 -3
  23. package/9_conso_ch.spec.js +1 -0
  24. package/9_emetteur_ch.spec.js +1 -0
  25. package/9_generateur_ch.spec.js +1 -0
  26. package/README.md +412 -291
  27. package/conso.spec.js +1 -0
  28. package/engine.js +3 -1
  29. package/engine.spec.js +1 -0
  30. package/package.json +15 -14
  31. package/features/engine/domain/apport_et_besoin/apport-et-besoin.service.spec.js +0 -222
  32. package/features/engine/domain/apport_et_besoin/ch/perte-ch-recup.service.spec.js +0 -345
  33. package/features/engine/domain/apport_et_besoin/ecs/besoin-ecs.service.spec.js +0 -87
  34. package/features/engine/domain/apport_et_besoin/ecs/perte-ecs-recup.service.spec.js +0 -260
  35. package/features/engine/domain/apport_et_besoin/froid/besoin-froid.service.spec.js +0 -272
  36. package/features/engine/domain/apport_et_besoin/surface-sud-equivalente.service.spec.js +0 -231
  37. package/features/engine/domain/ch/generateur-ch.service.spec.js +0 -849
  38. package/features/engine/domain/conso/froid/conso-froid.service.spec.js +0 -233
  39. package/features/engine/domain/ecs/installation-ecs.service.spec.js +0 -337
  40. package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.spec.js +0 -607
  41. package/features/engine/domain/enveloppe/deperdition-enveloppe.service.spec.js +0 -550
  42. package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.spec.js +0 -82
  43. package/features/engine/domain/enveloppe/mur/deperdition-mur.service.spec.js +0 -542
  44. package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +0 -430
  45. package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.spec.js +0 -411
  46. package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.spec.js +0 -653
  47. package/features/engine/domain/enveloppe/porte/deperdition-porte.service.spec.js +0 -117
  48. package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.spec.js +0 -508
@@ -1,849 +0,0 @@
1
- import { beforeEach, describe, expect, test, vi } from 'vitest';
2
- import { GenerateurChService } from './generateur-ch.service.js';
3
-
4
- import { DpeNormalizerService } from '../../../normalizer/domain/dpe-normalizer.service.js';
5
- import corpus from '../../../../../test/corpus-sano.json';
6
- import { getAdemeFileJson } from '../../../../../test/test-helpers.js';
7
- import { TypeGenerateur } from '../../../dpe/domain/models/type-generateur.model.js';
8
- import { ChTvStore } from '../../../dpe/infrastructure/ch/chTv.store.js';
9
- import { ContexteBuilder } from '../contexte.builder.js';
10
- import { TvStore } from '../../../dpe/infrastructure/tv.store.js';
11
- import { EmetteurChService } from './emetteur-ch.service.js';
12
- import { describeIntegration } from '../../../../../test/helpers/integration-test.js';
13
-
14
- /** @type {GenerateurChService} **/
15
- let service;
16
-
17
- /** @type {EmetteurChService} **/
18
- let emetteurChService;
19
-
20
- /** @type {ChTvStore} **/
21
- let chTvStore;
22
-
23
- /** @type {TvStore} **/
24
- let tvStore;
25
-
26
- /** @type {DpeNormalizerService} **/
27
- let normalizerService;
28
-
29
- /** @type {ContexteBuilder} **/
30
- let contexteBuilder;
31
-
32
- describe('Calcul des caractéristiques des générateurs de chauffage', () => {
33
- beforeEach(() => {
34
- chTvStore = new ChTvStore();
35
- tvStore = new TvStore();
36
- emetteurChService = new EmetteurChService(chTvStore);
37
- service = new GenerateurChService(chTvStore, tvStore, emetteurChService);
38
- normalizerService = new DpeNormalizerService();
39
- contexteBuilder = new ContexteBuilder();
40
- });
41
-
42
- test.each([
43
- {
44
- label: 'Générateur chauffage avec méthode de saisie 4',
45
- enumMethodeSaisieCaracSysId: 4,
46
- ratioVirtualisation: 1,
47
- pn: 25000,
48
- qp0Perc: '0.05%',
49
- qp0Initial: 125,
50
- expected: 125
51
- },
52
- {
53
- label: 'Générateur chauffage avec méthode de saisie 5',
54
- enumMethodeSaisieCaracSysId: 5,
55
- ratioVirtualisation: 1,
56
- pn: 25000,
57
- qp0Perc: '0.05%',
58
- qp0Initial: 125,
59
- expected: 125
60
- },
61
- {
62
- label: 'Générateur chauffage avec méthode de saisie 3 et aucun qp0Perc',
63
- enumMethodeSaisieCaracSysId: 3,
64
- ratioVirtualisation: 1,
65
- pn: 25000,
66
- qp0Perc: undefined,
67
- qp0Initial: 125,
68
- expected: 0
69
- },
70
- {
71
- label:
72
- 'Générateur chauffage avec méthode de saisie 3 et qp0Perc contenant Pn, ratio de virtualisation 1',
73
- enumMethodeSaisieCaracSysId: 3,
74
- ratioVirtualisation: 1,
75
- pn: 25000,
76
- qp0Perc: '0,085*Pn*(Pn)^-0,4',
77
- qp0Initial: 125,
78
- expected: 586.39
79
- },
80
- {
81
- label:
82
- 'Générateur chauffage avec méthode de saisie 3 et qp0Perc contenant Pn, ratio de virtualisation 0.5',
83
- enumMethodeSaisieCaracSysId: 3,
84
- ratioVirtualisation: 0.5,
85
- pn: 25000,
86
- qp0Perc: '0,085*Pn*(Pn)^-0,4',
87
- qp0Initial: 125,
88
- expected: 444.4
89
- },
90
- {
91
- label:
92
- 'Générateur chauffage avec méthode de saisie 3 et qp0Perc en %, ratio de virtualisation 1',
93
- enumMethodeSaisieCaracSysId: 3,
94
- ratioVirtualisation: 1,
95
- pn: 25000,
96
- qp0Perc: '0.6%',
97
- qp0Initial: 125,
98
- expected: 150
99
- },
100
- {
101
- label:
102
- 'Générateur chauffage avec méthode de saisie 3 et qp0Perc constante, ratio de virtualisation 1',
103
- enumMethodeSaisieCaracSysId: 3,
104
- ratioVirtualisation: 1,
105
- pn: 25000,
106
- qp0Perc: '12',
107
- qp0Initial: 125,
108
- expected: 12000
109
- },
110
- {
111
- label:
112
- 'Générateur chauffage avec méthode de saisie 3 et qp0Perc contenant Pn, E et F, ratio de virtualisation 0.5, sans ventouse',
113
- enumMethodeSaisieCaracSysId: 3,
114
- presenceVentouse: 0,
115
- ratioVirtualisation: 0.5,
116
- pn: 25000,
117
- qp0Perc: 'Pn * (E + F * logPn) / 100',
118
- qp0Initial: 125,
119
- expected: 285.21
120
- },
121
- {
122
- label:
123
- 'Générateur chauffage avec méthode de saisie 3 et qp0Perc contenant Pn, E et F, ratio de virtualisation 0.5, avec ventouse',
124
- enumMethodeSaisieCaracSysId: 3,
125
- presenceVentouse: 1,
126
- ratioVirtualisation: 0.5,
127
- pn: 25000,
128
- qp0Perc: 'Pn * (E + F * logPn) / 100',
129
- qp0Initial: 125,
130
- expected: 203.89
131
- }
132
- ])(
133
- "Détermination des pertes à l'arrêt qp0 pour $label",
134
- ({
135
- enumMethodeSaisieCaracSysId,
136
- ratioVirtualisation,
137
- pn,
138
- qp0Perc,
139
- qp0Initial,
140
- presenceVentouse = undefined,
141
- expected
142
- }) => {
143
- /** @type {GenerateurChauffage} */
144
- const generateurChauffage = {
145
- donnee_entree: {
146
- enum_methode_saisie_carac_sys_id: enumMethodeSaisieCaracSysId,
147
- presence_ventouse: presenceVentouse
148
- },
149
- donnee_utilisateur: {
150
- ratio_virtualisation: ratioVirtualisation,
151
- generateur: { qp0_perc: qp0Perc }
152
- },
153
- donnee_intermediaire: { qp0: qp0Initial, pn }
154
- };
155
-
156
- expect(service.qp0(generateurChauffage)).toBeCloseTo(expected, 2);
157
- }
158
- );
159
-
160
- test.each([
161
- {
162
- label: 'Générateur chauffage avec méthode de saisie 3',
163
- enumMethodeSaisieCaracSysId: 3,
164
- ratioVirtualisation: 1,
165
- pn: 25000,
166
- rpn: '84 + 2 logPn',
167
- rpint: '80 + 3 logPn',
168
- rpnInitial: 0.95,
169
- rpintInitial: 0.69,
170
- expected: { rpn: 0.95, rpint: 0.69 }
171
- },
172
- {
173
- label: 'Générateur chauffage avec méthode de saisie 4',
174
- enumMethodeSaisieCaracSysId: 4,
175
- ratioVirtualisation: 1,
176
- pn: 25000,
177
- rpn: '84 + 2 logPn',
178
- rpint: '80 + 3 logPn',
179
- rpnInitial: 0.95,
180
- rpintInitial: 0.69,
181
- expected: { rpn: 0.95, rpint: 0.69 }
182
- },
183
- {
184
- label: 'Générateur chauffage avec méthode de saisie 5',
185
- enumMethodeSaisieCaracSysId: 5,
186
- ratioVirtualisation: 1,
187
- pn: 25000,
188
- rpn: '84 + 2 logPn',
189
- rpint: '80 + 3 logPn',
190
- rpnInitial: 0.95,
191
- rpintInitial: 0.69,
192
- expected: { rpn: 0.95, rpint: 0.69 }
193
- },
194
- {
195
- label: 'Générateur chauffage avec méthodes de saisie 2 et aucun rpn ni rpint',
196
- enumMethodeSaisieCaracSysId: 2,
197
- ratioVirtualisation: 1,
198
- pn: 25000,
199
- rpn: undefined,
200
- rpint: undefined,
201
- rpnInitial: 0.95,
202
- rpintInitial: 0.69,
203
- expected: { rpn: 0, rpint: 0 }
204
- },
205
- {
206
- label: 'Générateur chauffage avec méthodes de saisie 2 et ratio de virtualisation 1',
207
- enumMethodeSaisieCaracSysId: 2,
208
- ratioVirtualisation: 1,
209
- pn: 25000,
210
- rpn: '84 + 2 logPn',
211
- rpint: '80 + 3 logPn',
212
- rpnInitial: 0.95,
213
- rpintInitial: 0.69,
214
- expected: { rpn: 0.8679588001734407, rpint: 0.8419382002601611 }
215
- },
216
- {
217
- label: 'Générateur chauffage avec méthodes de saisie 2 et ratio de virtualisation 0.5',
218
- enumMethodeSaisieCaracSysId: 2,
219
- ratioVirtualisation: 0.5,
220
- pn: 25000,
221
- rpn: '84 + 2 logPn',
222
- rpint: '80 + 3 logPn',
223
- rpnInitial: 0.95,
224
- rpintInitial: 0.69,
225
- expected: { rpn: 0.8739794000867204, rpint: 0.8509691001300805 }
226
- }
227
- ])(
228
- 'Détermination des rendements rpn et rpint pour $label',
229
- ({
230
- enumMethodeSaisieCaracSysId,
231
- ratioVirtualisation,
232
- pn,
233
- rpn,
234
- rpint,
235
- rpnInitial,
236
- rpintInitial,
237
- expected
238
- }) => {
239
- /** @type {GenerateurChauffage} */
240
- const generateurChauffage = {
241
- donnee_entree: { enum_methode_saisie_carac_sys_id: enumMethodeSaisieCaracSysId },
242
- donnee_utilisateur: {
243
- ratio_virtualisation: ratioVirtualisation,
244
- generateur: { rpn, rpint }
245
- },
246
- donnee_intermediaire: { rpn: rpnInitial, rpint: rpintInitial, pn }
247
- };
248
-
249
- expect(service.rpnrpint(generateurChauffage)).toStrictEqual(expected);
250
- }
251
- );
252
-
253
- test.each([
254
- {
255
- label: 'Générateur chauffage avec méthode de saisie 2 et pveilleuse',
256
- enumMethodeSaisieCaracSysId: 2,
257
- pveilleuseInitial: 150,
258
- pveil: 250,
259
- expected: 150
260
- },
261
- {
262
- label: 'Générateur chauffage avec méthode de saisie 2 et !pveilleuse',
263
- enumMethodeSaisieCaracSysId: 2,
264
- pveil: 250,
265
- expected: 250
266
- },
267
- {
268
- label: 'Générateur chauffage avec méthode de saisie 1 et pveilleuse',
269
- enumMethodeSaisieCaracSysId: 1,
270
- pveilleuseInitial: 150,
271
- pveil: 250,
272
- expected: 250
273
- }
274
- ])(
275
- 'Détermination de la puissance de la veilleuse pour $label',
276
- ({ enumMethodeSaisieCaracSysId, pveilleuseInitial, pveil, expected }) => {
277
- /** @type {GenerateurChauffage} */
278
- const generateurChauffage = {
279
- donnee_entree: { enum_methode_saisie_carac_sys_id: enumMethodeSaisieCaracSysId },
280
- donnee_utilisateur: { generateur: { pveil } },
281
- donnee_intermediaire: { pveilleuse: pveilleuseInitial }
282
- };
283
-
284
- expect(service.pveil(generateurChauffage)).toStrictEqual(expected);
285
- }
286
- );
287
-
288
- test.each([
289
- {
290
- label:
291
- 'Générateur chauffage avec méthode de saisie 5 mais pas de temp_fonc_30 ni temp_fonc_100',
292
- enumMethodeSaisieCaracSysId: 5,
293
- emetteurServiceCalled: true,
294
- expected: { temp_fonc_30: 18, temp_fonc_100: 25 }
295
- },
296
- {
297
- label: 'Générateur chauffage avec méthode de saisie 5 mais pas de temp_fonc_30',
298
- enumMethodeSaisieCaracSysId: 5,
299
- tempFonc100Initial: 38,
300
- emetteurServiceCalled: true,
301
- expected: { temp_fonc_30: 18, temp_fonc_100: 25 }
302
- },
303
- {
304
- label: 'Générateur chauffage avec méthode de saisie 5 mais pas de temp_fonc_100',
305
- enumMethodeSaisieCaracSysId: 5,
306
- tempFonc30Initial: 25,
307
- emetteurServiceCalled: true,
308
- expected: { temp_fonc_30: 18, temp_fonc_100: 25 }
309
- },
310
- {
311
- label: 'Générateur chauffage avec méthode de saisie 4 avec temp_fonc_30 et temp_fonc_100',
312
- enumMethodeSaisieCaracSysId: 4,
313
- tempFonc30Initial: 25,
314
- tempFonc100Initial: 38,
315
- emetteurServiceCalled: true,
316
- expected: { temp_fonc_30: 18, temp_fonc_100: 25 }
317
- },
318
- {
319
- label: 'Générateur chauffage avec méthode de saisie 5 avec temp_fonc_30 et temp_fonc_100',
320
- enumMethodeSaisieCaracSysId: 5,
321
- tempFonc30Initial: 25,
322
- tempFonc100Initial: 38,
323
- emetteurServiceCalled: false,
324
- expected: { temp_fonc_30: 25, temp_fonc_100: 38 }
325
- }
326
- ])(
327
- 'Détermination des températures de fonctionnement à 30% et 100% de charge pour $label',
328
- ({
329
- enumMethodeSaisieCaracSysId,
330
- tempFonc30Initial = undefined,
331
- tempFonc100Initial = undefined,
332
- emetteurServiceCalled,
333
- expected
334
- }) => {
335
- vi.spyOn(emetteurChService, 'temperatureFonctionnement').mockReturnValue({
336
- temp_fonc_30: 18,
337
- temp_fonc_100: 25
338
- });
339
-
340
- /** @type {GenerateurChauffage} */
341
- const generateurChauffage = {
342
- donnee_entree: { enum_methode_saisie_carac_sys_id: enumMethodeSaisieCaracSysId },
343
- donnee_intermediaire: { temp_fonc_100: tempFonc100Initial, temp_fonc_30: tempFonc30Initial }
344
- };
345
-
346
- /** @type {EmetteurChauffage[]} */
347
- const emetteursChauffage = [
348
- {
349
- donnee_entree: { surface_chauffee: 80 },
350
- donnee_intermediaire: { rendement_emission: 0.86 }
351
- }
352
- ];
353
-
354
- /** @type {Contexte} */
355
- const contexte = { altitude: { id: 1 }, zoneClimatique: { id: 1 } };
356
-
357
- expect(
358
- service.temperatureFonctionnement(contexte, generateurChauffage, emetteursChauffage)
359
- ).toStrictEqual(expected);
360
-
361
- if (emetteurServiceCalled) {
362
- expect(emetteurChService.temperatureFonctionnement).toHaveBeenCalledWith(
363
- contexte,
364
- generateurChauffage.donnee_entree,
365
- emetteursChauffage
366
- );
367
- } else {
368
- expect(emetteurChService.temperatureFonctionnement).not.toHaveBeenCalled();
369
- }
370
- }
371
- );
372
-
373
- test('Détermination de la puissance nominale pour un générateur de chauffage', () => {
374
- vi.spyOn(tvStore, 'getTempBase').mockReturnValue(-9.5);
375
-
376
- /** @type {Contexte} */
377
- const contexte = { altitude: { id: 1 }, zoneClimatique: { id: 1 } };
378
-
379
- /** @type {Logement} **/
380
- const logement = { sortie: { deperdition: { deperdition_enveloppe: 1134 } } };
381
-
382
- expect(service.pn(contexte, logement)).toBeCloseTo(45234.35, 2);
383
- expect(tvStore.getTempBase).toHaveBeenCalledWith(1, 1);
384
- });
385
-
386
- test('Détermination du type de générateur de chauffage', () => {
387
- expect(service.typeGenerateur({ enum_type_generateur_ch_id: 1 })).toBe(TypeGenerateur.OTHER);
388
- [
389
- 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
390
- 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 148, 149, 150, 151, 160, 161
391
- ].forEach((value) =>
392
- expect(service.typeGenerateur({ enum_type_generateur_ch_id: value })).toBe(
393
- TypeGenerateur.CHAUDIERE
394
- )
395
- );
396
- });
397
-
398
- test('Détermination des caractéristiques pour le générateur de chauffage', () => {
399
- vi.spyOn(emetteurChService, 'temperatureFonctionnement').mockReturnValue({
400
- temp_fonc_30: 18,
401
- temp_fonc_100: 25
402
- });
403
-
404
- /** @type {GenerateurChauffage} */
405
- const generateurChauffage = {
406
- donnee_entree: { enum_methode_saisie_carac_sys_id: 5, presence_ventouse: 1 },
407
- donnee_utilisateur: {
408
- ratio_virtualisation: 1,
409
- typeGenerateur: TypeGenerateur.CHAUDIERE,
410
- generateur: {
411
- qp0_perc: 'Pn * (E + F * logPn) / 100',
412
- rpn: '84 + 2 logPn',
413
- rpint: '80 + 3 logPn',
414
- pveil: 250
415
- }
416
- },
417
- donnee_intermediaire: {
418
- rpn: 0.95,
419
- rpint: 0.68,
420
- qp0: 125,
421
- pn: 15000,
422
- temp_fonc_30: 18,
423
- temp_fonc_100: 25
424
- }
425
- };
426
-
427
- /** @type {EmetteurChauffage[]} */
428
- const emetteursChauffage = [
429
- {
430
- donnee_entree: { surface_chauffee: 80 },
431
- donnee_intermediaire: { rendement_emission: 0.86 }
432
- }
433
- ];
434
-
435
- /** @type {Contexte} */
436
- const contexte = { altitude: { id: 1 }, zoneClimatique: { id: 1 } };
437
-
438
- expect(
439
- service.caracteristiques(contexte, generateurChauffage, emetteursChauffage)
440
- ).toStrictEqual({
441
- pveil: 250,
442
- qp0: 125,
443
- rpint: 0.68,
444
- rpn: 0.95,
445
- temp_fonc_100: 25,
446
- temp_fonc_30: 18
447
- });
448
- });
449
-
450
- describe('Détermination des caractéristiques du générateur', () => {
451
- let generateurChauffage;
452
- let installationChauffage;
453
- let logement;
454
- let ctx;
455
-
456
- beforeEach(() => {
457
- vi.spyOn(chTvStore, 'getCombustionGenerateurs').mockReturnValue([1, 76]);
458
- vi.spyOn(chTvStore, 'getPacGenerateurs').mockReturnValue([2]);
459
- vi.spyOn(chTvStore, 'getGenerateurCombustion').mockReturnValue({});
460
-
461
- /** @type {GenerateurChauffage} */
462
- generateurChauffage = {
463
- donnee_entree: {
464
- enum_methode_saisie_carac_sys_id: 4,
465
- enum_type_generateur_ch_id: 3,
466
- presence_ventouse: 1
467
- },
468
- donnee_intermediaire: {
469
- rpn: 0.95,
470
- rpint: 0.68,
471
- qp0: 125,
472
- pn: 15000,
473
- temp_fonc_30: 25,
474
- temp_fonc_100: 36
475
- }
476
- };
477
-
478
- installationChauffage = {
479
- donnee_entree: { ratio_virtualisation: 0.8 },
480
- generateur_chauffage_collection: {
481
- generateur_chauffage: [generateurChauffage]
482
- }
483
- };
484
-
485
- /** @type {Logement} */
486
- logement = {
487
- installation_chauffage_collection: { installation_chauffage: [installationChauffage] }
488
- };
489
-
490
- /** @type {Contexte} */
491
- ctx = {
492
- zoneClimatique: { id: 1 }
493
- };
494
- });
495
-
496
- test('Générateur autre que combustion ou chaudière', () => {
497
- service.execute(ctx, logement, installationChauffage);
498
- expect(chTvStore.getGenerateurCombustion).not.toHaveBeenCalled();
499
- expect(
500
- installationChauffage.generateur_chauffage_collection.generateur_chauffage[0]
501
- .donnee_utilisateur
502
- ).toStrictEqual({
503
- combustion: false,
504
- pac: false,
505
- ratio_virtualisation: 0.8,
506
- typeGenerateur: TypeGenerateur.OTHER
507
- });
508
- });
509
-
510
- test('Détermination des caractéristiques du générateur à combustion', () => {
511
- installationChauffage.generateur_chauffage_collection.generateur_chauffage[0].donnee_entree.enum_type_generateur_ch_id = 1;
512
- service.execute(ctx, logement, installationChauffage);
513
- expect(chTvStore.getGenerateurCombustion).toHaveBeenCalledWith(1, 18.75);
514
- expect(
515
- installationChauffage.generateur_chauffage_collection.generateur_chauffage[0]
516
- .donnee_utilisateur
517
- ).toStrictEqual({
518
- combustion: true,
519
- pac: false,
520
- generateur: {},
521
- ratio_virtualisation: 0.8,
522
- typeGenerateur: TypeGenerateur.OTHER
523
- });
524
- expect(
525
- installationChauffage.generateur_chauffage_collection.generateur_chauffage[0]
526
- .donnee_intermediaire
527
- ).toStrictEqual({
528
- pn: 15000,
529
- pveil: 0,
530
- qp0: 125,
531
- rpint: 0.68,
532
- rpn: 0.95,
533
- temp_fonc_100: 36,
534
- temp_fonc_30: 25
535
- });
536
- });
537
-
538
- test('Détermination des caractéristiques du générateur à combustion de type chaudière', () => {
539
- installationChauffage.generateur_chauffage_collection.generateur_chauffage[0].donnee_entree.enum_type_generateur_ch_id = 76;
540
- installationChauffage.generateur_chauffage_collection.generateur_chauffage[0].donnee_entree.enum_methode_saisie_carac_sys_id = 5;
541
- service.execute(ctx, logement, installationChauffage);
542
- expect(
543
- installationChauffage.generateur_chauffage_collection.generateur_chauffage[0]
544
- .donnee_utilisateur
545
- ).toStrictEqual({
546
- combustion: true,
547
- pac: false,
548
- generateur: {},
549
- ratio_virtualisation: 0.8,
550
- typeGenerateur: TypeGenerateur.CHAUDIERE
551
- });
552
- expect(
553
- installationChauffage.generateur_chauffage_collection.generateur_chauffage[0]
554
- .donnee_intermediaire
555
- ).toStrictEqual({
556
- pn: 15000,
557
- pveil: 0,
558
- qp0: 125,
559
- rpint: 0.68,
560
- rpn: 0.95,
561
- temp_fonc_100: 36,
562
- temp_fonc_30: 25
563
- });
564
- });
565
- });
566
-
567
- test('Générateur à combustion sans pn : calcul de la puissance nominale et filtrage des émetteurs', () => {
568
- // Type 76 (chaudière fioul) : générateur à combustion ET chaudière, pour que le calcul
569
- // des températures de fonctionnement (utilisant les émetteurs filtrés) soit exécuté.
570
- vi.spyOn(chTvStore, 'getCombustionGenerateurs').mockReturnValue([76]);
571
- vi.spyOn(chTvStore, 'getPacGenerateurs').mockReturnValue([2]);
572
- vi.spyOn(chTvStore, 'getGenerateurCombustion').mockReturnValue({});
573
- // pn absent dans donnee_intermediaire -> execute doit appeler this.pn(ctx, logement).
574
- const pnSpy = vi.spyOn(service, 'pn').mockReturnValue(20000);
575
- vi.spyOn(emetteurChService, 'temperatureFonctionnement').mockReturnValue({
576
- temp_fonc_30: 18,
577
- temp_fonc_100: 25
578
- });
579
-
580
- /** @type {GenerateurChauffage} */
581
- const generateurChauffage = {
582
- donnee_entree: {
583
- enum_methode_saisie_carac_sys_id: 4,
584
- enum_type_generateur_ch_id: 76,
585
- enum_lien_generateur_emetteur_id: 'L1',
586
- presence_ventouse: 1
587
- },
588
- // pas de pn : oblige au calcul de la puissance nominale
589
- donnee_intermediaire: { rpn: 0.95, rpint: 0.68, qp0: 125 }
590
- };
591
-
592
- // Deux émetteurs : un seul est lié au générateur (même enum_lien_generateur_emetteur_id).
593
- const emetteurLie = {
594
- donnee_entree: { enum_lien_generateur_emetteur_id: 'L1', surface_chauffee: 80 },
595
- donnee_intermediaire: { rendement_emission: 0.86 }
596
- };
597
- const emetteurNonLie = {
598
- donnee_entree: { enum_lien_generateur_emetteur_id: 'L2', surface_chauffee: 40 },
599
- donnee_intermediaire: { rendement_emission: 0.9 }
600
- };
601
-
602
- const installationChauffage = {
603
- donnee_entree: { ratio_virtualisation: 1 },
604
- generateur_chauffage_collection: { generateur_chauffage: [generateurChauffage] },
605
- emetteur_chauffage_collection: { emetteur_chauffage: [emetteurLie, emetteurNonLie] }
606
- };
607
-
608
- /** @type {Logement} */
609
- const logement = {
610
- installation_chauffage_collection: { installation_chauffage: [installationChauffage] },
611
- sortie: { deperdition: { deperdition_enveloppe: 300 } }
612
- };
613
-
614
- /** @type {Contexte} */
615
- const ctx = { altitude: { id: 1 }, zoneClimatique: { id: 1 } };
616
-
617
- service.execute(ctx, logement, installationChauffage);
618
-
619
- // La puissance nominale a été calculée puis affectée
620
- expect(pnSpy).toHaveBeenCalledWith(ctx, logement);
621
- expect(generateurChauffage.donnee_intermediaire.pn).toBe(20000);
622
-
623
- // getGenerateurCombustion utilise pn / (ratio * 1000) = 20000 / 1000 = 20
624
- expect(chTvStore.getGenerateurCombustion).toHaveBeenCalledWith(76, 20);
625
-
626
- // Seul l'émetteur lié est transmis au calcul des températures de fonctionnement
627
- expect(emetteurChService.temperatureFonctionnement).toHaveBeenCalledWith(
628
- ctx,
629
- generateurChauffage.donnee_entree,
630
- [emetteurLie]
631
- );
632
- });
633
-
634
- test('execute : installation sans collection de générateurs ne fait rien', () => {
635
- // Valeur de repli [] quand generateur_chauffage_collection est absente.
636
- const combustionSpy = vi.spyOn(chTvStore, 'getCombustionGenerateurs');
637
-
638
- /** @type {Contexte} */
639
- const ctx = { zoneClimatique: { id: 1 } };
640
-
641
- expect(() => service.execute(ctx, {}, { donnee_entree: {} })).not.toThrow();
642
- expect(combustionSpy).not.toHaveBeenCalled();
643
- });
644
-
645
- test('execute : ratio de virtualisation par défaut à 1 quand non renseigné', () => {
646
- vi.spyOn(chTvStore, 'getCombustionGenerateurs').mockReturnValue([1]);
647
- vi.spyOn(chTvStore, 'getPacGenerateurs').mockReturnValue([2]);
648
- vi.spyOn(chTvStore, 'getGenerateurCombustion').mockReturnValue({});
649
-
650
- /** @type {GenerateurChauffage} */
651
- const generateurChauffage = {
652
- donnee_entree: {
653
- enum_methode_saisie_carac_sys_id: 4,
654
- enum_type_generateur_ch_id: 1,
655
- presence_ventouse: 1
656
- },
657
- donnee_intermediaire: { rpn: 0.95, rpint: 0.68, qp0: 125, pn: 15000 }
658
- };
659
-
660
- const installationChauffage = {
661
- // donnee_entree sans ratio_virtualisation : repli sur 1
662
- donnee_entree: {},
663
- generateur_chauffage_collection: { generateur_chauffage: [generateurChauffage] }
664
- };
665
-
666
- /** @type {Logement} */
667
- const logement = {
668
- installation_chauffage_collection: { installation_chauffage: [installationChauffage] }
669
- };
670
-
671
- /** @type {Contexte} */
672
- const ctx = { zoneClimatique: { id: 1 } };
673
-
674
- service.execute(ctx, logement, installationChauffage);
675
-
676
- expect(generateurChauffage.donnee_utilisateur.ratio_virtualisation).toBe(1);
677
- // pn / (ratio * 1000) = 15000 / 1000 = 15
678
- expect(chTvStore.getGenerateurCombustion).toHaveBeenCalledWith(1, 15);
679
- });
680
-
681
- describeIntegration("Test d'intégration des installations de chauffage", () => {
682
- test.each(corpus)('vérification des DI qp0 des installations CH pour dpe %s', (ademeId) => {
683
- let dpeRequest = getAdemeFileJson(ademeId);
684
- dpeRequest = normalizerService.normalize(dpeRequest);
685
-
686
- const installationsCh = structuredClone(
687
- dpeRequest.logement.installation_chauffage_collection?.installation_chauffage || []
688
- );
689
-
690
- /** @type {Contexte} */
691
- const ctx = contexteBuilder.fromDpe(dpeRequest);
692
-
693
- installationsCh.forEach((installationCh, i) => {
694
- service.execute(ctx, dpeRequest.logement, installationCh);
695
-
696
- installationCh.generateur_chauffage_collection?.generateur_chauffage.forEach(
697
- (generateurChauffage, j) => {
698
- const expectedQp0 =
699
- dpeRequest.logement.installation_chauffage_collection.installation_chauffage[i]
700
- .generateur_chauffage_collection.generateur_chauffage[j].donnee_intermediaire.qp0;
701
-
702
- if (expectedQp0) {
703
- expect(generateurChauffage.donnee_intermediaire.qp0).toBeCloseTo(expectedQp0, 2);
704
- } else {
705
- expect(generateurChauffage.donnee_intermediaire.qp0).toBeUndefined();
706
- }
707
- }
708
- );
709
- });
710
- });
711
-
712
- test.each(corpus)('vérification des DI rpn des installations CH pour dpe %s', (ademeId) => {
713
- let dpeRequest = getAdemeFileJson(ademeId);
714
- dpeRequest = normalizerService.normalize(dpeRequest);
715
-
716
- const installationsCh = structuredClone(
717
- dpeRequest.logement.installation_chauffage_collection?.installation_chauffage || []
718
- );
719
-
720
- /** @type {Contexte} */
721
- const ctx = contexteBuilder.fromDpe(dpeRequest);
722
-
723
- installationsCh.forEach((installationCh, i) => {
724
- service.execute(ctx, dpeRequest.logement, installationCh);
725
-
726
- installationCh.generateur_chauffage_collection?.generateur_chauffage.forEach(
727
- (generateurChauffage, j) => {
728
- const expectedRpn =
729
- dpeRequest.logement.installation_chauffage_collection.installation_chauffage[i]
730
- .generateur_chauffage_collection.generateur_chauffage[j].donnee_intermediaire.rpn;
731
-
732
- if (expectedRpn) {
733
- expect(generateurChauffage.donnee_intermediaire.rpn).toBeCloseTo(expectedRpn, 2);
734
- } else {
735
- expect(generateurChauffage.donnee_intermediaire.rpn).toBeUndefined();
736
- }
737
- }
738
- );
739
- });
740
- });
741
-
742
- test.each(corpus)('vérification des DI rpint des installations CH pour dpe %s', (ademeId) => {
743
- let dpeRequest = getAdemeFileJson(ademeId);
744
- dpeRequest = normalizerService.normalize(dpeRequest);
745
-
746
- const installationsCh = structuredClone(
747
- dpeRequest.logement.installation_chauffage_collection?.installation_chauffage || []
748
- );
749
-
750
- /** @type {Contexte} */
751
- const ctx = contexteBuilder.fromDpe(dpeRequest);
752
-
753
- installationsCh.forEach((installationCh, i) => {
754
- service.execute(ctx, dpeRequest.logement, installationCh);
755
-
756
- installationCh.generateur_chauffage_collection?.generateur_chauffage.forEach(
757
- (generateurChauffage, j) => {
758
- const expectedRpint =
759
- dpeRequest.logement.installation_chauffage_collection.installation_chauffage[i]
760
- .generateur_chauffage_collection.generateur_chauffage[j].donnee_intermediaire.rpint;
761
-
762
- if (expectedRpint) {
763
- expect(generateurChauffage.donnee_intermediaire.rpint).toBeCloseTo(expectedRpint, 2);
764
- } else {
765
- expect(generateurChauffage.donnee_intermediaire.rpint).toBeUndefined();
766
- }
767
- }
768
- );
769
- });
770
- });
771
-
772
- test.each(corpus)(
773
- 'vérification des DI temp_fonc_30 des installations CH pour dpe %s',
774
- (ademeId) => {
775
- let dpeRequest = getAdemeFileJson(ademeId);
776
- dpeRequest = normalizerService.normalize(dpeRequest);
777
- console.log(ademeId);
778
- const installationsCh = structuredClone(
779
- dpeRequest.logement.installation_chauffage_collection?.installation_chauffage || []
780
- );
781
-
782
- /** @type {Contexte} */
783
- const ctx = contexteBuilder.fromDpe(dpeRequest);
784
-
785
- installationsCh.forEach((installationCh, i) => {
786
- service.execute(ctx, dpeRequest.logement, installationCh);
787
-
788
- installationCh.generateur_chauffage_collection?.generateur_chauffage.forEach(
789
- (generateurChauffage, j) => {
790
- const expectedTempFonct30 =
791
- dpeRequest.logement.installation_chauffage_collection.installation_chauffage[i]
792
- .generateur_chauffage_collection.generateur_chauffage[j].donnee_intermediaire
793
- .temp_fonc_30;
794
-
795
- console.log(expectedTempFonct30);
796
- console.log(generateurChauffage.donnee_intermediaire.temp_fonc_30);
797
-
798
- if (expectedTempFonct30) {
799
- expect(generateurChauffage.donnee_intermediaire.temp_fonc_30).toBeCloseTo(
800
- expectedTempFonct30,
801
- 2
802
- );
803
- } else {
804
- expect(generateurChauffage.donnee_intermediaire.temp_fonc_30).toBeUndefined();
805
- }
806
- }
807
- );
808
- });
809
- }
810
- );
811
-
812
- test.each(corpus)(
813
- 'vérification des DI temp_fonc_100 des installations CH pour dpe %s',
814
- (ademeId) => {
815
- let dpeRequest = getAdemeFileJson(ademeId);
816
- dpeRequest = normalizerService.normalize(dpeRequest);
817
-
818
- const installationsCh = structuredClone(
819
- dpeRequest.logement.installation_chauffage_collection?.installation_chauffage || []
820
- );
821
-
822
- /** @type {Contexte} */
823
- const ctx = contexteBuilder.fromDpe(dpeRequest);
824
-
825
- installationsCh.forEach((installationCh, i) => {
826
- service.execute(ctx, dpeRequest.logement, installationCh);
827
-
828
- installationCh.generateur_chauffage_collection?.generateur_chauffage.forEach(
829
- (generateurChauffage, j) => {
830
- const expectedTempFonct100 =
831
- dpeRequest.logement.installation_chauffage_collection.installation_chauffage[i]
832
- .generateur_chauffage_collection.generateur_chauffage[j].donnee_intermediaire
833
- .temp_fonc_100;
834
-
835
- if (expectedTempFonct100) {
836
- expect(generateurChauffage.donnee_intermediaire.temp_fonc_100).toBeCloseTo(
837
- expectedTempFonct100,
838
- 2
839
- );
840
- } else {
841
- expect(generateurChauffage.donnee_intermediaire.temp_fonc_100).toBeUndefined();
842
- }
843
- }
844
- );
845
- });
846
- }
847
- );
848
- });
849
- });