@open3cl/engine 1.6.2 → 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.
- package/10_besoin_fr.spec.js +1 -0
- package/10_clim.spec.js +1 -0
- package/11_besoin_ecs.spec.js +1 -0
- package/11_ecs.spec.js +1 -0
- package/12.4_pac.spec.js +1 -0
- package/13.2_generateur_combustion.spec.js +3 -3
- package/13.2_generateur_combustion_ch.spec.js +3 -3
- package/14_generateur_ecs.spec.js +1 -0
- package/15_conso_aux.js +121 -1
- package/15_conso_aux.spec.js +329 -4
- package/2021_04_13_confort_ete.spec.js +1 -0
- package/3.1_b.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.2.3_plancher_haut.spec.js +1 -0
- package/3.3.1.4_porte.spec.js +1 -0
- package/3.3_baie_vitree.spec.js +1 -0
- package/3.4_pont_thermique.spec.js +1 -0
- package/4_ventilation.spec.js +1 -0
- package/5_conso_ventilation.spec.js +1 -0
- package/6.2_surface_sud_equivalente.js +2 -1
- package/6.2_surface_sud_equivalente.spec.js +1 -0
- package/9_besoin_ch.spec.js +1 -0
- package/9_chauffage.spec.js +3 -3
- package/9_conso_ch.spec.js +1 -0
- package/9_emetteur_ch.spec.js +1 -0
- package/9_generateur_ch.spec.js +1 -0
- package/README.md +412 -291
- package/conso.js +20 -6
- package/conso.spec.js +21 -0
- package/engine.js +19 -1
- package/engine.spec.js +96 -0
- package/package.json +15 -14
- package/features/engine/domain/apport_et_besoin/apport-et-besoin.service.spec.js +0 -222
- package/features/engine/domain/apport_et_besoin/ch/perte-ch-recup.service.spec.js +0 -345
- package/features/engine/domain/apport_et_besoin/ecs/besoin-ecs.service.spec.js +0 -87
- package/features/engine/domain/apport_et_besoin/ecs/perte-ecs-recup.service.spec.js +0 -260
- package/features/engine/domain/apport_et_besoin/froid/besoin-froid.service.spec.js +0 -272
- package/features/engine/domain/apport_et_besoin/surface-sud-equivalente.service.spec.js +0 -231
- package/features/engine/domain/ch/generateur-ch.service.spec.js +0 -849
- package/features/engine/domain/conso/froid/conso-froid.service.spec.js +0 -233
- package/features/engine/domain/ecs/installation-ecs.service.spec.js +0 -337
- package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.spec.js +0 -607
- package/features/engine/domain/enveloppe/deperdition-enveloppe.service.spec.js +0 -550
- package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.spec.js +0 -82
- package/features/engine/domain/enveloppe/mur/deperdition-mur.service.spec.js +0 -542
- package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +0 -430
- package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.spec.js +0 -411
- package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.spec.js +0 -653
- package/features/engine/domain/enveloppe/porte/deperdition-porte.service.spec.js +0 -117
- package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.spec.js +0 -508
package/10_besoin_fr.spec.js
CHANGED
package/10_clim.spec.js
CHANGED
package/11_besoin_ecs.spec.js
CHANGED
package/11_ecs.spec.js
CHANGED
package/12.4_pac.spec.js
CHANGED
|
@@ -7,6 +7,7 @@ import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
|
7
7
|
* Le comportement de ces utilitaires n'est pas testé ici, seulement la logique du module.
|
|
8
8
|
*/
|
|
9
9
|
vi.mock('./utils.js', () => ({
|
|
10
|
+
set_bug_for_bug_compat: vi.fn(),
|
|
10
11
|
tv: vi.fn(),
|
|
11
12
|
requestInputID: vi.fn((de, du, field) => {
|
|
12
13
|
const enumName = `enum_${field}_id`;
|
|
@@ -14,6 +14,7 @@ import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
|
14
14
|
const state = vi.hoisted(() => ({ bug: false }));
|
|
15
15
|
|
|
16
16
|
vi.mock('./utils.js', () => ({
|
|
17
|
+
set_bug_for_bug_compat: vi.fn(),
|
|
17
18
|
get bug_for_bug_compat() {
|
|
18
19
|
return state.bug;
|
|
19
20
|
},
|
|
@@ -51,9 +52,8 @@ vi.mock('./ficheTechnique.js', () => ({
|
|
|
51
52
|
default: vi.fn()
|
|
52
53
|
}));
|
|
53
54
|
|
|
54
|
-
const { tv_generateur_combustion, updateGenerateurCombustion } =
|
|
55
|
-
'./13.2_generateur_combustion.js'
|
|
56
|
-
);
|
|
55
|
+
const { tv_generateur_combustion, updateGenerateurCombustion } =
|
|
56
|
+
await import('./13.2_generateur_combustion.js');
|
|
57
57
|
const { tv, tvColumnLines } = await import('./utils.js');
|
|
58
58
|
const { updateGenerateurBouilleurs } = await import('./13.2_generateur_combustion_bouilleur.js');
|
|
59
59
|
const { updateGenerateurChaudieres } = await import('./13.2_generateur_combustion_chaudiere.js');
|
|
@@ -29,6 +29,7 @@ vi.mock('./enums.js', () => ({
|
|
|
29
29
|
}));
|
|
30
30
|
|
|
31
31
|
vi.mock('./utils.js', () => ({
|
|
32
|
+
set_bug_for_bug_compat: vi.fn(),
|
|
32
33
|
get bug_for_bug_compat() {
|
|
33
34
|
return state.bug;
|
|
34
35
|
},
|
|
@@ -37,9 +38,8 @@ vi.mock('./utils.js', () => ({
|
|
|
37
38
|
requestInputID: vi.fn((de, du, field) => de[`enum_${field}_id`])
|
|
38
39
|
}));
|
|
39
40
|
|
|
40
|
-
const { tv_temp_fonc_30_100, calc_generateur_combustion_ch } =
|
|
41
|
-
'./13.2_generateur_combustion_ch.js'
|
|
42
|
-
);
|
|
41
|
+
const { tv_temp_fonc_30_100, calc_generateur_combustion_ch } =
|
|
42
|
+
await import('./13.2_generateur_combustion_ch.js');
|
|
43
43
|
const { tv } = await import('./utils.js');
|
|
44
44
|
|
|
45
45
|
beforeEach(() => {
|
package/15_conso_aux.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import enums from './enums.js';
|
|
2
2
|
import tvs from './tv.js';
|
|
3
|
-
import { mois_liste, Tbase } from './utils.js';
|
|
3
|
+
import { mois_liste, Njj, Tbase } from './utils.js';
|
|
4
4
|
|
|
5
5
|
const G_CHAUDIERE = 20;
|
|
6
6
|
const G_RADIATEURS_GAZ = 40;
|
|
@@ -259,3 +259,123 @@ function getPuissanceCirculateur(em_ch, de, di, du, surfaceHabitable, GV, Tbase)
|
|
|
259
259
|
Math.max(1, surfaceHabitable / 400)
|
|
260
260
|
);
|
|
261
261
|
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* 15.2.3 Consommation des auxiliaires de distribution d'ECS
|
|
265
|
+
* Calcul installation par installation pour le cas appartement
|
|
266
|
+
*
|
|
267
|
+
* SI installation individuelle : conso = 0
|
|
268
|
+
* SI installation collective :
|
|
269
|
+
* CAS 1 - enum_bouclage_reseau_ecs_id = 1 (non bouclé) : conso = 0
|
|
270
|
+
* CAS 2 - enum_bouclage_reseau_ecs_id = 2 (bouclé) : calcul selon étapes 1-9
|
|
271
|
+
* CAS 3 - enum_bouclage_reseau_ecs_id = 3 (traçage) : conso = 0.14 * BECS_annuel * Sh_install / Sh_logement
|
|
272
|
+
*
|
|
273
|
+
* @param ecs {object} installation ECS
|
|
274
|
+
* @param de {Donnee_entree} donnée d'entrée de l'installation ECS
|
|
275
|
+
* @param di {Donnee_intermediaire} donnée intermédiaire de l'installation ECS
|
|
276
|
+
* @param Sh_logement {number} surface habitable du logement
|
|
277
|
+
* @param Sh_immeuble {number} surface habitable de l'immeuble
|
|
278
|
+
* @param caId {number} id de la classe d'altitude
|
|
279
|
+
* @param zcId {number} id de la zone climatique
|
|
280
|
+
* @param nadeq {number} nombre d'unités d'équivalence
|
|
281
|
+
* @param nombre_niveau_immeuble {number} nombre de niveaux de l'immeuble
|
|
282
|
+
*/
|
|
283
|
+
export function conso_aux_distribution_ecs(
|
|
284
|
+
ecs,
|
|
285
|
+
de,
|
|
286
|
+
di,
|
|
287
|
+
Sh_logement,
|
|
288
|
+
Sh_immeuble,
|
|
289
|
+
caId,
|
|
290
|
+
zcId,
|
|
291
|
+
nadeq,
|
|
292
|
+
nombre_niveau_immeuble
|
|
293
|
+
) {
|
|
294
|
+
const typeInstallation = parseInt(de.enum_type_installation_id);
|
|
295
|
+
|
|
296
|
+
if (typeInstallation === 1) {
|
|
297
|
+
di.conso_auxiliaire_distribution_ecs = 0;
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const enumBouclage = parseInt(de.enum_bouclage_reseau_ecs_id);
|
|
302
|
+
|
|
303
|
+
// CAS 1 - enum_bouclage_reseau_ecs_id =1 (réseau d'ECS non bouclé)
|
|
304
|
+
if (enumBouclage === 1 || isNaN(enumBouclage)) {
|
|
305
|
+
di.conso_auxiliaire_distribution_ecs = 0;
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// CAS 3 - enum_bouclage_reseau_ecs_id = 3 (traçage)
|
|
310
|
+
if (enumBouclage === 3) {
|
|
311
|
+
const BECS_annuel = di.besoin_ecs;
|
|
312
|
+
const Sh_install = de.surface_habitable || Sh_logement;
|
|
313
|
+
di.conso_auxiliaire_distribution_ecs = (0.14 * BECS_annuel * Sh_install) / Sh_logement;
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// CAS 2 - enum_bouclage_reseau_ecs_id = 2 (réseau bouclé)
|
|
318
|
+
const ca = enums.classe_altitude[caId];
|
|
319
|
+
const zc = enums.zone_climatique[zcId];
|
|
320
|
+
|
|
321
|
+
const ratioVirtu = parseFloat(de.ratio_virtualisation);
|
|
322
|
+
let Sh_immeuble_ratio = Sh_immeuble;
|
|
323
|
+
let Sh_install = de.surface_habitable || Sh_logement;
|
|
324
|
+
let Niv_inst_ecs = de.nombre_niveau_installation_ecs || 1;
|
|
325
|
+
|
|
326
|
+
if (!(Sh_immeuble > Sh_logement) && ratioVirtu > 0 && ratioVirtu < 1) {
|
|
327
|
+
Sh_immeuble_ratio = Sh_logement / ratioVirtu;
|
|
328
|
+
Sh_install = Sh_logement;
|
|
329
|
+
Niv_inst_ecs = nombre_niveau_immeuble || Niv_inst_ecs;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Etape 3: Lb - longueur par défaut du bouclage ECS (m)
|
|
333
|
+
// Sh est la surface habitable des logements desservis par l'installation d'ECS
|
|
334
|
+
// Pour l'appartement, on utilise la surface à l'échelle de l'immeuble
|
|
335
|
+
const Sh = (Sh_install / Sh_logement) * Sh_immeuble_ratio;
|
|
336
|
+
const Lb = 4 * Math.pow(Sh / Niv_inst_ecs, 0.5) + 6 * (Niv_inst_ecs - 0.5);
|
|
337
|
+
|
|
338
|
+
// Etape 4: DeltaPb (kPa) - perte de charge dans le bouclage
|
|
339
|
+
const DeltaPb = 0.2 * Lb + 10;
|
|
340
|
+
|
|
341
|
+
let conso = 0;
|
|
342
|
+
|
|
343
|
+
for (const mois of mois_liste) {
|
|
344
|
+
// Besoin ECS mensuel pour le logement (kWh)
|
|
345
|
+
// spec : https://rt-re-batiment.developpement-durable.gouv.fr/IMG/pdf/consolide_annexe_1_arrete_du_31_03_2021_relatif_aux_methodes_et_procedures_applicables.pdf
|
|
346
|
+
// page 71-72
|
|
347
|
+
const tefsj = tvs.tefs[ca][mois][zc];
|
|
348
|
+
const njj = Njj[mois];
|
|
349
|
+
const BECS_j = (1.163 * nadeq * 56 * (40 - tefsj) * njj) / 1000;
|
|
350
|
+
|
|
351
|
+
// Etape 1: Qdwj_i (Wh) - pertes de distribution à l'échelle de l'immeuble
|
|
352
|
+
// Qd,w,j = (0.5 * Lvc / Sh + 0.112 + 0.028) * BECS_j
|
|
353
|
+
// Pour Ratecs=1 (bouclé): Lvc = 0.2 * Sh * Ratecs = 0.2 * Sh
|
|
354
|
+
// So Qd,w,j = (0.1 + 0.112 + 0.028) * BECS_j = 0.24 * BECS_j (kWh)
|
|
355
|
+
// Pour l'appartement: Qd,w,j est multiplié par Sh_immeuble_ratio / Sh_logement
|
|
356
|
+
const Qdwj_i =
|
|
357
|
+
(0.24 * BECS_j * 1000 * Sh_install * Sh_immeuble_ratio) / (Sh_logement * Sh_logement);
|
|
358
|
+
|
|
359
|
+
// Etape 2: qdwj_i (m³/h) - débit de distribution ECS
|
|
360
|
+
const Nh_puisage_j = njj * 5;
|
|
361
|
+
const qdwj_i = Qdwj_i / (5.815 * Nh_puisage_j) / 1000;
|
|
362
|
+
|
|
363
|
+
// Etape 5: Phyd,j (W) - puissance hydraulique du bouclage
|
|
364
|
+
const Phyd_j = (qdwj_i * DeltaPb) / 3.6;
|
|
365
|
+
|
|
366
|
+
// Etape 6: Effcirb,j - efficacité du circulateur
|
|
367
|
+
const Effcirb_j = Math.pow(Phyd_j, 0.324) / 15.3;
|
|
368
|
+
|
|
369
|
+
// Etape 7: Pcirb,j (W) - puissance électrique du circulateur
|
|
370
|
+
const Pcirb_j = Math.max(20, Phyd_j / Effcirb_j);
|
|
371
|
+
|
|
372
|
+
// Etape 8: Qcirb,j (Wh) - consommation mensuelle du circulateur
|
|
373
|
+
const Nh_mois_j = njj * 24;
|
|
374
|
+
const Qcirb_j = Nh_puisage_j * Pcirb_j + (Nh_mois_j - Nh_puisage_j) * 20;
|
|
375
|
+
|
|
376
|
+
conso += Qcirb_j;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Etape 9: conso annuelle ramenée à l'appartement (kWh)
|
|
380
|
+
di.conso_auxiliaire_distribution_ecs = (conso * Sh_logement) / Sh_immeuble_ratio / 1000;
|
|
381
|
+
}
|
package/15_conso_aux.spec.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Dépendances mockées
|
|
4
|
+
* Dépendances mockées pour `conso_aux_distribution_ch` et `conso_aux_distribution_ecs` :
|
|
5
5
|
* - `enums` : libellés de classe d'altitude / zone climatique ;
|
|
6
6
|
* - `tvs.nref19` : nombre d'heures de fonctionnement mensuel ;
|
|
7
|
-
* - `
|
|
7
|
+
* - `tvs.tefs` : température d'eau froide sanitaire mensuelle ;
|
|
8
|
+
* - `mois_liste` / `Njj` / `Tbase` : réduits à des valeurs contrôlées.
|
|
9
|
+
* L'année est réduite à un seul mois (Janvier, 31 jours) pour rendre les
|
|
10
|
+
* consommations attendues calculables à la main.
|
|
8
11
|
* `conso_aux_gen` n'utilise aucune de ces dépendances (calcul autonome).
|
|
9
12
|
*/
|
|
10
13
|
vi.mock('./enums.js', () => ({
|
|
@@ -16,16 +19,20 @@ vi.mock('./enums.js', () => ({
|
|
|
16
19
|
|
|
17
20
|
vi.mock('./tv.js', () => ({
|
|
18
21
|
default: {
|
|
19
|
-
nref19: { 0: { ca1: { Janvier: { h1a: 100 } } } }
|
|
22
|
+
nref19: { 0: { ca1: { Janvier: { h1a: 100 } } } },
|
|
23
|
+
tefs: { ca1: { Janvier: { h1a: 10 } } }
|
|
20
24
|
}
|
|
21
25
|
}));
|
|
22
26
|
|
|
23
27
|
vi.mock('./utils.js', () => ({
|
|
28
|
+
set_bug_for_bug_compat: vi.fn(),
|
|
24
29
|
mois_liste: ['Janvier'],
|
|
30
|
+
Njj: { Janvier: 31 },
|
|
25
31
|
Tbase: { ca1: { h1: -9 } }
|
|
26
32
|
}));
|
|
27
33
|
|
|
28
|
-
const { conso_aux_gen, conso_aux_distribution_ch } =
|
|
34
|
+
const { conso_aux_gen, conso_aux_distribution_ch, conso_aux_distribution_ecs } =
|
|
35
|
+
await import('./15_conso_aux.js');
|
|
29
36
|
|
|
30
37
|
/**
|
|
31
38
|
* 15.1 Consommation des auxiliaires de génération
|
|
@@ -223,3 +230,321 @@ describe('conso_aux_distribution_ch - auxiliaires de distribution', () => {
|
|
|
223
230
|
expect(di.conso_auxiliaire_distribution_ch).toBeCloseTo(136.51553416032854, 9);
|
|
224
231
|
});
|
|
225
232
|
});
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* 15.2.3 Consommation des auxiliaires de distribution d'ECS
|
|
236
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §15.2.3
|
|
237
|
+
*
|
|
238
|
+
* Les scénarios ci-dessous s'appuient sur l'année réduite à Janvier (31 jours,
|
|
239
|
+
* tefs = 10 °C) définie par les mocks en tête de fichier :
|
|
240
|
+
* - Nh_puisage = 31 × 5 = 155 h
|
|
241
|
+
* - Nh_mois = 31 × 24 = 744 h
|
|
242
|
+
*/
|
|
243
|
+
describe("conso_aux_distribution_ecs - auxiliaires de distribution d'ECS", () => {
|
|
244
|
+
// Consommation du circulateur maintenu à 20 W sur toutes les heures du mois (kWh)
|
|
245
|
+
const CONSO_PLANCHER_20W = (31 * 24 * 20) / 1000; // 14,88 kWh
|
|
246
|
+
|
|
247
|
+
test('installation individuelle : consommation nulle', () => {
|
|
248
|
+
const di = {};
|
|
249
|
+
conso_aux_distribution_ecs(
|
|
250
|
+
{},
|
|
251
|
+
{ enum_type_installation_id: '1', enum_bouclage_reseau_ecs_id: '2' },
|
|
252
|
+
di,
|
|
253
|
+
50,
|
|
254
|
+
2000,
|
|
255
|
+
1,
|
|
256
|
+
1,
|
|
257
|
+
30
|
|
258
|
+
);
|
|
259
|
+
expect(di.conso_auxiliaire_distribution_ecs).toBe(0);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
test("réseau d'ECS non bouclé (id 1) : consommation nulle", () => {
|
|
263
|
+
const di = {};
|
|
264
|
+
conso_aux_distribution_ecs(
|
|
265
|
+
{},
|
|
266
|
+
{ enum_type_installation_id: '2', enum_bouclage_reseau_ecs_id: '1' },
|
|
267
|
+
di,
|
|
268
|
+
50,
|
|
269
|
+
2000,
|
|
270
|
+
1,
|
|
271
|
+
1,
|
|
272
|
+
30
|
|
273
|
+
);
|
|
274
|
+
expect(di.conso_auxiliaire_distribution_ecs).toBe(0);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
test('type de bouclage non renseigné : consommation nulle', () => {
|
|
278
|
+
const di = {};
|
|
279
|
+
conso_aux_distribution_ecs({}, { enum_type_installation_id: '2' }, di, 50, 2000, 1, 1, 30);
|
|
280
|
+
expect(di.conso_auxiliaire_distribution_ecs).toBe(0);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
test('réseau avec traçage (id 3) : 0,14 × BECS × Sh_installation / Sh_logement', () => {
|
|
284
|
+
const di = { besoin_ecs: 1000 };
|
|
285
|
+
conso_aux_distribution_ecs(
|
|
286
|
+
{},
|
|
287
|
+
{
|
|
288
|
+
enum_type_installation_id: '2',
|
|
289
|
+
enum_bouclage_reseau_ecs_id: '3',
|
|
290
|
+
surface_habitable: 60
|
|
291
|
+
},
|
|
292
|
+
di,
|
|
293
|
+
50,
|
|
294
|
+
2000,
|
|
295
|
+
1,
|
|
296
|
+
1,
|
|
297
|
+
30
|
|
298
|
+
);
|
|
299
|
+
// 0,14 × 1000 × 60 / 50
|
|
300
|
+
expect(di.conso_auxiliaire_distribution_ecs).toBeCloseTo(168, 10);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
test("traçage sans surface d'installation : repli sur la surface du logement", () => {
|
|
304
|
+
const di = { besoin_ecs: 1000 };
|
|
305
|
+
conso_aux_distribution_ecs(
|
|
306
|
+
{},
|
|
307
|
+
{ enum_type_installation_id: '2', enum_bouclage_reseau_ecs_id: '3' },
|
|
308
|
+
di,
|
|
309
|
+
50,
|
|
310
|
+
2000,
|
|
311
|
+
1,
|
|
312
|
+
1,
|
|
313
|
+
30
|
|
314
|
+
);
|
|
315
|
+
// Sh_install = Sh_logement => 0,14 × 1000
|
|
316
|
+
expect(di.conso_auxiliaire_distribution_ecs).toBeCloseTo(140, 10);
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
test('réseau bouclé, faible puissance hydraulique : plancher de 20 W', () => {
|
|
320
|
+
const di = {};
|
|
321
|
+
// Immeuble réduit au logement (18 m²) et nadeq faible : Phyd ≈ 0,07 W, donc
|
|
322
|
+
// Pcirb calculée (≈ 2,6 W) passe sous le plancher de 20 W tous les mois.
|
|
323
|
+
conso_aux_distribution_ecs(
|
|
324
|
+
{},
|
|
325
|
+
{
|
|
326
|
+
enum_type_installation_id: '2',
|
|
327
|
+
enum_bouclage_reseau_ecs_id: '2',
|
|
328
|
+
surface_habitable: 18,
|
|
329
|
+
nombre_niveau_installation_ecs: 1
|
|
330
|
+
},
|
|
331
|
+
di,
|
|
332
|
+
18,
|
|
333
|
+
18,
|
|
334
|
+
1,
|
|
335
|
+
1,
|
|
336
|
+
1.15
|
|
337
|
+
);
|
|
338
|
+
expect(di.conso_auxiliaire_distribution_ecs).toBeCloseTo(CONSO_PLANCHER_20W, 10);
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
test('réseau bouclé : consommation ramenée au prorata Sh_logement / Sh_immeuble', () => {
|
|
342
|
+
const di = {};
|
|
343
|
+
// Même régime de plancher (Pcirb ≈ 11 W) : la consommation immeuble (14,88 kWh)
|
|
344
|
+
// est ramenée à l'appartement, soit un dixième ici.
|
|
345
|
+
conso_aux_distribution_ecs(
|
|
346
|
+
{},
|
|
347
|
+
{
|
|
348
|
+
enum_type_installation_id: '2',
|
|
349
|
+
enum_bouclage_reseau_ecs_id: '2',
|
|
350
|
+
surface_habitable: 50,
|
|
351
|
+
nombre_niveau_installation_ecs: 1
|
|
352
|
+
},
|
|
353
|
+
di,
|
|
354
|
+
50,
|
|
355
|
+
500,
|
|
356
|
+
1,
|
|
357
|
+
1,
|
|
358
|
+
0.5
|
|
359
|
+
);
|
|
360
|
+
expect(di.conso_auxiliaire_distribution_ecs).toBeCloseTo((CONSO_PLANCHER_20W * 50) / 500, 10);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
test('réseau bouclé, circulateur au-dessus du plancher de 20 W', () => {
|
|
364
|
+
const di = {};
|
|
365
|
+
conso_aux_distribution_ecs(
|
|
366
|
+
{},
|
|
367
|
+
{
|
|
368
|
+
enum_type_installation_id: '2',
|
|
369
|
+
enum_bouclage_reseau_ecs_id: '2',
|
|
370
|
+
surface_habitable: 50,
|
|
371
|
+
nombre_niveau_installation_ecs: 2
|
|
372
|
+
},
|
|
373
|
+
di,
|
|
374
|
+
50,
|
|
375
|
+
2000,
|
|
376
|
+
1,
|
|
377
|
+
1,
|
|
378
|
+
30
|
|
379
|
+
);
|
|
380
|
+
// valeur de référence de régression (Pcirb ≈ 549 W pendant les heures de puisage)
|
|
381
|
+
expect(di.conso_auxiliaire_distribution_ecs).toBeCloseTo(2.4208575056559525, 9);
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
test('plus de niveaux desservis : bouclage plus court, donc consommation plus faible', () => {
|
|
385
|
+
const scenario = (Niv) => {
|
|
386
|
+
const di = {};
|
|
387
|
+
conso_aux_distribution_ecs(
|
|
388
|
+
{},
|
|
389
|
+
{
|
|
390
|
+
enum_type_installation_id: '2',
|
|
391
|
+
enum_bouclage_reseau_ecs_id: '2',
|
|
392
|
+
surface_habitable: 50,
|
|
393
|
+
nombre_niveau_installation_ecs: Niv
|
|
394
|
+
},
|
|
395
|
+
di,
|
|
396
|
+
50,
|
|
397
|
+
2000,
|
|
398
|
+
1,
|
|
399
|
+
1,
|
|
400
|
+
30
|
|
401
|
+
);
|
|
402
|
+
return di.conso_auxiliaire_distribution_ecs;
|
|
403
|
+
};
|
|
404
|
+
// Lb = 4 × (Sh / Niv)^0,5 + 6 × (Niv − 0,5) : sur cet immeuble, Lb décroît avec Niv
|
|
405
|
+
expect(scenario(1)).toBeCloseTo(2.767218880573735, 9);
|
|
406
|
+
expect(scenario(4)).toBeCloseTo(2.2222299894932647, 9);
|
|
407
|
+
expect(scenario(4)).toBeLessThan(scenario(1));
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
test("réseau bouclé sans surface ni nombre de niveaux d'installation : valeurs par défaut", () => {
|
|
411
|
+
const diDefaut = {};
|
|
412
|
+
conso_aux_distribution_ecs(
|
|
413
|
+
{},
|
|
414
|
+
{ enum_type_installation_id: '2', enum_bouclage_reseau_ecs_id: '2' },
|
|
415
|
+
diDefaut,
|
|
416
|
+
50,
|
|
417
|
+
2000,
|
|
418
|
+
1,
|
|
419
|
+
1,
|
|
420
|
+
30
|
|
421
|
+
);
|
|
422
|
+
const diExplicite = {};
|
|
423
|
+
// Sh_install = Sh_logement et Niv = 1
|
|
424
|
+
conso_aux_distribution_ecs(
|
|
425
|
+
{},
|
|
426
|
+
{
|
|
427
|
+
enum_type_installation_id: '2',
|
|
428
|
+
enum_bouclage_reseau_ecs_id: '2',
|
|
429
|
+
surface_habitable: 50,
|
|
430
|
+
nombre_niveau_installation_ecs: 1
|
|
431
|
+
},
|
|
432
|
+
diExplicite,
|
|
433
|
+
50,
|
|
434
|
+
2000,
|
|
435
|
+
1,
|
|
436
|
+
1,
|
|
437
|
+
30
|
|
438
|
+
);
|
|
439
|
+
expect(diDefaut.conso_auxiliaire_distribution_ecs).toBeCloseTo(
|
|
440
|
+
diExplicite.conso_auxiliaire_distribution_ecs,
|
|
441
|
+
10
|
|
442
|
+
);
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
test("installation desservant tout l'immeuble : Sh_installation étendue à l'immeuble", () => {
|
|
446
|
+
const di = {};
|
|
447
|
+
conso_aux_distribution_ecs(
|
|
448
|
+
{},
|
|
449
|
+
{
|
|
450
|
+
enum_type_installation_id: '2',
|
|
451
|
+
enum_bouclage_reseau_ecs_id: '2',
|
|
452
|
+
surface_habitable: 2000,
|
|
453
|
+
nombre_niveau_installation_ecs: 2
|
|
454
|
+
},
|
|
455
|
+
di,
|
|
456
|
+
50,
|
|
457
|
+
2000,
|
|
458
|
+
1,
|
|
459
|
+
1,
|
|
460
|
+
30
|
|
461
|
+
);
|
|
462
|
+
// valeur de référence de régression
|
|
463
|
+
expect(di.conso_auxiliaire_distribution_ecs).toBeCloseTo(72.84189246242042, 9);
|
|
464
|
+
});
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* 15.2.3 - Cas des DPE d'appartement dont `surface_habitable_immeuble` est
|
|
469
|
+
* renseignée avec la surface du logement : l'échelle de l'immeuble est alors
|
|
470
|
+
* reconstruite à partir du ratio de virtualisation de l'installation.
|
|
471
|
+
*/
|
|
472
|
+
describe("conso_aux_distribution_ecs - surface d'immeuble incohérente", () => {
|
|
473
|
+
const RATIO_VIRTUALISATION = 0.0211;
|
|
474
|
+
const SH_LOGEMENT = 18;
|
|
475
|
+
// 18 / 0,0211 = 853,08 m²
|
|
476
|
+
const SH_IMMEUBLE_RECONSTRUITE = SH_LOGEMENT / RATIO_VIRTUALISATION;
|
|
477
|
+
|
|
478
|
+
/** @param de {object} @param Sh_immeuble {number} @param nbNiveauImmeuble {number} */
|
|
479
|
+
const consoEcs = (de, Sh_immeuble, nbNiveauImmeuble) => {
|
|
480
|
+
const di = {};
|
|
481
|
+
conso_aux_distribution_ecs(
|
|
482
|
+
{},
|
|
483
|
+
{
|
|
484
|
+
enum_type_installation_id: '2',
|
|
485
|
+
enum_bouclage_reseau_ecs_id: '2',
|
|
486
|
+
surface_habitable: SH_LOGEMENT,
|
|
487
|
+
nombre_niveau_installation_ecs: 1,
|
|
488
|
+
...de
|
|
489
|
+
},
|
|
490
|
+
di,
|
|
491
|
+
SH_LOGEMENT,
|
|
492
|
+
Sh_immeuble,
|
|
493
|
+
1,
|
|
494
|
+
1,
|
|
495
|
+
1.15,
|
|
496
|
+
nbNiveauImmeuble
|
|
497
|
+
);
|
|
498
|
+
return di.conso_auxiliaire_distribution_ecs;
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
test("surface d'immeuble égale à celle du logement : reconstruite via le ratio de virtualisation", () => {
|
|
502
|
+
const reconstruite = consoEcs(
|
|
503
|
+
{ ratio_virtualisation: String(RATIO_VIRTUALISATION) },
|
|
504
|
+
SH_LOGEMENT,
|
|
505
|
+
1
|
|
506
|
+
);
|
|
507
|
+
|
|
508
|
+
// Sans reconstruction, le prorata vaut 1 et le circulateur reste au plancher de 20 W
|
|
509
|
+
expect(reconstruite).not.toBeCloseTo((31 * 24 * 20) / 1000, 6);
|
|
510
|
+
expect(reconstruite).toBeCloseTo(0.45766695775765603, 9);
|
|
511
|
+
|
|
512
|
+
// Équivalent à une surface d'immeuble correctement renseignée
|
|
513
|
+
const renseignee = consoEcs({}, SH_IMMEUBLE_RECONSTRUITE, 1);
|
|
514
|
+
expect(reconstruite).toBeCloseTo(renseignee, 10);
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
test("reconstruction : le nombre de niveaux de l'immeuble prime sur celui de l'installation", () => {
|
|
518
|
+
// nombre_niveau_installation_ecs = 1 est la valeur du logement, incohérente
|
|
519
|
+
// avec la surface d'immeuble reconstruite
|
|
520
|
+
expect(
|
|
521
|
+
consoEcs({ ratio_virtualisation: String(RATIO_VIRTUALISATION) }, SH_LOGEMENT, 6)
|
|
522
|
+
).toBeCloseTo(0.4237342712345093, 9);
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
test("reconstruction sans nombre de niveaux d'immeuble : repli sur celui de l'installation", () => {
|
|
526
|
+
expect(
|
|
527
|
+
consoEcs(
|
|
528
|
+
{
|
|
529
|
+
ratio_virtualisation: String(RATIO_VIRTUALISATION),
|
|
530
|
+
nombre_niveau_installation_ecs: 3
|
|
531
|
+
},
|
|
532
|
+
SH_LOGEMENT,
|
|
533
|
+
undefined
|
|
534
|
+
)
|
|
535
|
+
).toBeCloseTo(0.4253220756819142, 9);
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
test('ratio de virtualisation égal à 1 : aucune reconstruction', () => {
|
|
539
|
+
expect(consoEcs({ ratio_virtualisation: '1' }, SH_LOGEMENT, 6)).toBeCloseTo(
|
|
540
|
+
(31 * 24 * 20) / 1000,
|
|
541
|
+
10
|
|
542
|
+
);
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
test("surface d'immeuble cohérente : le ratio de virtualisation est ignoré", () => {
|
|
546
|
+
expect(
|
|
547
|
+
consoEcs({ ratio_virtualisation: String(RATIO_VIRTUALISATION) }, SH_IMMEUBLE_RECONSTRUITE, 6)
|
|
548
|
+
).toBeCloseTo(consoEcs({}, SH_IMMEUBLE_RECONSTRUITE, 6), 10);
|
|
549
|
+
});
|
|
550
|
+
});
|
package/3.1_b.spec.js
CHANGED
|
@@ -14,6 +14,7 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
|
|
14
14
|
const state = vi.hoisted(() => ({ bug: false }));
|
|
15
15
|
|
|
16
16
|
vi.mock('./utils.js', () => ({
|
|
17
|
+
set_bug_for_bug_compat: vi.fn(),
|
|
17
18
|
tv: vi.fn(),
|
|
18
19
|
requestInputID: (de, du, field) => {
|
|
19
20
|
const enumName = `enum_${field}_id`;
|
package/3.2.1_mur.spec.js
CHANGED
|
@@ -30,6 +30,7 @@ vi.mock('./3.1_b.js', () => ({
|
|
|
30
30
|
}));
|
|
31
31
|
|
|
32
32
|
vi.mock('./utils.js', () => ({
|
|
33
|
+
set_bug_for_bug_compat: vi.fn(),
|
|
33
34
|
tv: vi.fn(),
|
|
34
35
|
requestInput: (de, du, field) => de[field],
|
|
35
36
|
getKeyByValue: (object, value) => Object.keys(object).find((key) => object[key] === value),
|
|
@@ -23,6 +23,7 @@ vi.mock('./3.1_b.js', () => ({
|
|
|
23
23
|
}));
|
|
24
24
|
|
|
25
25
|
vi.mock('./utils.js', () => ({
|
|
26
|
+
set_bug_for_bug_compat: vi.fn(),
|
|
26
27
|
tv: vi.fn(),
|
|
27
28
|
requestInput: (de, du, field) => de[field],
|
|
28
29
|
getKeyByValue: (object, value) => Object.keys(object).find((key) => object[key] === value),
|
package/3.3.1.4_porte.spec.js
CHANGED
package/3.3_baie_vitree.spec.js
CHANGED
package/4_ventilation.spec.js
CHANGED
|
@@ -8,6 +8,7 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
|
|
8
8
|
* - `calc_pvent` (5_conso_ventilation.js) : espion, la conso de ventilation est testée ailleurs.
|
|
9
9
|
*/
|
|
10
10
|
vi.mock('./utils.js', () => ({
|
|
11
|
+
set_bug_for_bug_compat: vi.fn(),
|
|
11
12
|
tv: vi.fn(),
|
|
12
13
|
requestInput: (de, du, field) => de[field],
|
|
13
14
|
requestInputID: (de, du, field) => de[`enum_${field}_id`],
|
|
@@ -5,6 +5,7 @@ import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
|
5
5
|
* d'entrée `de` pour le champ demandé. Cela isole `calc_pvent` de la logique de `utils`.
|
|
6
6
|
*/
|
|
7
7
|
vi.mock('./utils.js', () => ({
|
|
8
|
+
set_bug_for_bug_compat: vi.fn(),
|
|
8
9
|
requestInput: (de, du, field) => de[field]
|
|
9
10
|
}));
|
|
10
11
|
|